Declarative infrastructure, state, and the ways it goes wrong.
32 items at intermediate level · all topics
An organisation already runs a configuration management tool that installs packages and manages files on long-lived virtual machines. They are introducing Terraform alongside it. Which division of responsibility matches the design intent of the two tools?
Terraform provisions and owns the lifecycle of the infrastructure. A configuration management tool configures what runs inside it. The exam checks that you do not reach for provisioners to blur the line.
Changing an EC2 instance's tags updates it in place, but changing its AMI produces a plan showing the instance destroyed and recreated. What decides which of the two happens?
The provider's schema marks which arguments force a new resource. Terraform updates in place where the API supports it, and plans a replacement where the argument cannot be changed on a live object.
A team needs the DigitalOcean provider, published in the public registry as digitalocean/digitalocean. They add resource blocks using the digitalocean_droplet type and a provider "digitalocean" block, but no required_providers entry. terraform init fails, reporting that it could not find the provider in the registry. What is the cause?
With no source address to go on, Terraform fills in the hashicorp namespace and looks for a provider that was never published there. Any provider outside that namespace has to name its source in required_providers.
A single root module has to create an S3 bucket in us-east-1 and a replica bucket in eu-west-1 during the same apply. How should the two AWS provider configurations be set up?
Two configurations of the same provider need an alias, and resources opt in to the non-default one with the provider meta-argument. Terraform never picks a provider by matching arguments on the resource.
A team notices a .terraform.lock.hcl file appear after their first terraform init and is deciding how to treat it. Which TWO statements about the dependency lock file are correct?
The lock file records which provider versions Terraform chose and the checksums it will verify later. It belongs in version control, and it covers providers only, never remote modules.
A module declares the AWS provider with version = "~> 4.16". Provider releases 4.16.0, 4.17.2, 4.40.0 and 5.0.0 are all available in the registry. Which version does terraform init select?
The pessimistic operator lets only the rightmost component in the constraint move. Written with two components, ~> 4.16 allows any 4.x at or above 4.16 and stops before 5.0.
A module sets required_version = ">= 1.5.0" in its terraform block and version = "~> 5.0" in required_providers for aws. Which does each constrain?
required_version constrains the version of the Terraform CLI itself. The version argument inside required_providers constrains the provider plugin, and the two are checked at different moments.
A CI pipeline should reject a pull request that references an attribute that does not exist on a resource type, without contacting any cloud API and without needing credentials. Which command fits, and what does it require?
terraform validate catches configuration that is syntactically invalid or internally inconsistent, with no calls to remote services. It still needs an initialized directory, which init -backend=false can provide.
A plan prints a line reading -/+ resource "aws_db_instance" "main" and a comment saying forces replacement beside one argument. What is Terraform going to do?
The symbols are + create, - destroy, ~ update in place and -/+ destroy then recreate. A forces replacement comment names the argument that cannot be changed on the existing object.
A release process requires that the exact set of changes a reviewer approved is what gets applied, with no possibility of the configuration or infrastructure shifting between review and apply. Which approach meets this?
Save the plan to a file with terraform plan -out, then pass that file to terraform apply. Terraform applies the saved plan without prompting and without recomputing it.
Which TWO of the following Terraform commands read the current status of the real resources and update the state accordingly, without any additional flags or arguments being supplied?
Refreshing is part of building a plan, so the two commands that build one are the two that refresh. The state inspection and output commands read the state file as it stands and never contact a provider.
An apply is failing on one broken resource and a colleague suggests routinely using -target to apply the rest. What does HashiCorp say about that flag, and why?
-target is documented for exceptional recovery situations, not routine use. It applies part of the graph, so the resulting state can be inconsistent with the configuration as a whole.
A variable named instance_count has a default of 2 in its variable block. A terraform.tfvars file sets it to 4. The environment variable TF_VAR_instance_count is set to 6. The run is started with terraform apply -var="instance_count=8". Which value does Terraform use?
Command line flags win. The documented order runs from the variable default, through environment variables and tfvars files, to -var and -var-file, with the last of those taking precedence over everything before it.
An input variable for an environment name must only ever be dev, staging or prod, and a wrong value should fail immediately with a clear message. Which feature does this?
A validation block inside the variable declaration checks the value with a condition and reports error_message when it fails. It runs before planning, so a bad value never reaches a provider.
An EC2 instance resource references an aws_security_group id in its arguments. A separate IAM policy resource must also exist before the instance is created, but nothing in the instance's arguments refers to it. How should the configuration express each ordering requirement?
A reference between resources creates the dependency automatically. depends_on exists for the ordering that is real but invisible, where no attribute of one resource appears in the other.
A database password is passed in as a variable marked sensitive = true and used to set an RDS instance's master password. A security reviewer asks where that password can be read after an apply. Which statement is accurate?
sensitive = true redacts CLI output. It does nothing to the state file, where the value is still stored in plain text, so the protection that matters is on the backend holding that state.
A module block sources a module from a Git repository over SSH and also sets version = "~> 2.0". terraform init reports that the version argument is not valid for this source. Why, and how should the version be pinned instead?
The version argument works only for modules that come from a registry. Every other source pins itself through its own addressing, which for Git means a ref argument naming a tag.
A child module declares variable "instance_type" with no default. The caller's module block omits it. What happens, and how should the caller supply the value?
A variable with no default is required, so Terraform errors out naming the missing argument. The caller sets it as an argument inside the module block, alongside source.
A root module calls a child module that creates a VPC. The root module needs the VPC id to attach a subnet. The child module's aws_vpc resource exists and applies successfully, but referring to it from the root module produces an error. What is required?
A child module's resources are not visible to its caller. The child has to declare an output, and the caller reads it as module.NAME.OUTPUT.
One module creates a complete network stack. Three of them are needed, one per region, from a single configuration. Which approach avoids writing three near-identical module blocks?
count and for_each work on module blocks as well as resources. Using for_each over a map keyed by region gives one instance per key, addressed as module.network["eu-west-1"].
Four engineers share a configuration whose state file is committed to the Git repository. They regularly hit merge conflicts in terraform.tfstate, and two of them once applied at the same time and corrupted it. Which TWO benefits does moving to a supported remote backend give them?
A remote backend gives one shared copy of state that everyone reads and writes, and on the backends that support it, locking that stops two applies colliding.
A networking configuration exports a VPC id as an output. An application configuration in a different state needs that id at plan time. Which mechanism reads it?
The terraform_remote_state data source reads another configuration's root module outputs from its backend. Only outputs are exposed, so the producing configuration has to declare one.
An apply is interrupted when a CI runner is terminated mid-run. Subsequent runs fail immediately, reporting that the state is locked and showing a lock ID. The team has confirmed no other operation is running. What is the correct action?
A lock left behind by a killed process is exactly what terraform force-unlock is for. It takes the lock ID from the error message, and it is safe only once you are certain nothing is still running.
True or false: every Terraform backend supports state locking, so choosing any remote backend is enough to prevent two people applying at the same time.
False. Locking is per backend, and the documentation for each one states whether it supports locking. Remote storage on its own does not make concurrent applies safe.
An engineer is unsure whether a for expression over a map produces the shape they expect, and wants to try it against real state without running a plan. Which tool does that?
terraform console opens an interactive shell for evaluating expressions against the current configuration and state. It is read-only, so it changes nothing while you experiment.
A provider is failing with an unhelpful error and HashiCorp support has asked for detailed logs of the API calls, saved to a file. Which environment variables produce this?
TF_LOG sets the verbosity, with TRACE the most verbose level. TF_LOG_PATH appends the output to a file, and it does nothing unless TF_LOG is also set.
A virtual machine has been left in a broken state by a failed in-guest configuration step. Terraform reports no changes, because every argument still matches the configuration. The engineer wants Terraform to destroy and recreate that one instance, and wants to see the plan before it happens. What is the current recommended approach?
terraform apply -replace with the resource address forces one object to be replaced, and the plan is shown first. It is the documented replacement for terraform taint.
True or false: terraform state rm deletes the real infrastructure object as well as removing its record from the state file.
False. state rm only forgets the object. The real resource keeps running, unmanaged, which is useful when handing it over and dangerous when done by mistake.
A team uses terraform workspace new to keep dev and prod state separate in one working directory. They are moving to HCP Terraform and assume its workspaces are the same feature under a different name. Which statement corrects them?
CLI workspaces are alternate state files inside one working directory. HCP Terraform workspaces are the organising unit itself, holding configuration, state, variables, credentials and run history, and they carry access control.
A workspace in HCP Terraform is connected to a Git repository. A developer opens a pull request changing the configuration. What does HCP Terraform do, and what has to happen for the change to be applied?
A pull request triggers a speculative plan, which reports what would change without being applyable. Merging to the tracked branch queues a real run that can then be applied.
A platform team maintains approved modules for networking and databases. Application teams should discover and consume them with version constraints, without being given access to the underlying Git repositories. Which HCP Terraform capability fits?
The private registry publishes an organisation's own modules with documented versions, so consumers use a registry source and a version constraint instead of a repository URL.
An organisation in HCP Terraform has grown to over a hundred workspaces. They want to grant one business unit's engineers access to all of their own workspaces at once, without adding each team to every workspace individually. Which capability does this?
Projects group workspaces so permissions can be granted to the collection rather than to each workspace. Variable sets solve the neighbouring problem of sharing values, not access.