CDK destroyコマンドによる誤削除を防ぐ方法例

CDK destroyコマンドによる誤削除を防ぐ方法例

Clock Icon2024.09.18

はじめに

こんにちは。アノテーションの及川です。

AWS のインフラ管理に CDK(Cloud Development Kit)を使用している開発者の皆さん、誤ってcdk destroyコマンドを実行してしまい、重要なリソースが削除されるヒヤリハット経験はありませんか?

本記事では、そのような事故を防ぐための効果的な方法例を紹介します。

背景

開発環境で予期せぬ事態が発生したことがきっかけです。

開発者が誤ってcdk destroyコマンドを CLI から実行し、開発環境の AWS リソースが大量に削除されてしまいました。

幸い、迅速な対応により環境は復旧しましたが、この経験から同様の事態を防ぐ仕組みの必要性を強く感じ、方法を検討しました。

解決策の検討

この問題に対処するため、CloudFormation を使用して、CDK の実行に関わる IAM ロールに対し、DeleteStack(API) の実行を明示的に拒否する仕組みを検討しました。

DeploymentActionRole

This IAM role grants permission to perform deployments into your environment. It is assumed by the CDK CLI during deployments.

By using a role for deployments, you can perform cross-account deployments since the role can be assumed by AWS identities in a different account.

このテンプレートは、CDK のデプロイロールに対して、すべてのリソースに対する DeleteStack の実行を拒否するポリシーを適用します。

CloudFormation テンプレート

以下が、実装したCloudFormation テンプレートの一例です。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Attach deny delete stack policy to CDK deploy role'

Parameters:
  Qualifier:
    Type: String
    Default: 'hnb659fds'
    Description: 'The qualifier used in the CDK bootstrap process'

Resources:
  DenyDeleteStackPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub 'deny-delete-stack-policy-${AWS::AccountId}-${AWS::Region}'
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Deny
            Action:
              - cloudformation:DeleteStack
            Resource: '*'
      Roles:
        - !Sub 'cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}'

Outputs:
  DenyDeleteStackPolicyArn:
    Description: ARN of the Deny Delete Stack Policy
    Value: !Ref DenyDeleteStackPolicy

実際にやってみた

適当に AWS CDK のプロジェクトを作成して、cdk deploy コマンドで AWS リソースをデプロイします。

% cdk deploy

✨  Synthesis time: 2.59s

StackDeletionPreventionTestStack: deploying... [1/1]
StackDeletionPreventionTestStack: creating CloudFormation changeset...

 ✅  StackDeletionPreventionTestStack (no changes)

✨  Deployment time: 1.65s

そして、前述の CloudFormation テンプレートを用いて、CDK のデプロイロールに対して、すべてのリソースに対する DeleteStack の実行を拒否するポリシーを適用します。

CloudFormation スタック作成

Cfn-1

CDK のデプロイロールへ適用されている様子

Cfn-2

cdk destroy コマンド実行(1回目)

想定したとおり、DeleteStack に対して、明示的な拒否(explicit deny)が適用されているため、cdk destroyコマンドによるスタックの削除が許可されず失敗します。

% cdk destroy

Are you sure you want to delete: StackDeletionPreventionTestStack (y/n)? y
StackDeletionPreventionTestStack: destroying... [1/1]

❌  StackDeletionPreventionTestStack: destroy failed Error: User: arn:aws:sts::xxx:assumed-role/cdk-hnb659fds-deploy-role-xxx-ap-northeast-1/aws-cdk-xxx is not authorized to perform: cloudformation:DeleteStack on resource: arn:aws:cloudformation:ap-northeast-1:xxx:stack/StackDeletionPreventionTestStack/d2bcf110-74c2-11ef-bbeb-0e59ae201859 with an explicit deny in an identity-based policy
    at destroyStack (/Users/xxx/dev/aws/awscdk/stack-deletion-prevention-test/node_modules/aws-cdk/lib/index.js:427:2204)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async CdkToolkit.destroy (/Users/xxx/dev/aws/awscdk/stack-deletion-prevention-test/node_modules/aws-cdk/lib/index.js:430:204806)
    at async exec4 (/Users/xxx/dev/aws/awscdk/stack-deletion-prevention-test/node_modules/aws-cdk/lib/index.js:485:54250)

User: arn:aws:sts::xxx:assumed-role/cdk-hnb659fds-deploy-role-xxx-ap-northeast-1/aws-cdk-xxx is not authorized to perform: cloudformation:DeleteStack on resource: arn:aws:cloudformation:ap-northeast-1:xxx:stack/StackDeletionPreventionTestStack/d2bcf110-74c2-11ef-bbeb-0e59ae201859 with an explicit deny in an identity-based policy

cdk destroy コマンド実行(2回目)

DeleteStack の実行を明示的に拒否するポリシーの効果有無を確かめるため、こちらのポリシーを作成したスタックを削除した場合に、当該 CDK スタックがcdk destroyより削除されるかについても検証してみました。

Cfn-3

CDK のデプロイロールに対して、すべてのリソースに対する DeleteStack の実行を明示的に拒否するポリシーが適用されていないため、cdk destroyコマンドは成功します。

% cdk destroy

Are you sure you want to delete: StackDeletionPreventionTestStack (y/n)? y
StackDeletionPreventionTestStack: destroying... [1/1]

✅  StackDeletionPreventionTestStack: destroyed

効果

この仕組みを用いることで、cdk destroyコマンドの誤った実行による意図しないリソースの削除を防ぐことができます。

開発者は通常の CDK の操作(デプロイなど)を行えますが、cdk destroyコマンドは拒否されるため、重大な事故を未然に防ぐことができます。

注意点

  • この方法は開発環境や重要な本番環境に適していますが、頻繁にリソースの削除が必要な環境では不向きな場合があります。
  • CDK の正常な操作に影響を与えないよう、適宜慎重にテストを行ってください。
  • この仕組みは CDK CLI を通じた削除を防ぐものであり、CloudFormation コンソールや AWS CLI からの直接的なスタック削除は防げないことに注意してください。

まとめ

CDK destroy コマンドによる誤削除は、開発プロセスに大きな影響を与える可能性があります。

本記事で紹介した方法を行うことで、CDK destroy コマンドによる誤削除のリスクを大幅に軽減することが可能ですが、それぞれの AWS 環境の状況などにしたがって、適宜ご活用いただければ幸いです。

また、本記事以外にも本件に関連する弊社ブログもございますので、こちらも必要に応じてご参照いただき適宜お試しください。

https://dev.classmethod.jp/articles/cloudformation-stack-prevent-deletion-summary/

https://dev.classmethod.jp/articles/configure-deletion-protection-for-cloudformation-stack-with-aws-cdk/

この記事が誰かのお役に立てば幸いです。

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。

参考資料

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.