🐢

AWS SDK for Python (Boto3) を用いてプレフィックスごとにS3ライフサイクルルールを一括設定する

2022/10/27に公開約4,700字

Opt FitエンジニアのURUSHIです!
先日大量のライフサイクル設定を依頼されて泣き出しそうだったので、その際に利用した解決策を共有します。

概要

Boto3のResource APIを利用してAmazon S3 バケットのPrefixごとにライフサイクル設定をする

対象読者

  • 大量のライフサイクル設定を依頼されて泣きそうな方
  • Amazon S3 バケットにライフサイクル設定をしたい方
  • ライフサイクル設定をAmazon S3 コンソールからポチポチ頑張りたくない方
  • AWS CLIではなくBoto3を利用してライフサイクル設定をしたい方

できるようになること


内容

実行環境

Python 3.10.4
Boto3 1.24.69


手順

Boto3では個々のライフサイクルルールはdict型として、ライフサイクルルール全体はlist[dict]型として扱われます。以下の手順に沿って、バケットに設定するライフサイクルルール全体のlist[dict]を作成していきます。

  1. 既存ライフサイクルルールのバックアップ準備
  2. 既存ライフサイクルルールを取得する
  3. 追加するライフサイクルルールの雛形を作成する
  4. 新規ライフサイクルルールを作成する
  5. 新規ライフサイクルルールを設定する

import datetime
import json

import boto3
from botocore.exceptions import ClientError
  1. 既存ライフサイクルルールのバックアップ準備
def save_rules(rules: list[dict]) -> None:
   fmt = '%Y-%m-%dT%H:%M:%SZ'
   now = datetime.datetime.now()
   file_name = now.strftime(fmt)
   output_path = f'./{file_name}.json'

   with open(output_path, mode='w', encoding='utf-8') as f:
      f.write(json.dumps(rules,indent=2))
  1. 既存ライフサイクルルールを取得する
s3_resource = boto3.resource('s3')
bucket_lifecycle_configuration = s3_resource.BucketLifecycleConfiguration('<バケット名>')

BucketLifecycleConfigurationにライフサイクル設定を行う対象バケット名を設定します。

is_use_current_rules = True # 既存ライフサイクルルールを利用するか否か

try:
    current_rules = bucket_lifecycle_configuration.rules # 既存ライフサイクルルールを取得
    save_rules(current_rules) # 既存ライフサイクルルールを出力
    current_rules = current_rules if is_use_current_rules else []
except ClientError as error:
    current_rules = []
    print(error)

対象バケットに設定されている既存ライフサイクルルールを取得し、後で泣いてしまわないようにバックアップしておきます。このとき、既存ルールを継続利用しない場合は空リストで上書きします。

  1. 追加するライフサイクルルールの雛形を作成する[1]
  rule ={
          'Expiration': {'Days': オブジェクト作成後の日数},
          'ID': ライフサイクルルール名,
          'Filter': {'Prefix': プレフィックス},
          'Status': 'Enabled'
  }

Prefixごとに有効期限日数を設定するだけのシンプルな雛形を作成しました。この雛形は以下のAmazon S3 コンソールによるライフサイクル設定と同じです。

  1. 新規ライフサイクルルールを作成する
def make_rule(
              prefix: str,
              expiratoin_days: int,
             ) -> dict:
  prefix = str(prefix)
  expiratoin_days = int(expiratoin_days)

  rule ={
          'Expiration': {'Days': expiratoin_days},
          'ID': prefix,
          'Filter': {'Prefix': prefix},
          'Status': 'Enabled'
  }
  
  return rule

先程の雛形を元にライフサイクルルールを作成する関数を作り、量産体制を整えます。今回はライフサイクルルール名(ID)とプレフィックス(Prefix)が同一のルールとしました。

prefix_list = ['prefix_A/','prefix_B/','prefix_C/'] # ライフサイクルルール名&プレフィックス
expiratoin_days_list = [1,7,365] #有効期限日数

additional_rules = [ make_rule(prefix, expiration_days) for prefix, expiration_days in zip(prefix_list, expiratoin_days_list) ]

追加設定する値を用意し、追加ルールを作成していきます。

  1. 新規ライフサイクルルールを設定する
bucket_lifecycle_configuration.put(LifecycleConfiguration={'Rules': current_rules + additional_rules })

結果



Prefixごとにライフサイクル設定をすることができました。有効期限日数もそれぞれに対応する値が設定されています。お疲れ様でした!

参考

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#bucketlifecycleconfiguration
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/example_s3_PutBucketLifecycleConfiguration_section.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/intro-lifecycle-rules.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/lifecycle-configuration-examples.html

🔔採用情報

ジム施設向けDXソリューションGYMDXではエンジニアを積極採用中です。
ジュニア層のエンジニアからリーダー職まで幅広く募集しています。

2022年7月にプレシリーズAラウンドにて資金調達を実施しました。
https://prtimes.jp/main/html/rd/p/000000015.000055404.html

リードエンジニア

https://herp.careers/v1/optfit/GpvSeC-fA995

バックエンドエンジニア

https://herp.careers/v1/optfit/KsDmlZ1VhTmU

脚注
  1. Boto3 Docsにルールの設定項目と雛形が存在しますが、設定できる項目が多く混乱します。もし可能であれば初回はS3コンソールで目的のルールを設定後に既存ルールとして出力し、出力されたルールを真似するのが楽だと思います。 ↩︎

Discussion

ログインするとコメントできます