skip to content

In the AWS CDK, what does `cdk diff` compare, and what will it fail to warn you about before a deploy?

level: middleimportance: should knowfreq 55%

answer

  1. local template versus deployed template
  2. not a comparison against live resources
  3. IAM and security-group changes broken out
  4. replacement warnings come from a change set
  5. drift stays invisible to it

basics

~20 s

cdk diff synthesizes locally and compares that template against the template CloudFormation currently stores for the deployed stack, printing resource, IAM and security-group changes. It compares templates, not live resources, so console-made drift is invisible to it.

solid answer

~50 s

`cdk diff` runs synthesis, then reads the template CloudFormation holds for the deployed stack of the same name and prints the difference: added, removed and modified resources, which modifications force a replacement, and separate tables for IAM statement and security-group changes. Recent CLI versions create a change set behind the scenes so the replacement analysis reflects what CloudFormation would really do; `--no-change-set` skips that if you lack the permissions. In CI you run it with `--fail`, which exits non-zero when there are differences. Its blind spot follows from the comparison it makes: if someone changed a resource in the console, CloudFormation's stored template still matches your code, so diff reports nothing — you need drift detection for that. It also cannot show values only resolved during deployment, and a stack that has never been deployed shows up entirely as additions.

go deeper

for a junior

Get into the habit of running cdk diff before cdk deploy, and know it prints what would be added, changed or removed — without touching anything in AWS.

for a middle

Say precisely what the two sides of the comparison are, local synthesized template versus the deployed stack's stored template, and point at the separate IAM and security-group sections as the ones worth reading closely.

for a senior

Demonstrate the blind spots and what covers them: drift detection for console edits, diffing consumer stacks of a changed export, and moving the approval that --require-approval never removes onto the pull request.

for a principal

Own the review contract for infrastructure change: what evidence a reviewer must see before an apply, who sees it, and how the organization keeps declared state and reality converged rather than trusting a green diff.

## The comparison it actually makes There are three things one could compare: your code, the template CloudFormation recorded at the last successful deployment, and the live configuration of the resources themselves. `cdk diff` compares the **first two**. It synthesizes your app locally, fetches the deployed stack's template from CloudFormation, and diffs them. Holding that sentence firmly is what separates a good answer from a vague one, because every strength and every blind spot follows from it. ## Reading the output The output has more structure than a raw text diff: - **Resources** — a tree of additions, removals and modifications, with modified properties listed individually. Modifications that CloudFormation would implement by creating a new resource and deleting the old one are annotated as requiring replacement, which is the line to read carefully when the resource holds data. - **IAM statement changes** — a table of policy statements being added or removed, including statements generated for you by higher-level constructs. A one-line code change can quietly widen a role's permissions, and this table is where you catch it. - **Security group changes** — ingress and egress rule changes, called out separately for the same reason. Because a high-level construct can expand into a dozen resources, diff is often the first place you find out what a convenient one-liner actually does. ## Change sets under the hood Whether a property change causes an update or a replacement is CloudFormation's decision, not something the CDK can always infer from the template alone. Recent CDK CLI versions therefore create a change set for the diff, read the resulting replacement information, and delete it. That makes the replacement warnings trustworthy at the cost of requiring change-set permissions and a little time; `cdk diff --no-change-set` falls back to a purely local comparison. ## Where it fits in the workflow The normal loop is `cdk diff` to review, then `cdk deploy`. Deploy also protects you at the moment of truth: by default it prompts for confirmation when a change **broadens** IAM permissions or security-group rules. That behaviour is controlled by `--require-approval`, whose values are `never`, `any-change` and `broadening`. A non-interactive pipeline must pass `--require-approval never`, and the honest consequence is that the review has to move somewhere a human actually sees it — typically a `cdk diff` posted on the pull request. In CI, `cdk diff --fail` gives you an exit code you can gate on: useful for a job that asserts a deployed environment still matches the committed code, or for turning "there are pending changes" into a build signal. ## The blind spots **Drift is invisible.** If an engineer edits a bucket setting in the console, CloudFormation's stored template is untouched, your synthesized template is untouched, and diff reports no changes — while reality differs from both. Detecting that requires CloudFormation's drift detection, and the fix is usually to redeploy so the declared state wins. **Deploy-time values do not resolve.** Anything CloudFormation only knows while deploying — a generated name, the ARN of a resource being created — appears as a reference, so a diff can look large while being semantically trivial, or the reverse. **It is per stack.** Diffing one stack tells you nothing about the stacks consuming its exported values; a change that alters an export can look fine locally and break a consumer. Diff every stack you are about to deploy, not just the one you edited. **Nothing outside CloudFormation is covered.** Resources created by custom resources or by scripts, and data inside resources, are out of scope entirely. **A first deploy shows everything as new**, which is correct but unhelpful for review — and worth expecting rather than being alarmed by when a stack has been renamed, because a renamed stack is a new stack. ## What a strong candidate adds The judgment layer is that a clean `cdk diff` proves your code matches what CloudFormation was last told, not that production looks the way you think. Teams that rely on diff alone eventually meet a resource somebody fixed by hand at 3am; teams that pair diff with periodic drift detection and a redeploy-to-converge habit do not.

  • Someone changes a setting in the AWS console on a resource your stack manages. What does cdk diff show, and how do you fix the situation?
    It shows nothing. CloudFormation's stored template is unchanged and so is your synthesized one, so the two still match. You find it with CloudFormation drift detection, and you correct it by deploying again so the declared configuration overwrites the manual edit — or, if the manual change was right, by putting it into the code first.
  • How would you wire cdk diff into a pull-request pipeline?
    Synthesize and run `cdk diff` for every stack the change touches, post the output as a PR comment so the IAM and security-group tables get human review, and deploy on merge with `--require-approval never` since nobody is at a terminal. `--fail` is useful for a separate job that asserts a deployed environment still matches the committed code.
  • What does the --require-approval flag on cdk deploy control?
    Whether the CLI pauses for confirmation before applying a change, based on how sensitive it is: `never` applies everything, `any-change` prompts on any difference, and `broadening` prompts when a change widens IAM permissions or security-group rules. It is an interactive safety net, so pipelines set it to `never` and move the equivalent review to the diff on the pull request.

saying these in an interview costs you the question

  • Thinks cdk diff inspects the live configuration of each resource
  • Believes it detects console changes made outside CloudFormation
  • Assumes a clean diff proves production matches the code
  • Treats replacement warnings as merely cosmetic
  • Expects diff to cover consumer stacks of a changed export

context