Declarative infrastructure, state, and the ways it goes wrong.
12 items at advanced level · all topics
Three S3 buckets are created from a list variable using count and its index. A developer removes the first element from the list. The plan now shows the two surviving buckets being destroyed and recreated as well. Which change prevents this class of problem?
count addresses instances by position, so removing an element shifts every later index and Terraform sees a different resource at each address. for_each keys instances by a stable string instead.
A team wants two guarantees. An apply must fail outright if an AMI passed into a module is not owned by an approved account. Separately, they want a health endpoint to be reported as a warning after every apply without ever blocking the run. Which custom conditions fit?
Preconditions and postconditions stop the operation when they fail. A check block reports a warning and lets the run continue, which is the only one of the three that is non-blocking by design.
A security group resource needs one ingress block per entry in a list of port and CIDR pairs, where the number of entries is not known until the variable is supplied. The ingress block is a nested block of the resource, not an argument. Which language feature produces them?
Repeating a nested block from a collection is what dynamic blocks are for. count and for_each repeat whole resources, and neither can produce several nested blocks inside one resource.
A root module declares a default aws provider and a second one with alias = "dr" for the recovery region. A child module needs to create resources in both regions. What does the child module receive by default, and what has to be done explicitly?
Default provider configurations are inherited by child modules automatically. Aliased ones never are, so the child declares a configuration alias and the caller passes it through the providers argument.
A team configures the S3 backend for a new project and wants state locking without provisioning extra infrastructure to support it. Which approach matches the current guidance for the S3 backend?
The S3 backend can lock using a lock file held in the bucket itself, enabled with use_lockfile. The DynamoDB table that used to be required is deprecated and slated for removal.
An engineer changed an instance's tags directly in the cloud console. The team wants Terraform's state to accept those tags as the new reality, without changing any infrastructure and without editing the configuration to match. Which command does this, and what should they expect?
terraform apply -refresh-only shows the drift it found and asks before recording it in state. A normal apply would do the opposite and revert the console change.
A project has been using the default local backend and has real infrastructure recorded in terraform.tfstate. The team adds an S3 backend block. They run terraform init and want the existing state copied into the new backend. Which option does that?
Changing the backend makes Terraform ask whether to copy the existing state across. -migrate-state answers yes non-interactively, while -reconfigure is the opposite answer and abandons it.
A production database was created by hand two years ago and now has to be managed by Terraform. Nobody wants to write its resource block from scratch, and the change must be reviewable before anything is written to state. Which approach fits?
Write an import block naming the resource address and the real object's id, run plan with -generate-config-out to have Terraform write the resource block, then review and apply.
A module author renames a resource from aws_instance.app to aws_instance.web. Callers who upgrade should not see their running instance destroyed and recreated, and should not have to run any CLI commands by hand. What should the author add to the module?
A moved block records the rename in configuration. Terraform renames the object in state during planning, so callers get the rename automatically with no destroy and recreate.
A storage bucket currently managed by Terraform is being handed to another team who will manage it with their own tooling. Terraform must stop managing it, the bucket and its data must survive, and the change must be visible in a plan before it takes effect. What should be done?
Replace the resource block with a removed block whose nested lifecycle sets destroy = false. Terraform drops it from state on apply and leaves the real bucket alone.
An organisation wants runs triggered and recorded centrally in HCP Terraform, with policy checks applied, but Terraform itself must execute inside their private network because the target systems have no public endpoints. Which workspace execution mode fits?
Agent mode runs Terraform on a lightweight agent the organisation hosts inside its own network, while HCP Terraform still orchestrates the run. Remote mode runs on HCP Terraform's own machines, which cannot reach private endpoints.
An organisation adds a policy in HCP Terraform requiring that every resource carries a cost-centre tag. Runs that violate it should be stopped, but a platform team member with the right permission needs to be able to let an exceptional run proceed. Which enforcement level fits, and when is the policy evaluated?
Soft-mandatory stops a run but allows an override by users with permission. Policies are checked against the plan, so they run after the plan and before the apply.