Aqutras Members' Blog

株式会社アキュトラスのメンバーが、技術情報などを楽しく書いています。

esa で AWS S3 バケットを移行する方法

こんにちは、いるかさんです。
アキュトラスでは、ドキュメントの共有に esa.io を利用しています。

esa.io

他社だと、QiitaやWikiやコンフルなど、いろいろなサービスが見られますが、
esa.ioのいいなと思う点をざっと挙げると、

  • WIPという機能のおかげで、気軽にドキュメントを作成できる
    • Work in Progress まだ作りかけ、ということで気軽にWIPを溜められるのと、他の人から見ることもできるので、コメントしたり★をつけたりも気軽にできます。
  • 階層構造が分かりやすい
    • /で区切ると勝手に階層化してくれるので、気づいたら木構造で整理された状態になってます。
  • 機能が絞られているので利用コストが低い
  • 外部との連携もとりやすい

そして、esa.ioでは、ファイルを記事に添付することができるんですが、
アップロードしたファイルを、自前で用意したAWS S3バケットに保存するようにできます。
今回、とある事情からバケットを移行することになったので、移行にあたっての問題と手順を書きます。

移行にあたっての問題

既にS3バケットを設定している場合は、一度、その設定を削除してから、新しいS3バケットに連携させる必要があります。
元のS3バケットにアップされているファイルを消さない限りは、設定を切替えてしまっても、元のファイルは今までどおりアクセスできます。
しかし、元のS3バケットにアップされているファイルを削除すると、見られなくなります。これは、アップされたS3ファイルへのURLが、esaの記事内に記載されているため、新しいS3バケットに切り替えるには、以下の手順が必要です。

  • 元のS3バケットのファイルを新しいS3バケットにコピーする
  • esaの記事に記載されている元のS3バケットのURLを新しいS3バケットのURLに変更する

手順が完了したら、元のS3バケットのファイルは削除してしまってもOKです。
ただし、このやり方には副作用もあります。副作用については、後述しています。

1. 元のS3バケットのファイルを新しいS3バケットにコピーする

これは、AWS CLIを使えば簡単にできます。

AWS CLIについて: AWS コマンドラインインターフェイス | AWS
コピーの参考: S3 から ファイルをAWSCLIでディレクトリごとダウンロード - Qiita

ただし!ファイルのパーミッションを変更する必要があります。
1個1個のファイルを手動で変更していたらきりがないので、これもAWS CLIで変更します。
以下の記事を参考に、コマンドを実行します。

参考: AWS CLIを使ってS3のバケット内オブジェクトのpermission(ACL)を一括変更する - Qiita

aws s3 ls --recursive s3://{新バケット名}/ | awk '{print $4}' | xargs -P4 -I{} aws s3api put-object-acl --acl public-read --bucket {新バケット名} --key "{}"

2. esaの記事内のバケットURLを更新する

S3にアップされたファイルは、URLが以下のようになっていると思います。

https://{バケット名}.{エンドポイント}/uploads/production/attachments/(中略)/{UUID}.zip

なので、バケット名(と必要に応じてエンドポイント)を置換するだけでよさそうです。
実際に置換するスクリプトをRubyで書きました。事前に gem install esaしておく必要があります。

gist.github.com

注意点として、APIを叩きまくるので、記事数が多いと、こんな感じで制限に引っかかります。
{"error"=>"too_many_requests", "message"=>"Retry after 900 seconds.”}
場合によっては、時間あたりの更新数を制限して、他のAPI利用に支障がでないようにする必要があります。

このやり方の副作用

  • esaの更新をSlackなどに通知する設定にしている場合、超大量の通知がきます。
    • 一時的に通知を切っておいたほうがいいかもしれません。
  • updated_byが更新されます。
    • 上記スクリプトでは esa_bot にしていますが、更新のあった記事は全て esa_bot がつきます。
  • 最近更新されたPOSTSが埋まる
    • びっしり埋まります(;´∀`)

S3バケットの移行ができないということはないですが、
できれば、移行しなくて済むようにしておいた方が望ましいですね(・∀・)