如何用 AWS CDK 防止 AI 破壞環境
How to Keep AI from Breaking Your Environment with AWS CDK
AWS CDK CLI v2.1145.0 為 `cdk diff` 加入 `--fail-on destructive`,並讓 `cdk deploy` 可用 `--require-approval destructive` 偵測資源刪除或替換。前者會在出現破壞性變更時令指令失敗,後者會要求用戶確認;作者建議在部署前執行差異檢查,並將其加入 CI/CD 或 AI 自動化流程。
How to Keep AI from Breaking Your Environment with AWS CDK
More and more people are letting AI write their AWS CDK code. At the same time, some may feel uneasy about AI breaking their environment on its own.
For those people, this article introduces a way to safely stop the process only when a change to your CDK code contains a dangerous diff that could break your environment.
Destructive Changes
So what kind of dangerous diff can break an environment?
It is a destructive change, where a resource is deleted or replaced (recreated).
Simply adding a resource or changing a property is usually recoverable. But deleting or replacing a resource can affect your system, causing unexpected downtime or data loss.
Especially these days, some people let AI not only write CDK code but also deploy the resources. You absolutely want to avoid handing CDK development over to AI, running iteration after iteration, and then finding that an important resource has been deleted.
Of course, even if you don't let AI handle the deployment, you probably deploy through CI/CD, especially for production, and the same thing applies to automated deployments in a pipeline.
The Difficulty of Judging Destructive Changes
Some of you may already have been showing diffs to AI and having it judge whether an operation is dangerous. When you leave the judgment to AI, however, it inevitably becomes non-deterministic, which makes it hard to meet a requirement like reliably detecting and preventing destructive changes every single time.
The reason is this: just by looking at the diff of the CloudFormation template that CDK generates, you can tell whether a resource itself will be deleted.
But some AWS resources are replaced, that is, recreated, when a specific property is changed.
So even if the template diff shows no resource deletion, you cannot determine whether the change is destructive unless you can also judge changes to the properties that trigger replacement.
Mechanical Detection of Destructive Changes
The approach introduced here is now possible as a feature of AWS CDK itself: you can detect destructive changes mechanically and deterministically. Compared with having AI judge the diff, this gives you certainty.
In other words, you can now let AI drive development autonomously while reliably blocking only destructive changes for a human to judge, achieving both autonomy and safety.
This enables a workflow where a human decides whether the destructive change is expected, and approves it only in that case so the CI pipeline can move forward.
How to Do This in AWS CDK
AWS CDK CLI v2.1145.0 made the following available on the cdk diff and cdk deploy commands. These are the measures for detecting and preventing destructive changes.
cdk diff --fail-on destructivecdk deploy --require-approval destructive
cdk diff --fail-on destructive
The --fail-on option makes the command fail when a diff occurs and matches the condition you specify.
This option itself did not exist before; it was added in this release. Until now, there was only --fail, which fails the command whenever a diff occurs.
You can pass the following four values to --fail-on. These values are in fact the same ones you can pass to cdk deploy --require-approval, which is described next.
- broadening: fails when there are changes that broaden permissions from a security standpoint, such as adding IAM statements or security group rules
- any-change: fails whenever a diff occurs, no matter what the change is (=
--fail) - never: never fails, no matter what the change is
- destructive: fails when there is a destructive change
Running cdk diff with destructive passed to --fail-on makes it exit with an error only when there are destructive changes such as resource deletions or replacements.
$ npx cdk diff --fail-on destructive
...(omitted)
...
Resources
[-] AWS::ApiGateway::Deployment ChatBackend/ChatApi/Deployment ChatBackendChatApiDeploymentFA87D81751002ae6827233f0ff3b9559424161e2 destroy
[+] AWS::ApiGateway::Deployment ChatBackend/ChatApi/Deployment ChatBackendChatApiDeploymentFA87D8175fd5897368ff8cdd7cc53ed9c4d122c1
[~] AWS::Lambda::Function ChatBackend/HistoryFn ChatBackendHistoryFnCCDE0D46 replace
└─ [+] FunctionName (requires replacement)
└─ changed-name
...
✨ Number of stacks with differences: 1
❌ Found 5 destructive change(s) (--fail-on=destructive):
MyStack: AWS::ApiGateway::Deployment ChatBackend/ChatApi/Deployment ChatBackendChatApiDeploymentFA87D81751002ae6827233f0ff3b9559424161e2 will be destroyed
MyStack: AWS::Lambda::Function ChatBackend/HistoryFn ChatBackendHistoryFnCCDE0D46 will be replaced
...
cdk deploy --require-approval destructive
--require-approval is an option that prompts the user for confirmation when a diff at deploy time matches the condition you specify.
As with cdk diff above, specifying destructive now lets you detect destructive changes and prompt for confirmation.
$ npx cdk deploy --require-approval destructive
...(omitted)
...
Destructive changes:
MyStack: AWS::ApiGateway::Deployment ChatBackend/ChatApi/Deployment ChatBackendChatApiDeploymentFA87D81751002ae6827233f0ff3b9559424161e2 will be destroyed
MyStack: AWS::Lambda::Function ChatBackend/HistoryFn ChatBackendHistoryFnCCDE0D46 will be replaced
...
Stack includes destructive updates and "--require-approval" is set to 'destructive'.
Do you wish to deploy these changes? (y/n)
Putting It into Practice
Whether you let AI drive development autonomously or not — in CI/CD, for example — it is a good idea to run cdk diff --fail-on destructive before you deploy.
With AI, have the command run automatically from within a skill or a hook; with CI/CD, insert a stage right before the deploy. The basic idea is to keep the process running, and when a destructive change does appear, approve it and move on if the change is what you intended.
With this in place, the process stops only on destructive changes inside an autonomous, automated loop, which gives you a workflow that ensures safety at a low cost.
Contributing to the AWS CDK CLI
This feature actually started as an idea I had and wanted for myself. So I implemented it in the upstream repository, opened PRs, and had them merged. It ended up as the following three PRs, making it a fairly large feature addition.
- feat(cli): add
--fail-ontocdk diff - feat(cli): add
destructivetocdk diff --fail-on - feat(cli): add
destructivetocdk deploy --require-approval
Shipped First in cdkd
This feature was in fact shipped first in an OSS CLI tool called cdkd that I develop on my own, and was added to the CDK CLI afterwards. (Only a few days apart, though.)
cdkd is a from-scratch reimplementation of the CDK CLI. It lets you deploy CDK up to 15 times faster without changing a single line of your CDK code. If you are interested, I would be happy if you took a look.
GitHub: go-to-k/cdkd
Final Thoughts
As AI becomes widespread, the way we develop with AWS CDK keeps changing. Still, building infrastructure comes with side effects, so fully automating it remains a little unnerving.
I think the approach introduced here is a well-balanced hybrid that leaves as much as possible to AI while having humans cover only the genuinely dangerous and important parts.
來源:DEV Community · dev.to
