S3 syncコマンドを利用してS3バケット間を同期する
最近S3バケットデータ移行の要望が来ていました。
バケット間同期用のコマンドを調査しましたので、備忘として残ります。
やりたいこと
AアカウントにあるS3バケットのデータをBアカウントのS3に移行したい
実現方法を簡単に説明
- BアカウントにS3バケットを作成する
- オンプレミス環境で実行するので、S3操作権限あるIAMユーザを作成する
- AアカウントのS3バケットにBアカウントで作成したIAMユーザのアクセス許可ポリシーを追加する
- S3バケット間でデータを同期する
- データが正しくコピーされているかを確認する
同期コマンド
cpコマンドを利用して再帰的にコピーできますが、今回利用するもっと楽の同期コマンドをご紹介します。
aws s3 sync s3://BUCKET-SOURCE s3://BUCKET-TARGET
sync コマンドは CopyObject API を使用して S3 バケット間でオブジェクトの移動を行います。sync コマンドは、ソースとターゲットのバケットをリストアップし、ソース側に存在しターゲット側にないバケットを特定します。また、このコマンドは、LastModified の日付がターゲットバケット内のものと異なる、ソースバケット内のオブジェクトも識別します。
結構使えるオプションもあるので、今回使ったオプションをご紹介します。
他にはAWSの公式ドキュメントをご参照ください。
オプション | 説明 |
---|---|
--only-show-errors | デフォルトではコピープロセスが表示されます。オブジェクトが多いので、エラー情報のみ出力するように設定する。 |
--exact-timestamps | S3からローカルに同期する場合、同じサイズのアイテムは、タイムスタンプが完全に一致する場合にのみ無視されます。 デフォルトの動作では、ローカルバージョンがS3バージョンよりも新しい場合を除き、同じサイズのアイテムは無視されます。 |
--delete | コピー先には存在するがコピー元には存在しないファイルは、同期中に削除されます |
コピー結果を確認
次のコマンドを実行して、ソースとターゲットバケットの内容を確認する
aws s3 ls --recursive s3://BUCKET-SOURCE --summarize > bucket-contents-source.txt
aws s3 ls --recursive s3://BUCKET-TARGET --summarize > bucket-contents-target.txt
上記のコマンドを実行すると、バケット内容にあるオブジェクトリスト一覧とオブジェクト数とサマリーサイズが出力されます。
少しハマった話
コピーした後に上記の確認コマンドでリスト一覧を出力してみたら、
あれ、オブジェクト数が異なっています。
いろいろ調査し、試してみたら、以下のことがわかりました。
元のバケットでは、基本フォルダを作成した後に、ファイルをアップロードしています。
とすると、サイズゼロのオブジェクト(フォルダ)がリスト一覧に出力されます。
但し、オブジェクトをコピーする際に、サイズゼロのフォルダが作成しないので(プレフィックス付きのオブジェクトのみ作成する)
コピー後のTotla Objects
が異なっています。
なんか、サイズゼロのオブジェクトを出力しないオプションがなさそうなので
トータルサイズを比較し、オブジェクト一覧をExcelにコピーして整形してから比較するようにしました。