バージョニングしたS3バケットから削除されたファイルを取得するシェルファイルを作ってみた

2020.11.30

こんにちは、S3のバージョニングの設定をしているバケットでは削除前のIDを指定する事でファイルを取得する事ができます。

以前、CLIコマンドを利用して削除したファイルを戻す方法について書きました(CLIを使用してS3のバージョニングを設定し削除したファイルを戻してみる)。今回は削除されたファイルをローカルに取得するシェルファイルを作成したいと思います。

削除したファイルを取得するシェルファイル

最終的に作成したシェルファイル(get_delete_file.sh)を載せます。

処理内容は以下の2つになります。取得したファイルにはget_をつけます。

  • 削除された取得ファイルの削除前IDの取得
  • 削除されたファイルの取得

get_delete_file.sh

#!/usr/bin/bash
bucket_name="$1" # 第一引数からバケット名を取得
key_file="$2"    # 第二引数からキーファイル名を取得

# 取得したいファイルのversionsを取得
get_versions=`aws s3api list-object-versions \
--bucket ${bucket_name} \
--prefix ${key_file}`

# 削除前のバージョンidのみを取得
version_id=`echo ${get_versions} | jq -r ".Versions[].VersionId"`

# ファイル取得
get_file=`aws s3api get-object \
--bucket ${bucket_name} \
--key ${key_file} get_${key_file} \
--version-id ${version_id}`

ファイル実行時はバケット名とキーファイルを引数として指定します。

では引数を指定してシェルスクリプトを実行します(前提として、バージョニングされたバケットにてファイル(test2010.txt)が削除されている状態とします)。

$ bash get_delete_file.sh バケット名 test2010.txt

$ ls
get_delete_file.sh      get_test2010.txt

get_test2010.txtファイルが取得できました。

ファイル取得時の確認

では上記のシェルスクリプト作成時に必要な内容についてまとめます。内容はこちらの2つになります。

  1. 削除されたファイルを取得する方法
  2. 削除前のファイルのIDを取得する方法

1. 削除されたファイルを取得する方法

削除されたファイルを取得するにはs3api get-objectを使用します。こちらのコマンドは、バケット名、キーファイルと保存先のパスを指定することでS3からファイルを取得する事が可能です。しかし、削除されたファイルを取得する場合は削除前のVersionIDをオプションの--version-idにて指定する必要があります。

$ aws s3api get-object \
--bucket バケット名 \
--key S3バケット内の取得するファイル名 ローカルに保存するパス \
--version-id 取得するファイルのID

2. 削除前のファイルのIDを取得する方法

削除されたファイルを取得するには削除前のVersionIDが必要な事がわかりましたので、取得するファイルのIDを調べるためにs3api list-object-versionsを使用します。こちらは、バケット名と取得するキーファイルを指定します。

$ aws s3api list-object-versions \
--bucket バケット名 \
--prefix test2010.txt

{ "Versions": [ { "ETag": "\"********************************\"", "Size": 5, "StorageClass": "STANDARD", "Key": "test2010.txt", "VersionId": "zoOYjGiE9DLP_d2OIBxFPBkUCUN5CAfC", "IsLatest": false, "LastModified": "2020-10-24T03:20:17+00:00", "Owner": { "DisplayName": "*****-****", "ID": "****************************************************************" } } ], "DeleteMarkers": [ { "Owner": { "DisplayName": "*****-****", "ID": "****************************************************************" }, "Key": "test2010.txt", "VersionId": "eUwtMeGAL6S4GDBOLG5mO.XpDYBlO7WI", "IsLatest": true, "LastModified": "2020-10-24T03:21:17+00:00" } ] }

test2010.txtファイルの戻り値として上記の値が取得できました。戻り値のVersionsの項目がファイル削除前のIDになり、DeleteMarkersが削除されたことを示す内容になります。必要なのはVersions配列にあるVersionId値のみです。

このIDを取得しているところが、get_delete_file.shの前半部分になります。VersionIdのみを取得するためにjqコマンドを使用します。jqコマンドは.Versions[].VersionIdのように指定し、-rをつけることで取得結果の"(ダブルクォーテーション)を省く事ができます。

get_delete_file.sh

#!/usr/bin/bash

bucket_name="$1" # 第一引数からバケット名を取得
key_file="$2"    # 第二引数からキーファイル名を取得

# 取得したいファイルのversionsを取得
get_versions=`aws s3api list-object-versions \
--bucket ${bucket_name} \
--prefix ${key_file}`

# 削除前のバージョンIDのみを取得
version_id=`echo ${get_versions} | jq -r ".Versions[].VersionId"`
echo ${version_id}

バケット名とキーファイルを指定して実行しIDのみが取得できているか確認します。

$ bash get_delete_file.sh バケット名 test2010.txt
zoOYjGiE9DLP_d2OIBxFPBkUCUN5CAfC

削除前IDの取得が出来ました。この結果を使用してファイル取得が可能なり作ることができました。

まとめ

Delete Markerを削除してファイルを戻しましたが、削除される前のIdを指定することでファイルを戻さずとも取得することが出来ました。 シェル化してみたかったのでjqなど寄り道をしましたが良い勉強になりました。 この記事がどなたかの助けになれば幸いです。

参考リンク