🪣

CloudFormationにもS3バケットの中身を空にしてから削除してくれるリソースタイプが存在します。

2023/09/29に公開

CloudFormationでもオブジェクト削除を兼ねたバケット削除をするリソースタイプが存在する。

以下のようにS3バケットの中に存在するオブジェクトを削除した後、バケットを削除してくれるのは、CDKだけの画期的な機能と認識されている方は多いと思います。勿論私もそうでした。

      removalPolicy: RemovalPolicy.DESTROY,
      autoDeleteObjects: true,

上記はCustomResouceのLambdaが作成され、前述の意図の動作を実現させるものです。

CloudFormationにもありましたので記事にしました。


手順

実行ロールの準備

CFnコンソールに移動して以下テンプレートを実行してください。

resource-role-prod.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: >
  This CloudFormation template creates a role assumed by CloudFormation
  during CRUDL operations to mutate resources on behalf of the customer.

Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      MaxSessionDuration: 8400
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: resources.cloudformation.amazonaws.com
            Action: sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: ResourceTypePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                - "s3:DeleteObject"
                - "s3:GetBucketTagging"
                - "s3:ListBucket"
                - "s3:ListBucketVersions"
                - "s3:PutBucketTagging"
                - "cloudformation:ListExports"
                Resource: "*"
Outputs:
  ExecutionRoleArn:
    Value:
      Fn::GetAtt: ExecutionRole.Arn


このテンプレートから生成されるスタックではIAMRoleが作られます。


出力にあるARNをコピーしておいてください。


拡張機能のアクティブ化













先ほどの拡張機能検索画面でも「アクティブ化済み」となっている事が確認出来ます。


拡張機能としてレジストリから追加したリソースタイプを使ってみる。

ドキュメント(ユーザーガイドにあたるもの)のリンクも置いておきます。
https://github.com/aws-cloudformation/community-registry-extensions

https://github.com/aws-cloudformation/community-registry-extensions/tree/main/resources/S3_DeleteBucketContents

以下テンプレートを実行。

※注意点としては一行目に

AWSTemplateFormatVersion: "2010-09-09"

を書いてはいけません。

↓で正常動作します。↑を存在させてしまった場合はバケット作成完了後、Deleterの作成が進みません。

Resources:
  Bucket:
    Type: AWS::S3::Bucket

  Deleter:
    Type: AwsCommunity::S3::DeleteBucketContents
    Properties:
      BucketName: !Ref Bucket
ちなみに

※本来は下記のようにprod以外でしかここでいうDeleterが作成されないようにする事が推奨されています。

Parameters:
  EnvType:
    Description: Environment type.
    Default: alpha
    Type: String
    AllowedValues:
      - alpha
      - beta
      - gamma
      - prod
    ConstraintDescription: Specify alpha, beta, gamma, or prod
Conditions:
  IsNotProd: !Not 
    - !Equals
      - !Ref EnvType
      - prod
Resources:
  Bucket:
    Type: AWS::S3::Bucket
  Deleter:
    Condition: IsNotProd
    Type: AwsCommunity::S3::DeleteBucketContents
    Properties:
      BucketName: !Ref Bucket

無事作成完了しました。



作成されたS3バケットにtest.txtが存在するtestフォルダをアップロードしてみます。

スタックを削除してみます。


オブジェクトが入っていたバケットのはずですが、削除が完了しました。

注目したいのは先にDeleterが削除されている事。
つまり、Deleterという実態がなんらか存在していたのであれば、
CFnコンソールにはオブジェクトデリートというアクション自体は記載されないものの、動作を終えてから削除され、その後バケットが削除されたという順番と読めます。

先にお話ししておくと、今回のDeleterリソースはLambda関数等が作成されたものではない事は、念のためコンソールからも確認済みです。

こういう事をしているのだなと以下から読見とれましたが、これがどのようにして実行されているのがが私にはいまいち理解出来ていません。
https://github.com/aws-cloudformation/community-registry-extensions/blob/main/resources/S3_DeleteBucketContents/src/awscommunity_s3_deletebucketcontents/handlers.py

もしご説明が可能な方がいらっしゃれば、是非記事作成者にコメントいただければ幸いです。


以上でした。

有難うございました。

Discussion