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 -eue フラグを外してエラーが生じても落ちないようにしたのと、 if [ $? -ne 0 ] によって fetch の成否で後続処理を分岐させているところです。

とりあえず Multipart Upload のゴミ掃除はどの bucket でも設定しておきたいものだとは思うので初期化としては妥当ではないでしょうか。

以上

やっぱりコードベースでインフラ管理をできるのは設定の手間もミスも無くせる上にバージョン管理やレビューも導入できて幸福度が高いですね。どんどん推し進めていきたいと思います。

lifecycle はそれなりの数(試したところ200は少なくとも設定できた)が設定できるので、大量のオブジェクトを削除する際に prefix で絞れる場合は lifecycle を 1d で設定して待つとリクエスト数も節約できる上に楽なので、コードベースで気軽にベタベタ変更できるのはとても嬉しいです。

ちなみに Terraform でも lifecycle の管理はできるようなので、 bucket を Terraform で管理している場合はそちらを使用するのが良いかもしれません。今のところ私の使い方では影響範囲を絞ってフランクに管理したかったのでスクリプトでの json 管理が捗っています。

Share Comments
comments powered by Disqus