S3 の Lifecycle をコードベースで管理できる環境を整備した
S3 の Lifecycle をポチポチしているのが辛くなったので、カッとなって作りました。
awscli と jq があれば動くので、簡易的なコードベース管理の雛形としてお使いください。
hori-ryota/s3-lifecycle-manager
あくまで個人使用のために作成したので、細かいアレコレはご容赦ください。
お約束ですが、 使用は自己責任でお願いします。
以下、記事公開時点の README.md と同内容のものに補足を加えたものです。
README.md
hori-ryota/cloudfront-manager: Scripts for CloudFront から派生して作りました。
S3 の lifecycle をポチポチ運用するのが辛いので awscli を用いた json 管理にするやつです。
(基礎知識)主要な aws コマンド
AWS CLI を使用したライフサイクル設定の設定 - Amazon Simple Storage Service
ディレクトリ構成
targetBuckets.txt # 管理対象とするbucketリスト
json/ # apiから取得したjson置き場
更新は json ディレクトリ内のファイルを更新して S3 に反映してください。
スクリプト
vim の quickrun で叩きやすくするため、dirname などでのパス解決はしていないです。 s3-lifecycle-manager/
ディレクトリ直下で実行してください。
fetchall.sh
初期化用。 targetBuckets.txt
に記載されている bucket の lifecycle を取ってきて json ディレクトリに反映。
削除済みの json 削除は行わないので、削除も必要なら json ディレクトリを削除後に実行してください。
update.sh
./update.sh ${targetCName}
更新用。get-bucket-lifecycle-configuration
の json と put-bucket-lifecycle-configuration
の形式は若干違うので、jq
コマンドで整形したものを入力へ。
全 bucket を targetBuckets.txt に入れたい場合
このコマンドで入るかと思います。
aws s3api list-buckets | jq -r '.Buckets[].Name' > targetBuckets.txt
補足
lifecycle が未設定な bucket に fetch をかけるとエラーになるので、以下のようなスクリプトで初期化するのも良いと思います。
#!/bin/bash
set -eu
dir='json'
mkdir -p $dir
buckets="$(cat ./targetBuckets.txt)"
json='{
"Rules": [
{
"Filter": {
"Prefix": ""
},
"Status": "Enabled",
"ID": "incomplete-multipart",
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 1
}
}
]
}'
for bucket in $buckets; do
echo "fetch $bucket"
echo $json | jq '.' > "$dir/$bucket.json"
done
上記のスクリプトは targetBuckets.txt
の全ての bucket の json に対し、不完全な Mupltipart Upload の残骸を 1 日で削除する lifecycle を設定指定しています。
その上で fetchall.sh
を以下のように書き換えて実行すると、既存のもののみ上書きされるので初期化に良いです。
#!/bin/bash
set -u
dir='json'
mkdir -p $dir
buckets="$(cat ./targetBuckets.txt)"
for bucket in $buckets; do
echo "fetch $bucket"
target=$(aws s3api get-bucket-lifecycle-configuration --bucket "$bucket")
if [ $? -ne 0 ]; then
echo "not initialized"
continue
fi
echo $target | jq '.' > "$dir/$bucket.json"
done
書き換えた部分は set -eu
の e
フラグを外してエラーが生じても落ちないようにしたのと、 if [ $? -ne 0 ]
によって fetch の成否で後続処理を分岐させているところです。
とりあえず Multipart Upload のゴミ掃除はどの bucket でも設定しておきたいものだとは思うので初期化としては妥当ではないでしょうか。
以上
やっぱりコードベースでインフラ管理をできるのは設定の手間もミスも無くせる上にバージョン管理やレビューも導入できて幸福度が高いですね。どんどん推し進めていきたいと思います。
lifecycle はそれなりの数(試したところ 200 は少なくとも設定できた)が設定できるので、大量のオブジェクトを削除する際に prefix で絞れる場合は lifecycle を 1d で設定して待つとリクエスト数も節約できる上に楽なので、コードベースで気軽にベタベタ変更できるのはとても嬉しいです。
ちなみに Terraform でも lifecycle の管理はできるようなので、 bucket を Terraform で管理している場合はそちらを使用するのが良いかもしれません。今のところ私の使い方では影響範囲を絞ってフランクに管理したかったのでスクリプトでの json 管理が捗っています。