skip to content

In AWS CloudFormation, what is a change set, and which part of the described change set tells you a resource will be destroyed and recreated rather than updated in place?

level: middleimportance: must knowfreq 68%

answer

  1. preview stored, not applied
  2. three separate API calls
  3. action plus one decisive field
  4. True means a new physical ID
  5. execute is its own call

basics

~20 s

A change set is a stored, named preview of what an AWS CloudFormation stack update would do, computed without applying anything. Its Replacement field is the thing to read: True means the resource is deleted and recreated with a new physical ID.

solid answer

~50 s

`update-stack` compares my template against the template CloudFormation has recorded for the stack and starts making changes immediately. A change set splits those halves: `CreateChangeSet` computes the diff and stores it as an object attached to the stack, `DescribeChangeSet` shows it, and nothing happens until `ExecuteChangeSet`. Each entry carries an `Action` — Add, Modify, Remove, Import or Dynamic — and the field I actually look for, `Replacement`. True means CloudFormation creates a new physical resource and deletes the old one, so its identifier changes and anything stored on it is gone. `Conditional` means it depends on values only resolved at execution, and I treat that as True. Two limits matter: it is a template-to-template diff, so it does not check live resources, and it does not prove the update will succeed — IAM denials and quota errors still surface at execute time.

code

bash · 20 lines
bash
aws cloudformation create-change-set \
  --stack-name payments-prod \
  --change-set-name bump-instance-class \
  --template-body file://template.yaml \
  --capabilities CAPABILITY_IAM \
  --include-nested-stacks

aws cloudformation wait change-set-create-complete \
  --stack-name payments-prod \
  --change-set-name bump-instance-class

aws cloudformation describe-change-set \
  --stack-name payments-prod \
  --change-set-name bump-instance-class \
  --query 'Changes[].ResourceChange.{Id:LogicalResourceId,Action:Action,Replace:Replacement}' \
  --output table

aws cloudformation execute-change-set \
  --stack-name payments-prod \
  --change-set-name bump-instance-class

go deeper

for a junior

Know that CloudFormation can show you the diff before it acts, and that creating a change set changes nothing until you explicitly execute it. Name the three steps: create, describe, execute.

for a middle

Be ready to walk the described output: the Action values, the Replacement field, and what Conditional means. Explain concretely why a replacement is dangerous — new physical ID, old resource deleted, state gone.

for a senior

Show where the preview is placed in a pipeline and what you block on. Say plainly what it does not catch: IAM denials at execute time, service quotas, and a diff that has gone stale because the stack moved underneath it.

for a principal

Own the policy question: which stacks require a reviewed change set, who is allowed to execute one, and how you make a replacement on a stateful resource impossible to approve by accident rather than merely visible in a diff.

## The problem a change set solves When you call `aws cloudformation update-stack`, CloudFormation compares the template and parameters you submitted against the template and parameters it has recorded for that stack, works out the set of resource changes, and immediately begins performing them. There is no gap between deciding and doing. On a production stack that is uncomfortable, because a one-line property edit can quietly mean "delete the database and build a new one". A change set splits that single operation into two. `CreateChangeSet` performs exactly the same comparison but writes the result down as a named, addressable object attached to the stack instead of acting on it. Nothing in the account changes. `DescribeChangeSet` returns it for review, `ExecuteChangeSet` applies it, and `DeleteChangeSet` throws it away. A stack can hold several change sets at once, each a competing proposal. A change set can also create a brand-new stack: with `--change-set-type CREATE`, CloudFormation registers the stack in status `REVIEW_IN_PROGRESS` with no resources in it, and the resources come into existence only when you execute. ## What is inside one `DescribeChangeSet` returns a `Changes` array of `ResourceChange` entries. The fields worth knowing: - **`Action`** — `Add`, `Modify`, `Remove`, `Import`, or `Dynamic`. - **`LogicalResourceId` / `PhysicalResourceId` / `ResourceType`** — which resource, and the real-world object behind it today. - **`Replacement`** — `True`, `False`, or `Conditional`. This is the one that decides whether the change is safe. - **`Scope`** — which parts of the resource definition changed: `Properties`, `Tags`, `Metadata`, `CreationPolicy`, `UpdatePolicy`, `DeletionPolicy`, `UpdateReplacePolicy`. - **`Details`** — per-change breakdown, each with a `Target` naming the attribute and its `RequiresRecreation` (`Never`, `Conditionally`, `Always`), an `Evaluation` of `Static` or `Dynamic`, and a `ChangeSource` explaining why (a direct edit, a parameter reference, another resource's attribute). `Replacement: True` means CloudFormation cannot mutate the existing resource into the requested shape, so it will create a replacement and then delete the original. The physical identifier changes — a new DB endpoint, a new bucket, a new ENI — anything downstream that pinned the old identifier breaks, and any state living on the old resource is destroyed unless a policy saves it. `Replacement: Conditional` means the outcome depends on values CloudFormation cannot resolve before execution. The professional reading of `Conditional` is "assume True". `Evaluation: Dynamic` (and an `Action` of `Dynamic`) is the same family of uncertainty: the new value of a property is derived from something not yet known — another resource's runtime attribute, for instance — so the preview lists the change without being able to show the value. Expect more to change than the preview names. ## What a change set does not tell you Three gaps get candidates in trouble: 1. **It is not a validation that the update will succeed.** The diff is computed from the templates. Whether the IAM role executing the stack may create that resource, whether you are at a service quota, whether the value is acceptable to the service — all of that surfaces during execution, and a failure there sends the stack into rollback. 2. **It is not a comparison against reality.** The comparison is template-to-template. If somebody edited a stack-managed resource by hand, the change set does not know; noticing that is a separate CloudFormation operation, not part of this one. 3. **It goes stale.** The diff is computed against the stack as it was at create time. If the stack is updated in the meantime, the preview no longer describes what will happen — regenerate it rather than executing an old one. One more practical trap: by default the preview stops at an `AWS::CloudFormation::Stack` resource and reports the nested stack as a `Modify` without expanding it. Pass `IncludeNestedStacks` (`--include-nested-stacks` on the CLI) to get resource-level changes for the children in the same preview. ## Where it sits in a pipeline The change set is the natural approval gate. `aws cloudformation deploy` creates and executes a change set for you in one step; adding `--no-execute-changeset` makes it stop after creating, print the change set ARN, and exit — so a pull-request job can create the change set and post the described output as a comment, and a merge job executes it. That gives a human the one piece of information worth blocking on: which resources say `Replacement: True`. ```bash aws cloudformation describe-change-set \ --stack-name payments-prod --change-set-name pr-482 \ --query 'Changes[?ResourceChange.Replacement!=`False`]' ``` An empty result is the boring, safe update. A non-empty one is the conversation you want to have before, not after.

  • What does an entry with an Action or Evaluation of Dynamic tell you?
    That CloudFormation could not work the change out statically — the property depends on a value resolved only at execution, such as another resource's runtime attribute. The entry is a warning that more may change than the preview lists. Read it as "unknown until executed" and review it with the same suspicion as a replacement.
  • You create a change set on a parent stack and it lists no changes for resources defined in its nested stacks. Why?
    By default the preview stops at the `AWS::CloudFormation::Stack` resource and reports the child as a plain Modify. Pass `IncludeNestedStacks` — `--include-nested-stacks` on `create-change-set` — and CloudFormation expands the children so their resource-level changes, including replacements, appear in the same describe output.
  • What happens if you create a change set for a stack name that does not exist yet?
    With `--change-set-type CREATE`, CloudFormation registers the stack in `REVIEW_IN_PROGRESS` and provisions nothing. Executing the change set creates the resources. If you delete the change set instead, the empty stack record stays behind in `REVIEW_IN_PROGRESS` and you have to delete the stack itself to release the name.

A change set is the estimate a builder writes up before touching anything: it lists which walls get repainted and which get knocked down and rebuilt. Reading it is the whole point of asking for one.

saying these in an interview costs you the question

  • Says a change set proves the update will succeed
  • Thinks a change set checks live resources, not templates
  • Ignores Replacement and assumes every update is in place
  • Treats Conditional replacement as safe
  • Believes describing a change set applies it

context