🪣

Amazon S3 バケットの terraform destroy に注意

2023/12/11に公開

TL;DR

  • Amazon S3 バケットを削除する前には,必ずすべてのオブジェクトを削除しよう。
    • aws_s3_bucket リソースの force_destroy 引数 を true にしてもよい。
  • terraform destroy で削除すると,パブリックアクセスできる旨のアラートが出る場合があるので注意しよう。
    • aws_s3_bucket_public_access_block リソースを terraform state rm するとアラートが出ない。
    • マネジメントコンソールから削除してもアラートは出ない。

S3 バケットの terraform destroy で生じる問題

Terraform で管理していた Amazon S3 バケットが不要になったとき,terraform destroy で削除することがあります。

ただ,無邪気に実行してしまうと厄介なことが起きる場合があります。

オブジェクトが残っていてバケットの削除に失敗

バケット内にオブジェクトが残っていると,エラーが出てバケットの削除に失敗してしまいます。

オブジェクトをバージョンも含めて全削除する必要があります。

パブリックアクセスブロックが先に削除される

Terraform ではバケットの各種設定も別リソースで管理されています。
パブリックアクセスブロックもその一つで,一括削除するとこちらが先に削除されることがあります。

そうするとバケットが削除されるまでの一瞬だけ「パブリックアクセスブロックが設定されていないバケットが存在」することになり,AWS Config や Amazon GuardDuty で監視が設定されている場合は引っかかってアラートが出ることになります。
一瞬なので実害はほぼないですが,誤検知について説明する必要があります。

また,もしオブジェクトが残っていた場合は,バケットの削除には失敗するが,パブリックアクセスブロックは削除されてしまい,公開バケットが残るという厄介な事態になります。

対策

オブジェクト削除

何らかの方法ですべてのオブジェクト・バージョンを削除しましょう。

  • マネジメントコンソール・CLI で手動削除
  • ライフサイクルルール
  • force_destroy 属性
  • API で大量削除

数が少なければマネジメントコンソールでも CLI でもできますが,大量に存在する場合は,ライフサイクルルールを設定すると確実に空にできます。ただし,削除が実行されるのは AWS 側のタイミング次第で,1日待たないといけない場合もあります。

https://repost.aws/ja/knowledge-center/s3-empty-bucket-lifecycle-rule

あるいは,aws_s3_bucket リソースの force_destroy 属性を true にしておくと,オブジェクト削除もできるので,バケット削除までできます。ただし,通常運用時に誤操作によるオブジェクト削除がないかに気をつける必要があります。

またお急ぎの場合は,以下のようなツールを利用して,API の最大レートで削除する方法もあります。

https://go-to-k.hatenablog.com/entry/cls3

バケット削除

terraform destroy でバケットを削除する場合は,前もって terraform state rm コマンドで aws_s3_bucket_public_access_block リソースを state から除外しておくとよいでしょう。
パブリックアクセスブロックだけ先に削除されることなく,バケットごと削除されます。

https://github.com/hashicorp/terraform-provider-aws/issues/12153#issuecomment-1090024248

また,マネジメントコンソールからバケットを削除しても,アラートが出ずに済みます。

Discussion