はじめに
普段S3を使用する時、長期間の保管が必要でかつアクセスが少ないデータに対しては、ライフサイクルルールを使用してGlacierに移動している方が多いと思います。
Glacierはストレージコストが低い分最低保存期間が決まっていたり、S3に復元する際に別途費用が掛かったり色々と制限がありますが、今回はその復元方法について書いていきます。
Glacierを使用する要件がある時点で、そこから復元する機会というのは中々ないとは思いますが、いざ復元を使用しようと思ったときに、1ファイルだけ復元するだけでなく、このフォルダ階層配下をまとめて復元したい、なんてこともあるのではないでしょうか。
しかし、コンソール上から復元しようとした場合、以下の通りフォルダごとまとめての復元はできず、
以下のように復元対象のファイルをすべて選択して復元操作をする必要があります。
そこで、今回はCLIで指定したフォルダ配下のオブジェクトをまとめて復元するスクリプトを作ってみました。
一応調べてみると、既に先人の方々が似たようなことをやっているような記事は見つけました。
ただ、Pythonスクリプトや非公式のツールを使用した復元手順はあるものの、AWS CLIでスクリプトを組んでみたみたいなのはなさそうだったので、今回はそこにフォーカスを当ててやってみました。
あと個人的に最近Windows Server にCloudBerry DriveでS3をマウントして使用することが多いので、Windowsで使う想定でAWS CLI+PowerShellにしています。
実施内容
実施作業
使用コマンドとスクリプト構成
AWS CLIでS3を操作するときに、aws s3
コマンドとaws s3api
コマンドの2種類ありますが、今回はGlacierからの復元を行うので、後者のaws s3api
コマンドを使用します。
s3apiのリファレンスはこちら
docs.aws.amazon.com
スクリプトの構成としては、以下を想定しています。
①バケット名、復元対象のパス、復元期間(日)、復元方法(Standard ,Bulk ,Expedited)をパラメータで指定
②指定パス配下の全オブジェクト取得処理
③オブジェクトごとにストレージクラス及び復元判定処理
④復元中でなければ復元リクエスト送信処理
使用コマンド確認
スクリプトを作成する前に、実行するコマンドを確認しておきます。
特定バケット配下のオブジェクト取得コマンド
- コマンド
aws s3api list-objects-v2 --bucket test-tmp-windows --prefix test1/test1-1/
- 実行結果
オブジェクトのストレージクラス及びリストアステータス取得コマンド
- コマンド
aws s3api head-object --bucket test-tmp-windows --key test1/test1-1/test1.txt
- 実行結果
※Restoreパラメータがある場合はファイル復元中
復元リクエスト送信コマンド
- コマンド
aws s3api restore-object --bucket test-tmp-windows --key test1/test1-1/test1.txt --restore-request '{\"Days\":1,\"GlacierJobParameters\":{\"Tier\":\"Standard\"}}'
- 実行結果
スクリプトの実行対象
作成したスクリプトを実行する環境は以下の構成です。
スクリプトを実行したら2つのtxtファイルがGlacierから復元中になる想定です。
PS C:\Users\Administrator> aws s3api list-objects-v2 --bucket test-tmp-windows --prefix test { "Contents": [ { "Key": "test/", "LastModified": "2019-12-06T14:23:24.000Z", "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"", "Size": 0, "StorageClass": "STANDARD" }, { "Key": "test/test1/", "LastModified": "2019-12-06T14:23:34.000Z", "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"", "Size": 0, "StorageClass": "STANDARD" }, { "Key": "test/test1/Test.txt", "LastModified": "2019-12-06T14:25:59.000Z", "ETag": "\"3f0326f4e56c3f4b54feede9071cafbf\"", "Size": 6, "StorageClass": "GLACIER" }, { "Key": "test/test1/test1-1/", "LastModified": "2019-12-06T14:23:40.000Z", "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"", "Size": 0, "StorageClass": "STANDARD" }, { "Key": "test/test1/test1-1/test1-1.txt", "LastModified": "2019-12-06T14:26:13.000Z", "ETag": "\"3f0326f4e56c3f4b54feede9071cafbf\"", "Size": 6, "StorageClass": "GLACIER" } ] }
作成したスクリプト
説明したコマンドを使用して以下のスクリプトを作成します。
Param( [parameter(mandatory=$true)][String]$s3_bucket, # S3バケット名 [parameter(mandatory=$true)][String]$s3_prefix, # バケット配下パス [parameter(mandatory=$true)][String]$restore_day, # 復元期間 [parameter(mandatory=$true)][String]$restore_type # 復元方法 ) $obj_list=aws s3api list-objects-v2 --bucket $s3_bucket --prefix $s3_prefix | ConvertFrom-Json $restore_op="'{\`"Days\`":" + ${restore_day} + ",\`"GlacierJobParameters\`":{\`"Tier\`":\`"" + ${restore_type} + "\`"}}'" if($obj_list -eq $null){ echo "オブジェクトの取得に失敗しました" exit 1 } foreach( $obj in $obj_list.Contents){ $path=$obj.key $last_str=$path.Substring($path.Length - 1, 1) if($last_str -ne "/"){ $file_data=aws s3api head-object --bucket $s3_bucket --key $path | ConvertFrom-Json echo "$path" if($file_data.StorageClass -eq "GLACIER"){ $cmd="aws s3api restore-object --bucket " + $s3_bucket + " --key $path --restore-request $restore_op" if($file_data.Restore -ne $null){ echo "ファイルは復元中です" continue } else { echo "復元リクエスト送信しました" invoke-expression $cmd if($? -eq $false){ echo "コマンドが失敗しました" exit 1 } } } else { echo "ストレージタイプがGlacierではありません" continue } } }
実行結果
スクリプトを実行したら以下のようになりました。
PS C:\Users\Administrator\Desktop\tool> .\glacier_restore.ps1 コマンド パイプライン位置 1 のコマンドレット glacier_restore.ps1 次のパラメーターに値を指定してください: s3_bucket: test-tmp-windows s3_prefix: test restore_day: 1 restore_type: Standard test/test1/Test.txt 復元リクエスト送信しました test/test1/test1-1/test1-1.txt 復元リクエスト送信しました
想定通りエラーなくtxtファイルのみに復元リクエストが送信されています。
S3上でも確認したところステータスが復元中になっていることが確認できました。
感想及び所感
ということで、Glacierからの復元をAWS CLI+PowerShellで作成してみました。
状況によってはサーバにPythonをインストールできなかったりするので、もし良かったら試してみてください。