
AWS CloudFormationの指定のStackで管理されている全てのS3 Bucketを一括で空にするシェルスクリプトを作ってみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、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
以上






