Skip to content

002 · Domain 5: Terraform Security and Governance · 13% of the exam

Task 5.5: Identify and mitigate risky infrastructure changes

Spotting a dangerous plan and stopping it: replace and destroy markers, prevent_destroy, create_before_destroy, ignore_changes, sensitive values in plans, and preconditions that block bad inputs.

Study it

  • Risky plans: replacements, destroys and the lifecycle rules that stop them

    Lesson coming

Sample questions

Try each one before opening the answer. Every option is explained, with the HashiCorp documentation page that proves it.

Question 1 · choose 1

To avoid an outage when a load balancer target group is replaced, the team adds lifecycle { create_before_destroy = true }. The next change that forces replacement fails because a target group with that name already exists. The name is set with name = "app-tg". What should the team do?

  1. AAdd create_before_destroy to every resource the target group depends on as well
  2. BUse the resource's name-prefix option instead of a fixed name to let old and new coexist
  3. CSet prevent_destroy on the target group to keep the old object until the new one works
  4. DRun terraform state rm on the old target group first to let a replacement with the same name be created
Show the answer and why
  • AAdd create_before_destroy to every resource the target group depends on as well

    Incorrect

    The failure is the name that both target groups need at the same time; changing other resources' lifecycle settings does not free it.

  • BUse the resource's name-prefix option instead of a fixed name to let old and new coexist

    Correct

    With create_before_destroy both objects exist at once, so names that must be unique need an option that adds a unique suffix.

  • CSet prevent_destroy on the target group to keep the old object until the new one works

    Incorrect

    prevent_destroy makes Terraform reject any plan that destroys the object, so the replacement could never complete.

  • DRun terraform state rm on the old target group first to let a replacement with the same name be created

    Incorrect

    state rm only forgets the old object; it still exists with the same name, so creating the new one still conflicts and the old one is left unmanaged.

create_before_destroy is opt-in because many objects have unique-name constraints. Before enabling it, make sure two copies can exist at once, for example with a generated suffix.

Question 2 · choose 1

A refactor changes aws_instance.app from count = 3 to for_each over the keys "blue", "green" and "canary". The plan shows 3 to add and 3 to destroy. Which change lets the existing servers keep running under their new keys?

  1. ARun terraform apply -refresh-only to record the new keys in state before the normal apply
  2. BAdd lifecycle { ignore_changes = all } to the resource during the switch
  3. CAdd lifecycle { prevent_destroy = true } to make Terraform keep the old instances
  4. DAdd moved blocks from aws_instance.app[0], [1] and [2] to the matching keys
Show the answer and why
  • ARun terraform apply -refresh-only to record the new keys in state before the normal apply

    Incorrect

    Refresh-only mode updates attribute values from real objects; it does not move instances to new addresses.

  • BAdd lifecycle { ignore_changes = all } to the resource during the switch

    Incorrect

    ignore_changes only suppresses updates to arguments; it has no effect on instances whose address changes.

  • CAdd lifecycle { prevent_destroy = true } to make Terraform keep the old instances

    Incorrect

    prevent_destroy makes the plan fail; it does not map old instances to new keys.

  • DAdd moved blocks from aws_instance.app[0], [1] and [2] to the matching keys

    Correct

    moved blocks with instance keys tell Terraform which old index becomes which new key, so it renames instead of replacing.

Read the plan's add and destroy counts as a warning sign after any refactor. moved blocks record address changes, including index-to-key changes between count and for_each.

Question 3 · choose 1

A risk check reads the plan JSON and must report which attributes force each replacement. Which field does it read?

  1. Areplace_paths on the resource change
  2. Brelevant_attributes at the plan's top level
  3. Cafter_unknown on the change
  4. Dprior_state for the resource
Show the answer and why
  • Areplace_paths on the resource change

    Correct

    replace_paths is an array of paths into the object value that resulted in the replace action.

  • Brelevant_attributes at the plan's top level

    Incorrect

    That relates drift to the plan, not to replacements.

  • Cafter_unknown on the change

    Incorrect

    That marks values known only after apply.

  • Dprior_state for the resource

    Incorrect

    Prior state holds old values, not causes.

Combine replace_paths with action_reason to explain each replacement to reviewers.

Question 4 · choose 1

In a plan JSON, a database shows action_reason = "replace_because_cannot_update". What does that mean?

  1. ASomeone passed -replace for this object
  2. BA requested change is impossible without replacement
  3. CThe object was tainted
  4. DThe object has no configuration
Show the answer and why
  • ASomeone passed -replace for this object

    Incorrect

    That is replace_by_request.

  • BA requested change is impossible without replacement

    Correct

    The provider indicated one of the requested changes is not possible without replacing the existing object.

  • CThe object was tainted

    Incorrect

    That is replace_because_tainted.

  • DThe object has no configuration

    Incorrect

    That is delete_because_no_resource_config.

Treat this reason on stateful resources as a signal to review before approving.

Question 5 · choose 1

A postcondition checks an instance's root volume ID, which the cloud assigns at launch. The plan succeeds. When can the postcondition fail?

  1. ANever; plan already validated every condition
  2. BOnly on the next run's refresh
  3. CDuring init, when providers load
  4. DIn the apply phase, after launch
Show the answer and why
  • ANever; plan already validated every condition

    Incorrect

    Only conditions on known values run at plan.

  • BOnly on the next run's refresh

    Incorrect

    The check runs in the same apply.

  • CDuring init, when providers load

    Incorrect

    Conditions are not evaluated at init.

  • DIn the apply phase, after launch

    Correct

    When a value is known only after applying, Terraform delays the check to the apply phase.

Treat such conditions as guards on apply, and expect failures after some changes were already made.

Question 6 · choose 1

A mandatory post-plan run task times out because the scanning service is down. What happens to the run?

  1. AIt continues with a warning
  2. BIt waits until the service returns
  3. CIt stops and errors, as a timeout counts as a failure
  4. DIt skips the task and applies
Show the answer and why
  • AIt continues with a warning

    Incorrect

    A failed mandatory task does not let the run continue.

  • BIt waits until the service returns

    Incorrect

    A timeout counts as a failure.

  • CIt stops and errors, as a timeout counts as a failure

    Correct

    A failed mandatory task, including a timeout or unexpected remote error, stops the run with an error.

  • DIt skips the task and applies

    Incorrect

    Mandatory tasks can block runs.

Make a task mandatory only when its service must be reachable for every run, since an outage then stops runs.

Practice domain 5 →Practice all domains →