この記事は公開されてから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を一括で空にするシェルスクリプトを作ってみました。
やってみた
シェススクリプト
作成したシェルスクリプトは以下となります。
empty-cfn-managed-buckets.sh
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
以上