AWS CDKで管理しているスタックの削除保護を有効化してみた
AWS CDKで管理しているスタックの削除保護ってどうするんだろう
こんにちは、のんピ(@non____97)です。
「AWS CDKで管理しているスタックの削除保護ってどうするんだろう」と思ったことはありますか? 私はあります。
AWS CDKではcdk destroy
で簡単にスタックを削除できます。私は非常にうっかりさんなので、絶対に削除したくないスタックには念のため削除保護をしたいなと思いました。
そこで、「よし、じゃあ削除保護を有効化するか!」と思ったのですが、実際設定を知らなかったので今回確認してみました。
API Referenceに書いてある
困った時はAPI Referenceということで、確認したら早速見つけました。
スタックを作成する際のプロパティとして、terminationProtection
をtrue
にすれば良さそうですね。
やってみた
実際にやってみます。
まず、terminationProtection
を指定しない場合の削除保護はどうなっているか確認します。
#!/usr/bin/env node import "source-map-support/register"; import * as cdk from "aws-cdk-lib"; import { VpcStack } from "../lib/vpc-stack"; const app = new cdk.App(); new VpcStack(app, "VpcStack");
こちらのスタック(VpcStack
)では以下のようにVPCを作成します。
import { Stack, StackProps, aws_ec2 as ec2 } from "aws-cdk-lib"; import { Construct } from "constructs"; export class VpcStack extends Stack { public readonly vpc: ec2.IVpc; constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new ec2.Vpc(this, "Vpc", { cidr: "10.11.0.0/24", natGateways: 0, }); } }
npx cdk deploy VpcStack
でスタックを作成します。
作成後のスタックをマネージメントコンソールから確認すると削除保護は無効になっていました。
次に、terminationProtection
をtrue
にした場合を確認します。
以下のようにVpcStack
の第3引数で指定しました。
#!/usr/bin/env node import "source-map-support/register"; import * as cdk from "aws-cdk-lib"; import { VpcStack } from "../lib/vpc-stack"; const app = new cdk.App(); new VpcStack(app, "VpcStack", { terminationProtection: true, });
変更後、npx cdk deploy VpcStack
でスタックを更新します。
更新後のスタックをマネージメントコンソールから確認すると削除保護は有効になっていました。
この状態でスタックを削除しようとすると、とてつもなく怒られました。確かに削除保護が動作していますね。
> npx cdk destroy VpcStack MFA token for arn:aws:iam::<AWSアカウントID>:mfa/<IAMユーザー名>: 768613 Are you sure you want to delete: VpcStack (y/n)? y VpcStack: destroying... ❌ VpcStack: destroy failed Error [ValidationError]: Stack [VpcStack] cannot be deleted while TerminationProtection is enabled at Request.extractError (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/protocol/query.js:50:29) at Request.callListeners (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:686:14) at Request.transition (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/state_machine.js:14:12) at /<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:688:12) at Request.callListeners (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/sequential_executor.js:116:18) { code: 'ValidationError', time: 2022-03-11T08:37:57.965Z, requestId: '68d8d382-b030-4dcb-aef0-d6f17863e8b2', statusCode: 400, retryable: false, retryDelay: 791.5998092652587 } Stack [VpcStack] cannot be deleted while TerminationProtection is enabled
最後にこの状態で、terminationProtection
をfalse
にして、npx cdk destroy VpcStack
を実行します。
#!/usr/bin/env node import "source-map-support/register"; import * as cdk from "aws-cdk-lib"; import { VpcStack } from "../lib/vpc-stack"; const app = new cdk.App(); new VpcStack(app, "VpcStack", { terminationProtection: false, });
MFA token for arn:aws:iam::<AWSアカウントID>:mfa/<IAMユーザー名>: 722992 Are you sure you want to delete: VpcStack (y/n)? y VpcStack: destroying... ❌ VpcStack: destroy failed Error [ValidationError]: Stack [VpcStack] cannot be deleted while TerminationProtection is enabled at Request.extractError (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/protocol/query.js:50:29) at Request.callListeners (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:686:14) at Request.transition (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/state_machine.js:14:12) at /<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/request.js:688:12) at Request.callListeners (/<ディレクトリパス>/cdk/database/node_modules/aws-sdk/lib/sequential_executor.js:116:18) { code: 'ValidationError', time: 2022-03-11T08:44:43.218Z, requestId: 'd33ac328-2491-47a7-bcbf-77bb4c4c0b30', statusCode: 400, retryable: false, retryDelay: 532.5637111139594 } Stack [VpcStack] cannot be deleted while TerminationProtection is enabled
やはりとてつもなく怒られました。スタックの更新をせずに削除しようとするな。横着するな。ということですね。
そのため、スタックを削除したい場合は、一度terminationProtection
をfalse
にした状態でcdk deploy
をした上で、cdk destroy
をする必要があります。
本番運用中は削除保護の有効化がオススメ
AWS CDKで管理しているスタックの削除保護を有効化してみました。
クロススタック参照している場合、参照先のスタックを削除してしまうと、参照元のスタックも削除されてしまいます。そういった意図しないスタック削除を防ぐ意味で削除保護が非常に大切です。開発期間中はterminationProtection
をfalse
にしておいて、本番稼働後はterminationProtection
をtrue
にするといった運用をすれば安心かと思います。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!