Serverless Framewok便利ですね。
S3を作ったからにはモノを置くと思うんですが、この状態でremoveしようとすると、空じゃないバケットをremoveしてはダメらしくエラーが出ます。
An error occurred: xxxBucket - The bucket you tried to delete is not empty
そこで探し当てたのがserverless-s3-remover
sls remove時に先に指定S3バケットを空っぽにしてくれるという優れもの。
ただちょっと扱いに難ありだったのでここに記録を残します。
ずいぶんメンテされてないようですが、十分使えます。
最終的なyaml構成
service: ez-s3-remove
provider:
name: aws
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'ap-northeast-1'}
profile: ${opt:profile, 'default'}
deploymentBucket: 'sls-deploy-bucket'
resources:
Resources:
myBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName:
Fn::Join:
- ""
- - '${self:service}-${self:provider.stage}-'
- Ref: AWS::AccountId
Outputs:
myBucket:
Value: !Ref myBucket
plugins:
- serverless-s3-remover
custom:
remover:
buckets:
- ${cf:${self:service}-${self:provider.stage}.myBucket, ''}
ここに至る過程を書きます。
ただの日記です。
過程
ベースとなるyamlファイル
S3だけ作る簡単なものです。
service: ez-s3-remove
provider:
name: aws
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'ap-northeast-1'}
profile: ${opt:profile, 'default'}
deploymentBucket: 'sls-deploy-bucket'
resources:
Resources:
myBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName:
Fn::Join:
- ""
- - '${self:service}-${self:provider.stage}-'
- Ref: AWS::AccountId
これだけだとremoveするときにファイルがあるとエラーになってしまいます。
serverless-s3-removerを追加
npm i -D serverless-s3-remover
プラグインを使うようにyamlを変更。
対象バケット名をRefで参照。
service: ez-s3-remove
provider:
name: aws
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'ap-northeast-1'}
profile: ${opt:profile, 'default'}
deploymentBucket: 'sls-deploy-bucket'
resources:
Resources:
myBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName:
Fn::Join:
- ""
- - '${self:service}-${self:provider.stage}-'
- Ref: AWS::AccountId
plugins:
- serverless-s3-remover
custom:
remover:
buckets:
- !Ref myBucket
そして最初のremove
S3 Remover: Faild: [object Object] may not be empty.
~略~
An error occurred: myBucket - The bucket you tried to delete is not empty
だめだ…
何かエラーが出ている。
オブジェクトが消せてないためCloudFormationのエラーも変わりません。
バケット名の参照の仕方を変えてみる
もともとRefでバケット名がとれるんだっけ?と思い、バケット名と同じ書き方で直接突っ込んでみる
custom:
remover:
buckets:
- Fn::Join:
- ""
- - '${self:service}-${self:provider.stage}-'
- Ref: AWS::AccountId
remove
S3 Remover: Faild: [object Object] may not be empty.
~略~
An error occurred: myBucket - The bucket you tried to delete is not empty
だめ。
どうやらRefとか関数をかますと動かない模様。
解決編
いろいろ調べてこのIssueに到達。
https://github.com/sinofseven/serverless-s3-remover/issues/3#issuecomment-621385163
CloudFormationのOutputsを参照すればいいとのこと。
Outputs:
myBucket:
Value: !Ref myBucket
plugins:
- serverless-s3-remover
custom:
remover:
buckets:
- ${cf:${self:service}-${self:provider.stage}.myBucket, ''}
そしてremove
S3 Remover: Success: ez-s3-remove-dev-xxxxxxxx is empty.
~略~
Serverless: Stack removal finished...
やった!成功です!
CloudFormationのOutputsって使いどころよくわからず使ってこなかったんですが、初めて活躍しました。
書き方も簡単ですね。
まとめ
最近はAWS SDKにも興味があります。TypeScript補完がかなり効くらしいので。
CloudFormationのyamlを手で書くのがつらい…