AWS CloudFormationの指定のStackで管理されている全てのS3 Bucketを一括で空にするシェルスクリプトを作ってみた
こんにちは、CX事業本部 IoT事業部の若槻です。
S3 Bucketのbucketを削除する際に、Bucketが空でなければ削除できないというのは周知の事実かと思います。
Make sure the bucket is empty – You can only delete buckets that don't have any objects in them. Make sure the bucket is empty.
なのでbucketを削除したい時には「bucketを空にする」→「bucketを削除する」を1セットで行う必要があります。これはAWS CloudFormation(AWS CDK)で作成したbucketの場合も同様で、CloudFormation Stackで管理しているrecourceを本来なら一括で削除できる(removal policyをDESTROY
にしている場合)ところ、事前に手動でbucketを空にしておかないといけません。
そこで今回は、AWS CloudFormationの指定のStackで管理されている全てのS3 Bucketを一括で空にするシェルスクリプトを作ってみました。
やってみた
シェススクリプト
作成したシェルスクリプトは以下となります。
targetStackName=${1} buckets=$( \ aws cloudformation describe-stack-resources \ --stack-name ${targetStackName} \ --query 'StackResources[?ResourceType==`AWS::S3::Bucket`].PhysicalResourceId[]') bucketsLen=$(echo ${buckets} | jq length) if [ bucketsLen -eq 0 ]; then echo "Bucket resources not found in specified stack." exit fi echo "" echo "Buckets:" echo ${buckets} | jq . echo "" read -p "Do you empty these buckets ? (y/N): " yn case "$yn" in [yY]*) ;; *) echo "abort." ; exit ;; esac for i in $( seq 0 $((${bucketsLen} - 1)) ); do bucket=$(echo ${buckets} | jq -r .[$i]) aws s3 rm --recursive s3://${bucket} done
- AWS CLIのcloudformation describe-stack-resourcesコマンドで指定のCloudFormation StackのResoucreをListし、ResourceTypeが
AWS::S3::Bucket
のResouceのみ変数に格納しています。 - 取得した各Bucketに対してfor文でs3 rmコマンドを
--recursive
オプションを使用して実行し、Bucket内のすべてのオブジェクトを削除して空にしています。
シェルスクリプトのファイルに実行可能権限を付与します。
$ chmod +x empty-cfn-managed-buckets.sh
動作確認
管理しているBucketが空ではないStackProcessStack
があります。cdk destroy
コマンドでDestroyしようとすると案の定エラーとなります。
$ cdk destroy ProcessStack Are you sure you want to delete: ProcessStack (y/n)? y ProcessStack: destroying... 12:27:25 AM | DELETE_IN_PROGRESS | AWS::CloudFormation::Stack | ProcessStack 12:27:28 AM | DELETE_FAILED | AWS::S3::Bucket | hogeBucket The bucket you tried to delete is not empty (Service: Amazon S3; Status Code: 409; Error Code: BucketNotEmpty; Request ID: XMNQMWW P38RT6KBE; S3 Extended Request ID: LdExLHGa0BZenrReyjCLKjScvwh//DygdIGSe0F8p/Ah+2zReMF7AgbBcE3ThRZ6ALXLgdv6aKc54T4ySZxRlw==; Proxy : null)
そこでProcessStack
を指定して前述のスクリプトを実行します。Yes/Noの確認プロンプトを挾み、管理されている2つのbucketを空にすることができました。
$ sh ./empty-cfn-managed-buckets.sh ProcessStack ./empty-cfn-managed-buckets.sh: line 10: [: bucketsLen: integer expression expected Buckets: [ "processstack-databucketd8691f4e-1qncl1zy7gvfm", "processstack-hogebucketd41d3f4e-w59igilmmrsb" ] Do you empty these buckets ? (y/N): y delete: s3://processstack-databucketd8691f4e-1qncl1zy7gvfm/deliveryStream-1-2022-08-10-13-55-33-04431990-8c8d-465f-b41b-fcda45713eac delete: s3://processstack-hogebucketd41d3f4e-w59igilmmrsb/deliveryStream-1-2022-08-10-13-55-33-04431990-8c8d-465f-b41b-fcda45713eac
bucketを空にした後は、同じcdk destroy
コマンドでstackをdestroyすることができました!
$ cdk destroy ProcessStack Are you sure you want to delete: ProcessStack (y/n)? y ProcessStack: destroying... ✅ ProcessStack: destroyed
おわりに
AWS CloudFormationの指定のStackで管理されている全てのS3 Bucketを一括で空にするシェルスクリプトを作ってみました。
案件やブログの執筆のために検証用のAWS resourceをCDKで作ったり壊したりをしょっちゅう繰り返すウノで、こんなシェルスクリプトがあるといいな、ということで作ってみました。
参考
- Filtering AWS CLI output - AWS Command Line Interface
- /bash
- BASHシェルスクリプトで「キー入力待ち」プロンプトを実装する | DevelopersIO
以上