Bootstrap an environment and deploy with the CDK
Prepare an account and Region for CDK deployments and deploy safely — cdk bootstrap with termination protection, scoped execution policies instead of AdministratorAccess, trusting a CI or tools account, choosing deploy options (approval, method, rollback, hotswap, express) and checking that the deploy really went through the bootstrap roles.
markdownguidev405CR-4AGQstage: deploytrust: officialservice: cdkservice: cloudformationinterface: cliinterface: iaccdk bootstrapbootstrap each environmentcdk bootstrap --trustcloudformation-execution-policies least privilegepermissions boundary bootstraptermination-protection CDKToolkitre-bootstrap upgradecdk deployrequire-approval broadening--method change-set direct--no-rollback cdk rollback--hotswap production--express--concurrency--outputs-filecross-account CDK deploymentcdk deploy CI
Bootstrap every account and Region once, with termination protection and an execution policy you chose. Then deploy with change sets and rollback on. The bootstrap's default execution role has AdministratorAccess. So unless you scope it, anyone who can assume the deploy role can create anything through CloudFormation.
1. Bootstrap
Use an identity with broad rights (cloudformation:*, ecr:*, ssm:*, s3:*, iam:*):
cdk bootstrap aws://<account-id>/<region> \
--termination-protection \
--cloudformation-execution-policies "arn:aws:iam::<account-id>:policy/CdkExecution"
- Execution policies go on the role CloudFormation uses, so they must cover everything every CDK app in this environment creates: Lambda, IAM roles, S3 and the rest. Otherwise deployments fail with access denied on a resource (
reference/cloudformation/errors.md). Leaving the option out meansAdministratorAccess. For a guardrail that still allows broad creation, add--custom-permissions-boundary <policy-name>. - Each environment needs its own bootstrap, and the CDK never does it automatically. Bootstrapping early also reserves the staging bucket name.
- Bootstrapping again is safe and upgrades the template when needed. Re-run it after CLI upgrades when a deploy asks for a newer bootstrap version. Previous option values carry over unless you pass
--no-previous-parameters. - Never delete
CDKToolkitto "reset" it. - The resources and roles created are listed in
reference/cdk/bootstrap-roles-and-trust.md.
2. Trust another account (CI, tools or pipeline account)
In the target account:
cdk bootstrap aws://<target-account>/<region> \
--trust <tools-account> --trust <other-existing-trusted-account> \
--cloudformation-execution-policies "arn:aws:iam::<target-account>:policy/CdkExecution"
--trustreplaces the trusted list, so repeat every account you already trust.--trustrequires--cloudformation-execution-policies: the CLI won't silently grant administrator to another account.- Accounts that only need to synth (context lookups) get
--trust-for-lookupinstead. - In the tools account, the deploying identity needs an IAM Allow for
sts:AssumeRoleonarn:aws:iam::<target-account>:role/cdk-hnb659fds-*. Both halves are required (guides/iam/cross-account-access.md).
3. Deploy
npx aws-cdk deploy --all --require-approval broadening --outputs-file outputs.json
| Option | Default | Use | |||
|---|---|---|---|---|---|
| `--require-approval any-change\ | broadening\ | never` | broadening | never only in CI with a reviewed change set or diff | |
| `--method change-set\ | direct\ | prepare-change-set\ | execute-change-set` | change-set | prepare-change-set to review first; direct is faster but loses progress detail |
--no-rollback | rollback on | Keep partial progress while iterating, then cdk rollback if needed. Fails for replacing changes | |||
--hotswap, --hotswap-fallback, --watch | off | Development only. They update Lambda code and similar through service APIs with your credentials and leave drift. Clean up with --revert-drift | |||
--express | off | Express mode: finishes when resources are configured, not ready, and rollback is off by default. Don't use it for production gates (reference/cloudformation/stack-operations.md) | |||
--concurrency <n> | 1 | Deploy independent stacks in parallel | |||
--exclusively | off | Skip dependency stacks | |||
--parameters Stack:Key=Value | — | CloudFormation parameters; they don't reach nested stacks | |||
--import-existing-resources | off | Adopt unmanaged resources whose custom names match the template |
Use the project's local CLI (npx aws-cdk). It must be at least as new as aws-cdk-lib.
4. Check the deploy went through the bootstrap roles
- Same account: if your identity can't assume the deploy role, the CLI warns
… could not be used to assume '<role-arn>', but are for the right account. Proceeding anyway.and deploys with your own credentials. That works for admins and hides missing trust until CI fails. Look for this warning in the output. - CloudTrail: in the
CreateChangeSet/ExecuteChangeSetevents,userIdentity.sessionContext.sessionIssuer.arnshould be thecdk-<q>-deploy-role-…. In the events that create your resources, it should be thecdk-<q>-cfn-exec-role-…, withinvokedBynaming CloudFormation, the field CloudTrail sets when a service acts through a service role. Finding the deploying identity there instead means the fallback happened. Seeguides/cloudtrail/find-who-did-what.mdandreference/cloudtrail/event-records.md.
When it fails
- CLI messages (assume-role, bootstrap version, bucket,
--app):reference/cdk/errors.md. - Stack events (
CREATE_FAILED,UPDATE_ROLLBACK_FAILED):guides/cloudformation/fix-failed-stack.md.