[AWS CDK(Cloud Development Kit)] スタック削除時にS3バケットも削除されるように設定する

コンニチハ、千葉です。

CDKの検証で、スタック環境を作成、削除をしていたのですが、cdk destroy を実行しても作成したS3バケットが残ってました。なぜだろう?と思い調査をはじめました。

背景

GitHubのイシューを見つけました。

  • S3のデフォルトは削除ポリシーがRetain(つまりCFnスタックを削除されてもバケットが残る)
  • この動作は、cdk destroy を実行した場合に、失敗することがあるため。理由としては、S3バケットが空でないとバケットが削除できない
  • CloudWatchロググループもRetainとなっている

今後、デフォルト値がアップデートされる可能性がありますが、現状はRetainとなっています。

デフォルトの挙動確認

デフォルトの動作確認です。通常通りS3を作成してみます。コードは以下です。

from aws_cdk import (
    aws_s3 as s3,
    core
)

class CdkMultiSampleStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here
        bucket = s3.Bucket(self,
            "cdk-s3-multi-sample")

このコードからCloudFormationテンプレートを出力します。cdk synthを実行して出力されたjsonを確認しました。

{
  "Resources": {
    "cdks3multisample47C6CE34": {
      "Type": "AWS::S3::Bucket",
      "UpdateReplacePolicy": "Retain",
      "DeletionPolicy": "Retain",
      "Metadata": {
        "aws:cdk:path": "Stack-dev-tokyo/cdk-s3-multi-sample/Resource"
      }
    }
  }

出力されるCloudFormationテンプレートにデフォルトでRetainが付与されていますね。つまり、cdk destroy をやってもCDKで作成したS3バケットが削除されない状況でした。

削除されるように設定を変更する

removal_policy = core.RemovalPolicy.DESTROY を入れることで、削除されるように変更できました。

from aws_cdk import (
    aws_s3 as s3,
    core
)

class CdkMultiSampleStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here
        bucket = s3.Bucket(self,
            "cdk-s3-multi-sample",
            removal_policy = core.RemovalPolicy.DESTROY)

cdk synthを実行してみました。

{
  "Resources": {
    "cdks3multisample47C6CE34": {
      "Type": "AWS::S3::Bucket",
      "UpdateReplacePolicy": "Delete",
      "UpdateReplacePolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "Stack-dev-tokyo/cdk-s3-multi-sample/Resource"
      }
    }
  }
}

UpdateReplacePolicyUpdateReplacePolicyDeleteとなってますね。これで、destroy時にS3バケットも削除されるようになりました。(ただし、事前にバケットの中を空にしておく必要があります)

最後に

ちょっと紛らわしい動作で混乱しました。もしハマった方がいたら参考になると嬉しいです。

参考

  • https://github.com/aws/aws-cdk/issues/2601
  • https://docs.aws.amazon.com/cdk/api/latest/docs/aws-s3-deployment-readme.html