Terraform interview questions show up in nearly every DevOps, platform, and cloud engineering loop, because HashiCorp Terraform remains the default answer to how infrastructure gets provisioned and kept honest. This page is a complete, tiered bank: 104 questions with worked answers, split into beginner, intermediate, and scenario sections, plus hands-on labs, a command cheat sheet, and a knowledge check at the end. Work through it in order, or jump straight to the tier your next round will actually test.

TL;DR
- 104 questions, three tiers. Beginner vocabulary, intermediate mechanics like state and locking, and realistic scenario rounds on drift, failed applies, and refactors, each answered the way interviewers want it said.
- State is the theme underneath everything. The strongest answers in any set of Terraform interview questions pair a command with the mechanism behind it: what the plan diff reads, what the state file owns, what the backend protects.
- Practice is built in. Three scenario labs, a cheat sheet of the commands that decide rounds, and a five-question quiz to check what stuck.
How the Terraform interview works in 2026
Most Terraform interview questions arrive in one of three rounds. The first is a screening call, often with the hiring manager, mixing quick definitions with one or two judgment checks: what the state file is for, what terraform plan actually promises, why you would never commit secrets into a variable default. These are confidence filters. Nobody expects a lecture; they expect a crisp 30-second answer with one level of detail held in reserve.
The second round is the deep technical. This is where Terraform interview questions get mechanical: state backends and locking, workspaces, module contracts, provider resolution, the difference between count and for_each, what a refresh does, what a moved block does. Interviewers at this stage are listening for whether your knowledge has edges. Saying “plan shows what will change” passes a beginner bar; explaining that the diff is computed against refreshed state plus known-after-apply values, and why that makes branching logic in code impossible, passes a working-engineer bar. Terraform interview questions are graded on that second sentence, not the first.
The third round is the scenario round, and it is the one candidates fail most. You get one symptom sentence: “someone edited the security group in the console,” “apply died halfway through,” “CI says it needs to destroy the database.” What is scored is your diagnostic order. Engineers who say “first I stop everyone, then I run plan to see what Terraform believes, then I decide adopt versus revert” outperform engineers who reach for state rm and hope. Nearly all scenario Terraform interview questions reward the narration as much as the answer.
Role shape changes the emphasis. General DevOps roles weight Terraform interview questions toward the daily workflow: modules, variables, CI/CD integration, code review of plans. Platform roles push harder on state design at organization scale: blast radius, workspace versus directory-per-environment, remote state data sources between stacks, policy as code. SRE roles care about drift, guarded applies, and what happens during an incident when Terraform is the thing standing between you and a manual fix. The base bank below is the same; only the depth expectation moves.
Preparation that works is boringly mechanical. Drill the commands until they are reflexes: init, plan, apply, state list, import, force-unlock. Then rehearse the explanations out loud, each in 30 to 60 seconds, because Terraform interview questions are a speaking exam as much as a knowledge one. Pair the page with a throwaway cloud account or LocalStack, break state deliberately, and rehearse the scenario tier the way you would rehearse a demo.
Core concepts interviewers expect you to know
Two mental models unlock most Terraform interview questions: what the state file is and owns, and what happens between plan and apply. Everything else, modules, providers, workspaces, hangs off those two. If you can narrate both fluently, most follow-up questions become extensions rather than new topics, which is exactly why interviewers open Terraform interview questions here.
State: the file that makes Terraform work
Terraform is a declarative engine, but your code is only half the input. The other half is the state file: Terraform’s record of every object it manages, with real-world IDs, attribute values, and dependency metadata. A plan is a three-way comparison: your configuration, the last recorded state, and the live infrastructure discovered by refreshing. Delete the state and Terraform loses track of everything it built; that is why state loss, not code loss, is the disaster scenario, and why scenario Terraform interview questions about recovery start with backups and versioned buckets.
Because one writer at a time is the only safe rule for state, serious setups move it to a remote backend with locking, S3 with its lock object or DynamoDB lease, Azure Blob, GCS, Postgres, or a platform like HCP Terraform. The lock serializes writes so a laptop and a CI pipeline cannot apply against the same stack concurrently. Remote state is also a security topic: state stores resource attributes in plaintext, including database passwords and tokens unless you design around them, so backend access policy matters as much as code review. State design anchors more intermediate Terraform interview questions than any other single topic, from locking mechanics to how you split one giant state into stacks with small blast radius.
The plan and apply lifecycle
The second model is the loop every command sits inside. terraform init downloads providers and modules and writes the lock file. A plan refreshes live infrastructure, diffs it against configuration plus state, and prints the proposed changes with symbols: + create, ~ update in place, - destroy, -/+ destroy and recreate. terraform apply walks the same graph and executes those changes in dependency order, writing state incrementally as each object lands. Saving the plan to a file with -out and applying exactly that file is how CI guarantees the reviewed diff is the executed diff, which is a favorite detail in workflow-focused Terraform interview questions.
The subtlety worth rehearsing: values that Terraform cannot know until an object exists, like a load balancer’s DNS name, are unknown at plan time. That is why plans can be accurate and still incomplete, why a plan cannot be a guarantee, and why code cannot branch on computed values. Interviewers probe this constantly because it separates people who have run Terraform from people who have read about it.
Modules, providers, and the graph
The third model is composition. Modules are directories of configuration with a contract: typed inputs, outputs, a version. Providers are the plugins that speak each API, downloaded and pinned through required_providers and the lock file. Terraform builds a directed acyclic graph from the references between resources, modules, and data, and that graph decides creation order and parallelism, not file layout. When you can explain that ordering is derived from references and that depends_on is an escape hatch with real costs, you have covered the territory where intermediate Terraform interview questions live: for_each maps, module chaining, provider aliases, and why renaming a resource in code would otherwise be a destroy and recreate until a moved block says otherwise.
Question bank at a glance
The bank below is organized the way Terraform interview questions are actually asked: broadly increasing difficulty, then the scenario round that finishes most loops. Counts are exact, so you can pace a week of prep: roughly 15 beginner questions a day gets you through the bank in a working week, with the labs on the weekend.
| Section | Questions | What it proves |
|---|---|---|
| Beginner | 38 | You use Terraform daily and know the vocabulary cold. |
| Intermediate | 40 | You understand mechanisms: state, locking, modules, the graph, imports. |
| Scenario and troubleshooting | 26 | You can diagnose broken state, drift, and failed applies in a defensible order. |
Difficulty inside each tier still rises as you go, so if a section starts feeling easy near its end, that is the signal to move on. Every answer pairs the command with the mechanism, because Terraform interview questions are graded on both halves: the right tool, and the reason that tool applies.
Beginner Terraform interview questions
These 38 are the warm-up tier of Terraform interview questions. They look easy, and that is the trap: interviewers use them to check precision. Answer each in one or two sentences, then add exactly one supporting detail. Say more and you burn round time; say less and you sound like you memorized a list.
What is Terraform, and what problem does it solve?
Answer: Terraform is an infrastructure as code tool: you declare infrastructure in files, and it creates, updates, and deletes real resources to match. The problem it solves is manual drift and tribal knowledge, since console-clicked infrastructure cannot be reviewed, reproduced, or rolled back. That pairing of declaration plus an execution engine is the opening nearly all Terraform interview questions expect, because everything else on the page builds on it.
What does “declarative” mean compared to scripting infrastructure?
Answer: A script lists steps to run, in order, once; a Terraform configuration describes the desired end state, and Terraform computes the steps needed to get there. Run it twice and the second run does nothing, because reality already matches. That convergence is called idempotency, and it is why declarative code survives team review while a snowflake script does not.
What is HCL?
Answer: HashiCorp Configuration Language, the declarative syntax Terraform files use: blocks with type labels and braces, arguments as key = value, and expressions for computed values. It is JSON-compatible in spirit but designed for humans. Knowing the name matters less than knowing blocks, arguments, and attributes are the three things you are always reading.
What is a provider?
Answer: A provider is the plugin that teaches Terraform to speak one API: AWS, Azure, GCP, Kubernetes, Cloudflare, hundreds more. Terraform itself manages none of your infrastructure directly; every resource type belongs to a provider. That separation of engine from plugins is the mechanism behind many follow-up Terraform interview questions, because version pinning, lock files, and upgrade risk all live at this layer.
Where do providers come from, and how do you pin one?
Answer: From the public registry by default, declared in a required_providers block with a source address like hashicorp/aws and a version constraint such as ~> 5.0. terraform init downloads the newest allowed version and records the exact selection in the lock file. Unpinned providers are how a Tuesday init becomes an incident, which is why pinning discipline shows up early in Terraform interview questions.
What is a resource?
Answer: A resource block declares one infrastructure object you want to exist: resource "aws_instance" "web" is type plus local name. The block is the source of truth; the cloud object is the outcome; the state file maps the two by real ID. Everything you review in a plan is expressed as changes to resources.
What is a data source, and how is it different from a resource?
Answer: A resource creates or changes something; a data source only reads something that already exists, like a current AMI ID, an existing VPC, or a TLS certificate. Data sources let your code reference reality without owning it. The rule of thumb worth stating: if Terraform would need to create or delete it, it is a resource; if it only needs to look it up, it is data.
What is a variable, and what are the ways to set one?
Answer: A variable is a typed input to your configuration, declared with a type and optional default. You set it in terraform.tfvars, in -var or -var-file flags, or through TF_VAR_name environment variables. Variables are how one module serves many environments without copy-pasting code, so input design comes up in practical Terraform interview questions constantly.
What are output values for?
Answer: Outputs expose selected values after an apply: instance IPs, ARNs, generated passwords handed to another system. Child module outputs are also how a parent consumes what a module created, which makes them the return values of modules. Mark them sensitive = true when the value is a secret, which hides it from CLI output without removing it from state.
What are locals, and how do they differ from variables?
Answer: Locals are named expressions computed inside the configuration, like a concatenated name prefix or a merged tag map. Variables are inputs from outside; locals are internal, derived, and assigned exactly once each. The habit interviewers like: reach for locals when the same expression would otherwise be repeated in several places, because one source of truth beats four divergent copies.
What are the steps of the core Terraform workflow?
Answer: Write configuration, terraform init to prepare providers and backend, terraform plan to preview the diff, review it with a human, then terraform apply to execute. In teams the review happens on a pull request and apply happens from automation. That loop, write, plan, review, apply, is the skeleton behind most workflow Terraform interview questions, so be able to say what each step produces.
What does terraform init do, and when must you run it again?
Answer: Init prepares the working directory: downloads the provider and module versions allowed by your constraints, configures the backend, and writes .terraform.lock.hcl. Rerun it when constraints change, when the backend changes, when you add a module, or with -upgrade to deliberately lift pinned versions. Init is safe to repeat; it is environment preparation, not an infrastructure change.
What does terraform plan show, and what does it not promise?
Answer: Plan shows the proposed diff between refreshed reality and your configuration: additions, updates, destructions, and reads. What it does not promise is a guaranteed outcome, because values that only exist after creation are unknown at plan time, and someone can change the world between plan and apply. Plans are previews with a timestamp, a distinction that appears in more advanced Terraform interview questions than candidates expect.
What do the plan symbols +, ~, -, and -/+ mean?
Answer: Plus creates, tilde updates in place, minus destroys, and minus-plus destroys and recreates the object, which appears when you change a property the API cannot modify, like an instance’s root volume size or a subnet’s availability zone. Reading -/+ as “downtime and data loss possible” is the survival instinct this symbol tests. The tilde line’s gray sub-lines show exactly which attributes change.
What does terraform apply do if you run it without a plan file?
Answer: It computes a fresh plan, shows it, and waits for interactive approval before executing. That is convenient locally and wrong for CI, because between review and execution nothing binds the diff. Production pipelines save the plan with -out in one job and apply exactly that file in the next, a separation that workflow Terraform interview questions treat as the professional default.
What is terraform destroy, and how do you guard against accidental runs?
Answer: Destroy plans the deletion of every managed object in that state and applies it. Guards, in order of usefulness: prevent_destroy lifecycle blocks on databases and buckets, separate credentials for production applies, plan review in CI, and backend access policies that make prod state unreadable from laptops. Almost every set of Terraform interview questions includes one “how would you prevent this” destroy story.
What is the state file, and what lives inside it?
Answer: The state file, terraform.tfstate locally, is Terraform’s map between configuration addresses and real-world objects: resource IDs, attribute values, dependency metadata, and a serial number that changes with every write. Plan diffs are computed against it, and outputs are read from it. Losing it means Terraform no longer knows what it owns, which is why state dominates Terraform interview questions from intermediate level up.
Why should you never hand-edit the state file?
Answer: Because its structure is internal, versioned, and unforgiving: one mistyped field corrupts the record for a resource and the next plan inventories it as destroy or recreate. Terraform gives you supported surgery tools instead, state mv, state rm, import, and the moved block, which validate what they touch. Hand editing is the answer that ends a scenario round badly, so name the supported commands rather than vim.
What are the .terraform directory and the lock file?
Answer: .terraform is a local cache: downloaded providers, modules, and backend setup, and it should be gitignored. .terraform.lock.hcl is the opposite, it is committed: it pins exact provider versions and their checksums so every teammate and CI run installs what you tested. Cache versus lock file is a small question that cleanly separates people who have onboarded a team from people who have not.
What is a module?
Answer: Any directory of Terraform configuration invoked from elsewhere; a child module with declared variables and outputs is a reusable component, like a “vpc” module that builds a whole network from a CIDR input. Modules are the unit of reuse, review, and testing in Terraform, so answers that mention a clear input-output contract tend to stand out in Terraform interview questions about scaling configuration.
What is the difference between the root module and child modules?
Answer: The root module is the directory where you actually run Terraform, the one with the backend and provider blocks; child modules are directories it calls, and they never run on their own. Child modules should stay backend-free and provider-agnostic where possible, taking everything through variables. Where configuration lives and who is allowed to apply it is decided at the root, which is the sentence the question is fishing for.
How does Terraform know what order to create things in?
Answer: From references: when a resource argument reads another resource’s attribute, like a subnet ID, Terraform builds a dependency graph and creates referenced objects first, destroys them last. File and block order in your code is irrelevant. This implicit ordering is why depends_on exists only for hidden dependencies, a distinction that intermediate Terraform interview questions push hard.
How do you build strings and files from values in HCL?
Answer: String interpolation with ${expression} inside quoted strings, like "${var.name}-web", plus heredocs for multiline text. For whole files, templatefile(path, vars) renders a template with variables, which keeps user data scripts and configs out of your resource blocks. Interpolation, heredoc, templatefile is the trio this question wants, in rising order of complexity.
What do terraform fmt and terraform validate do?
Answer: fmt rewrites configuration to canonical style, aligned equals signs, consistent indentation, and fmt -check fails in CI when anything is unformatted. validate checks syntax and internal consistency, references that resolve, required arguments present, without touching any API. Both are the cheapest gates a pipeline can run, and skipping them is the tell this question looks for.
What are provisioners, and why are they a last resort?
Answer: Provisioners, like local-exec and remote-exec, run scripts at creation or destruction time, usually over SSH. They are a documented last resort because they break the declarative model: actions happen outside the plan, failures leave resources half-configured, and SSH reachability becomes an apply prerequisite. The strong answer names the alternatives first, cloud-init, Packer images, or a config management layer, which is exactly the judgment Terraform interview questions on this topic are scoring.
What does marking a variable sensitive actually do?
Answer: It hides the value from plan, apply, and output display in the CLI, printing (sensitive value) instead. It does not encrypt anything: the value still lands in the state file in plaintext and appears in any error message that interpolates it. Sensitive is a screen, not a vault, and knowing that boundary is the entire point of this entry in Terraform interview questions.
Does Terraform encrypt state? Where do secrets end up?
Answer: State is plaintext JSON by design, because Terraform must read attribute values back to compute diffs, so database passwords, tokens, and generated keys all land inside it. Protection comes from the backend, encryption at rest, tight IAM, and access logs, plus practices like generating secrets in Vault instead of code. Security-adjacent Terraform interview questions almost always circle back to this plaintext fact, so volunteer it before being asked.
What is a backend, and which one do you get by default?
Answer: A backend determines where state is stored and how it is locked. The default is the local backend: a plain file in your working directory, no locking, no sharing, fine for a laptop experiment and wrong for a team. You configure alternatives in a terraform block, S3, Azure Blob, GCS, Postgres, or HCP Terraform, and changing backends means re-running init to migrate state.
Why do teams move state to a remote backend?
Answer: Three reasons: one shared copy so everyone plans against the same truth, locking so two applies cannot interleave, and operational safety like versioning and encryption on the storage side. A local file on one engineer’s laptop is invisible to CI and to the teammate covering on-call. Shared, locked, backed-up state is the expected three-part answer to this staple of Terraform interview questions.
What is a resource address, and how do you read one?
Answer: It is the unique name Terraform uses for an object: aws_instance.web, or module.network.aws_subnet.private[0] for something inside a counted module. Addresses matter because every state command, state list, state mv, import, and -target, speaks addresses. Reading them fluently is the difference between navigating state and guessing, which is why Terraform interview questions keep returning to this vocabulary.
What are provider aliases for?
Answer: When one configuration must talk to two configurations of the same provider, us-east and eu-west regions, or two AWS accounts, you declare provider "aws" { alias = "west" } and point resources at it with provider = aws.west. Without an alias, resources inherit the default provider. Multi-region and multi-account patterns start here, so expect a follow-up about per-environment provider blocks in Terraform interview questions for platform roles.
If a variable is set in several places, which one wins?
Answer: Precedence from lowest to highest: the default in the variable block, then terraform.tfvars, then other auto-loaded *.auto.tfvars files in name order, then any explicitly passed -var-file, then individual -var flags, with environment TF_VAR_ variables slotting alongside flags. The last source you explicitly hand Terraform wins. Precedence surprises cause real wrong-environment applies, which is why this small ordering question survives in Terraform interview questions year after year.
What is terraform console useful for?
Answer: It is a REPL that evaluates expressions against your real configuration and state: test a cidrsubnet() call, inspect var.complex_map, or check what data.aws_ami.current.id resolves to before you commit code that depends on it. It reads state, so it is free and safe, and it fails loudly on bad expressions. Reaching for the console instead of trial-and-error applies is the working habit this question rewards.
What kind of infrastructure can Terraform manage beyond public cloud?
Answer: Anything with a provider: Kubernetes manifests and Helm releases, DNS records, GitHub repositories and team memberships, Datadog monitors, Postgres databases and their roles, even localhost files with the local provider. The pattern to state: Terraform is a declarative engine, and every provider is just another API adapter. Breadth here predicts how you will answer design Terraform interview questions later in the loop.
What happened with Terraform’s license, and what is OpenTofu?
Answer: In 2023 HashiCorp moved Terraform from open source MPL to the Business Source License, restricting competitive use. The community forked the last MPL version as OpenTofu, now Linux Foundation governed, drop-in compatible and adopted by several distros and managed platforms. Expect at least one 2026-vintage licensing Terraform interview question on this, because “which binary do we standardize on” is now a real team decision with real procurement consequences.
What is HCP Terraform, and how is it different from a plain S3 backend?
Answer: HCP Terraform, renamed from Terraform Cloud, is HashiCorp’s managed platform: it stores and locks state, but also runs plans and applies in its own agents, gates them with approvals and policies, and keeps run history. S3 plus CI gives you storage and locking and nothing else. The platform-versus-DIY tradeoff, cost and control versus built-in governance, is the discussion this question is built to start.
What does required_version control, and what does the ~> constraint mean?
Answer: The required_version setting pins which Terraform binary may run this configuration, refusing init otherwise. Operators: = exact, >= floor, and ~> pessimistic, where ~> 1.9 allows any 1.x at or above 1.9 but blocks 2.0, protecting you from untested major bumps. Pinning the binary, the providers, and the modules is version discipline across all three layers, a theme that runs through Terraform interview questions at every level.
What does a validation block on a variable buy you?
Answer: It runs a condition against the incoming value at plan time and fails with your own error message, like rejecting a CIDR outside your allocation or an environment name outside an allowed list. Defaults are validated too, so bad values die before any API call. Validation turns runtime surprises into preflight failures, which is the cheapest error class to have, a framing that lands well in Terraform interview questions about module design.
Intermediate Terraform interview questions
This tier is where Terraform interview questions stop testing vocabulary and start testing mechanism. Forty questions follow, and the pattern to internalize is command, then cause: name the tool, then explain what Terraform or the backend is actually doing. That second half moves you from operator to engineer in an interviewer’s notes, and it is what the scenario tier of Terraform interview questions assumes you already have.
What does refresh actually do, and what is a refresh-only plan for?
Answer: Refresh queries every managed object’s real API state and records it into state, so the next diff compares current reality, not stale memory. Since Terraform 0.15.4 the default plan refreshes as part of the run, and plan -refresh-only isolates that step, showing only what the world changed with no proposed actions. Interviewers like this question because the answer proves you know plans read reality before diffing it, which is the foundation under every drift discussion.
Walk me through what terraform apply does internally.
Answer: Load and validate configuration, configure the backend, acquire the state lock, refresh, build the diff, present it, then on approval walk the dependency graph creating, updating, and destroying through provider APIs, writing state incrementally after each object so a crash leaves a truthful record. Finally release the lock and print outputs. Saying “state is written as it goes, not at the end” is the detail that separates this answer from the parroted version most Terraform interview questions receive.
How does remote state locking work, and what is force-unlock for?
Answer: The backend stores a lock alongside state, a lock object in S3, an item in DynamoDB for older setups, a lease row in Postgres, and refuses write operations while it is held, which is how a laptop and CI cannot apply concurrently. If a runner died mid-apply, the lock can outlive the process, and terraform force-unlock LOCK_ID releases it after you confirm nothing is genuinely running. Lock mechanics and the discipline of verifying before forcing are both being graded here.
What are workspaces really for, and what are they not for?
Answer: A workspace is a named instance of one root module’s state: same code, separate terraform.tfstate per workspace, switchable with terraform workspace select. That fits short-lived variants like per-developer or per-feature copies, and terraform.workspace can vary small values. What they are not for is production isolation, because every workspace shares one backend, one provider config, and one blast radius, and applying to the wrong one is one typo away. That boundary is what workspace Terraform interview questions exist to draw.
How do you choose between workspaces and one root module per environment?
Answer: Separate roots or separate backends per environment when isolation matters: different credentials, different state locations, different apply permissions, so prod cannot be touched by the dev pipeline. Workspaces when you want lightweight copies of identical code with shared access. The honest rule: environments differ in risk, so state isolation should differ in kind, not just in name, and explaining that risk asymmetry is what intermediate Terraform interview questions are listening for on this topic.
Why do teams split one giant state into multiple stacks?
Answer: Blast radius and workflow speed. One monolithic state means every apply diffs everything, any corruption destroys the whole map, plan times grow with resource count, and one team’s typo can destroy another team’s database. Splitting by lifecycle and ownership, network, cluster, app stacks, gives small plans, narrow credentials, independent release cadence, and clear ownership lines. Cost of splitting: cross-stack references must become remote state data sources or data lookups, and that tradeoff discussion is the real subject of these Terraform interview questions.
How does for_each work, and why is it usually safer than count?
Answer: for_each takes a map or set of strings and creates one instance per key, addressable as resource["key"]. Count creates instances addressable by list index. The safety difference is identity: remove item two from a count list and every later index shifts, so Terraform plans destroys and recreates down the chain; remove a key from a for_each map and only that instance dies. Maps bind instances to names, and names are stable. That identity argument is the core of count versus for_each Terraform interview questions.
What happens to state when you convert count to for_each?
Answer: Nothing good by default: app[0], app[1], app[2] are different addresses from app["a"], so Terraform plans three destroys plus three creates even though the real objects are identical. The fix is remapping state before applying: a moved block per instance or terraform state mv calls that rename each address, after which the plan is empty. Anyone who has done this migration answers slowly and precisely, which is why it appears in working-level Terraform interview questions.
When is depends_on legitimate, and what does it cost you?
Answer: Legitimately, when the dependency is real but invisible to the reference graph: an app depends on an access key existing inside a policy document string, or a provisioner needs a helper’s side effect. It costs you honesty: the graph edge is manual, it suppresses Terraform’s ability to order things efficiently, and it rots when the hidden coupling changes. Every legitimate use should carry a comment explaining why, and volunteering that convention is the maturity signal these Terraform interview questions hunt.
What does create_before_destroy change about an update?
Answer: Normally a replacement destroys first, then creates, which is downtime and, for volumes or load balancer targets, data loss. lifecycle { create_before_destroy = true } inverts the order: the new object provisions and passes health checks before the old one dies, enabling blue-green style replacement. The caveat worth naming: some resources cannot coexist with their replacement, name collisions, name-locked DNS records, so the flag needs per-resource judgment, which is exactly the nuance this question tests.
What does prevent_destroy guarantee, and how do you still decommission?
Answer: lifecycle { prevent_destroy = true } makes any plan that would destroy that resource fail immediately, before touching the API, which turns “oops” into a refused plan. Decommissioning is deliberate: remove the block, apply, then destroy, or state rm the object to hand it over unmanaged. It is a guardrail for databases, buckets, and KMS keys, and the two-step removal ritual is the operational detail Terraform interview questions look for here.
When is ignore_changes the right call, and what drift does it hide?
Answer: lifecycle { ignore_changes = [tags] } tells plan to stop diffing listed attributes, correct when another system owns them: a cost tool tagging aggressively, autoscalers editing desired capacity, or a platform injecting tags at apply time. What it hides: real drift on those attributes becomes invisible forever, and Terraform stops being the source of truth for them. Scope it narrowly, specific attributes not the whole resource, and say the tradeoff out loud, because that balance is what this question grades.
What makes a good module contract?
Answer: Typed variables with descriptions, defaults, and validation; outputs for exactly what callers need, IDs, names, ARNs; no hidden surprises, no providers created inside except when deliberately managed with configuration_aliases; a README with an example; and stable semantics between versions. A module is an API, and the questions that matter are the same as any API review: what do I pass, what do I get, what can change under me. Framing modules as contracts is the register strong candidates use in module Terraform interview questions.
How do you version and release a shared module safely?
Answer: Tag immutable versions, semver, source it as git::...?ref=v1.4.2 or a registry module with a pinned version, and never let callers float at main. Pre-1.0: breaking changes bump minor. Post-1.0: breaking changes bump major, features minor, fixes patch. Test the release with example configurations and terraform test, then migrate callers stack by stack while both versions coexist. A changelog and a deprecation window are what “mature” sounds like in module lifecycle Terraform interview questions.
How do you chain modules, and how does ordering follow the data?
Answer: A child module declares outputs; the parent reads them and passes them into the next module’s variables, module "app" { subnet_ids = module.network.subnet_ids }. That reference creates the graph edge automatically, so the network module finishes before app resources are planned, no depends_on required. Design rule worth stating: pass IDs through the parent rather than letting siblings reference each other, because flat sibling wiring makes the graph invisible and the refactor painful. Data-through-parents is the architecture these Terraform interview questions reward.
How does Terraform resolve provider versions, and what role does the lock file play?
Answer: Constraints in required_providers define an allowed range; init picks the newest version satisfying every constraint in the tree, including ones imposed by modules, and records the exact choice plus checksums in .terraform.lock.hcl. After that, every teammate and CI run installs the locked versions until someone runs init -upgrade. Two consequences interviewers probe: a module’s constraint can conflict with your root’s, and lock files must be committed or builds are irreproducible. Provider resolution mechanics appear in most intermediate Terraform interview questions somewhere.
How do you use one provider configured two different ways?
Answer: Declare multiple provider blocks with distinct alias values, then choose per resource with provider = aws.eu. For modules, the child declares its provider requirements with configuration_aliases = [aws.eu] and the parent passes which concrete configuration each alias means, which is how one stack builds resources in two accounts or regions deliberately. Default versus aliased providers, and the module-level indirection, are the two halves this question wants covered.
What does the remote state data source do, and what are its rules?
Answer: data "terraform_remote_state" "network" reads another stack’s state outputs, read-only: you get values, never ownership, and the other stack keeps managing those objects. Rules worth stating: only outputs are exposed, the backend must grant read access, and relying on it creates an invisible ordering dependency between pipelines, so teams often wire explicit triggers in CI. It is the standard cross-stack glue after a state split, and its read-only semantics are the trap inside the related Terraform interview questions.
What do state list, state show, and state pull tell you?
Answer: state list prints every address Terraform manages, the fastest way to find the exact address for a state operation. state show ADDRESS dumps one object’s recorded attributes, useful for debugging a diff that will not go away. state pull streams the raw state JSON to stdout for backup, diffing, or tooling, with state push as its dangerous sibling. Read-only state inspection is always safe and should be your first move in the scenario tier of Terraform interview questions.
What do state mv and state rm actually change?
Answer: state mv OLD NEW renames an address in state only, binding the same real object to new configuration, which is how renames and count-to-for_each conversions avoid destroy cycles. state rm, now documented as “forget”, removes the address from state while leaving the real object untouched, converting managed infrastructure to unmanaged. Both edit Terraform’s map of the world, never the world itself, and both should be followed immediately by a plan that shows the expected zero or minimal changes.
How does terraform import work, and what changed with the import block in 1.5?
Answer: Import binds an existing real object to a configuration address so Terraform starts managing it, writing its current attributes into state. The old CLI flow needed hand-written configuration first; the 1.5 import block makes imports plannable and reviewable, and plan -generate-config-out=generated.tf writes starting HCL for you. Both steps matter: bind the address, then reconcile the generated code until the plan is clean. Bulk adoption of legacy infrastructure is the work these Terraform interview questions are really probing.
How does Terraform detect drift between plan runs?
Answer: At plan time the refresh pulls live attribute values from each provider API and overwrites the recorded ones, then the diff compares that refreshed reality against configuration. A console edit therefore surfaces as a plan line wanting to revert it, and plan -refresh-only isolates the detection step. Limits to volunteer: detection only covers attributes the provider reads and Terraform tracks, and it happens when someone runs plan, so standing drift needs scheduled plans or a platform watching continuously. Detection mechanics anchor the drift family of Terraform interview questions.
Which HCL functions do you reach for most, and what do they solve?
Answer: The workhorses: cidrsubnet() for carving network ranges, merge() and coalesce() for combining maps and defaults, lookup() and try() for safe access, join() and split() for strings, formatdate() for timestamps, templatefile() for configs, and toset() or tomap() for type coercion before for_each. The graded habit is naming the class of problem, defaults, carving, guarding, rather than reciting an encyclopedia. Function fluency signals daily practice in working-level Terraform interview questions.
What does templatefile do, and how is it different from string interpolation?
Answer: templatefile("userdata.tftpl", { role = "web" }) renders a separate template file with a variables map, supporting loops and conditionals inside the template. Interpolation lives inside resource arguments and gets unwieldy past two or three lines; templates keep shell scripts, nginx configs, and cloud-init files out of HCL entirely, diff nicely in review, and stay testable. The operational note interviewers like: template files are included in the plan hash, so edits trigger replacement of the resource consuming them.
What are HCL’s complex types, and what is the any type?
Answer: Collections are list, map, and set, all elements one type; structural types are object and tuple, which fix attributes or positions with possibly mixed types. any is not a real type, it is a placeholder meaning “derive the concrete type from the value and stick to it,” which is why passing differently shaped objects to one any variable fails. Modeling environments as lists of objects with typed fields is the modern idiom, and comfortable type talk raises the level of your Terraform interview questions answers noticeably.
What are dynamic blocks, and where do they go wrong?
Answer: dynamic "ingress" { for_each = var.rules ... } repeats a nested block once per element of a collection, turning hand-copied security group rules into data. The failure modes: deeply nested dynamics become unreadable fast, so nest at most one level; not every block accepts them, arguments differ from blocks; and errors inside the collection surface at plan time with confusing messages. The judgment being tested is knowing when data-driven blocks beat explicit repetition, and when they hide complexity that belongs in a module. That judgment is the real subject of dynamic block Terraform interview questions.
Why save a plan file with -out for CI applies?
Answer: terraform plan -out=tfplan writes the reviewed diff to an encrypted-at-rest artifact, and terraform apply tfplan executes exactly that diff, rejecting anything that would change the plan’s assumptions. That closes the gap where the world shifts between review and execution, and it lets plan and apply run as separate jobs with the artifact as the contract between them. Candidate habit worth naming: the artifact still needs protection in CI, since it contains configuration values. Plan artifacts are the backbone of pipeline Terraform interview questions.
How do you structure a Terraform repository for a real organization?
Answer: Common shape: modules/ for reusable building blocks versioned by tags, stacks/ or per-team roots that call those modules and own backends, one root per environment per stack, and live configuration kept thin so review focuses on intent. Separate repos between module library and live roots once ownership diverges; keep provider and Terraform versions pinned per root. There is no single right answer, and interviewers score your reasoning about blast radius, ownership, and CI boundaries more than the layout you name. Repo design questions are the architectural end of Terraform interview questions.
How do you keep secrets out of Terraform code and logs?
Answer: Sources, not literals: pull secrets at apply time with data sources from Vault, AWS Secrets Manager, or SSM, pass them as environment variables through CI secret stores, and mark variables and outputs sensitive. Know the boundary honestly: anything that reaches state is readable by anyone with state access, and newer Terraform adds ephemeral values and write-only arguments so secrets can pass through without persisting. Rotation planning matters more than redaction, and saying that plainly is the senior move in secrets Terraform interview questions.
What is the moved block, and when does it beat state mv?
Answer: A moved block declares in code that an object’s address changed, moved { from = aws_instance.web, to = module.app.aws_instance.web }, and the next plan rewrites state as part of the normal review flow. It beats CLI state mv because it is versioned, reviewed, and applies to everyone who pulls the code, not just the engineer who ran a command. For one-off local fixes state mv is faster; for refactors shipped to a team, moved blocks are the professional default, a distinction module-refactor Terraform interview questions test directly.
What does terraform test (1.6+) add, and how do teams use it?
Answer: A native test framework: .tftest.hcl files run plan or apply against the configuration, assert on outputs and computed values, and can chain runs where one applies and the next verifies, with mock providers for unit-style tests. Teams use it two ways: fast assertions on module logic without cloud access, and small apply-and-destroy integration tests against real sandboxes in CI. Testing Terraform as code, not just reviewing plans, is the practice this question exists to surface, and it lands especially well in platform-focused Terraform interview questions.
What are precondition and postcondition blocks?
Answer: Preconditions fail a plan when an input is wrong, like a subnet CIDR overlapping an allocation; postconditions fail after a resource is read or created when reality does not match an assumption, like an AMI lacking a required tag. They encode invariants where they belong, at the resource, instead of scattered through logic, and failures stop the run before dependent objects are touched. Preconditions guard inputs, postconditions guard reality; saying that pairing crisply answers this question completely.
What is -replace, and what happened to terraform taint?
Answer: terraform apply -replace="aws_instance.web[0]" marks one object for destruction and recreation on the next apply, planned and reviewed like any other change. taint did the same job by writing a flag into state, but it hid the intent from review and left state mutated by a side channel, so HashiCorp deprecated it. The reasoning to state: replacement should always be visible in a plan, which is why the flag-based approach won. This deprecated-command arc is a favorite credibility check in Terraform interview questions.
How does the dependency graph drive apply order, and what does -parallelism do?
Answer: Terraform builds a directed acyclic graph from references between resources, modules, and data, then walks it creating independent branches concurrently and respecting edges for order. -parallelism N caps concurrent operations, lowered to be gentle with rate-limited APIs or to avoid hammering a shared database during mass provisioning. File layout and block order are irrelevant to ordering, a fact that surprises people and makes this question a reliable differentiator in Terraform interview questions about how the engine really works.
What changed about S3 backend locking, and why does it matter?
Answer: Historically S3 state needed DynamoDB as a lock table, a second piece of infrastructure with its own permissions and failure modes. Terraform 1.10 added native S3 locking via lock files, use_lockfile = true, with DynamoDB still supported for older setups, and the migration path is to cut over then remove the table. It matters operationally because one fewer service means one fewer source of stuck locks and cross-region latency issues, and it is current-awareness material in 2026 Terraform interview questions.
What does terraform state push do, and why is it the most dangerous command in the CLI?
Answer: state push FILE overwrites remote state with a local file, bypassing the serial check with -force even when the remote is newer. Its legitimate uses are narrow: restoring from a verified backup after corruption or a botched operation. Everything else is how you turn one bad state file into a fleet-wide destroy plan, because the next apply diffs the whole world against wrong records. Naming the one legitimate use and the backup-first ritual is the entire expected answer.
Why does required_providers have a local name and a source, and when do they differ?
Answer: aws = { source = "hashicorp/aws" }: the local name is what resource types use as their prefix, the source says which distribution to download. They diverge when namespaces change or forks exist: a partner provider, a vendor-forked provider, or OpenTofu registry mirrors all work by mapping one local name to a different source, with provider_local_name = provider.source style mappings in modules. Understanding that resource prefixes are just local names unlocks reading provider errors, which is the depth these Terraform interview questions are checking for.
What is terraform show -json for?
Answer: It renders plans, state, and applies as stable machine-readable JSON with a documented schema, which is what every Terraform integration is actually built on: policy tools parse resource changes and attribute diffs, dashboards render colored plans in pull requests, and audit jobs extract who changed what. The human plan output is for people; the JSON is for programs. Knowing it exists and naming one concrete consumer, OPA checks, PR plan comments, is the detail that completes this answer.
Why can’t your code branch on values that Terraform will only know after apply?
Answer: Because plan must complete before any object exists: computed values like an instance’s private IP are unknowns at plan time, represented but not resolved, so logic like count = aws_instance.web.ip == "x" ? 1 : 0 is impossible by design. Configuration can only branch on values known upfront, variables, data attributes, resource arguments you set. This is why proven patterns exist: null_resource triggers, separate applies, or provider-side interpolation. Unknown-value reasoning is the mechanical depth that intermediate Terraform interview questions use to sort candidates.
How do you run Terraform in CI safely?
Answer: The shape: plan on every pull request with the diff posted for review; apply only on merge to the protected branch, from one pipeline identity, applying the saved plan artifact. Authenticate to cloud APIs with short-lived OIDC federation instead of stored keys, scope the pipeline role to the stack’s resources, keep state in a locked backend the runner alone can write, and gate applies behind environment approvals. Everything in the scenario tier of Terraform interview questions assumes this pipeline exists, which is why it closes this tier.
Scenario and troubleshooting questions
This tier is how scenario rounds actually feel: one symptom sentence, then the interviewer goes quiet while you think out loud. For every item below, the graded skill is the same: state your order of checks and the reasoning behind it, then act. Silence plus random state rm loses to a spoken diagnostic plan almost every time, and that plan is what scenario Terraform interview questions are really measuring.
The state file is gone or corrupted: the bucket was emptied and nobody can explain how. What do you do?
Answer: First, freeze: no applies, no state pushes, announce it. Then inventory recoverable copies in order of trust: S3 bucket versioning or replication, backend platform run history, a teammate’s stale terraform.tfstate backup file, CI artifacts. Restore the newest version, verify with terraform plan: a healthy restore diffs to near-zero, a wrong one diffs wildly. If nothing is recoverable, rebuild state by importing every managed object, using cloud inventory, tags, and -generate-config-out. The order, freeze, restore, verify by plan, import as the fallback, is the entire question, and it is the most feared of the scenario Terraform interview questions for good reason.
A developer changed a security group rule in the console to unblock themselves. Walk me through your response.
Answer: Diagnose first: terraform plan shows the console edit as a diff wanting to revert it, and plan -refresh-only isolates detection from action. Then make the adopt-or-revert decision with the developer: if the change is wanted, bring it into code, edit the resource or import their manual object properly, and the plan goes clean. If not, a normal apply reverts the object to configuration. Either path ends with a clean plan and a conversation about why the console was faster than a pull request. Deciding on purpose instead of reflexively applying is exactly what drift Terraform interview questions score.
terraform apply died halfway through, after creating some resources and before others. What is the state of the world, and what now?
Answer: The state file is truthful: every object that finished is recorded, partial objects may be tainted or absent, and nothing else was touched. The recovery order: read the error to understand why it stopped, permissions, API error, timeout; run terraform plan, which shows exactly the remaining work because state already reflects progress; then apply again. If a created-then-failed object is now stuck in “already exists,” import it or let the replace logic handle it. The sentence interviewers wait for: a failed apply is resumable, not ruined, because state was written incrementally, which is the mechanism half of these Terraform interview questions.
After adding a new module, init fails: the module pins aws 4.x while your root requires 5.x. How do you resolve it?
Answer: Terraform reports the conflicting constraints and installs nothing, so the diagnosis is already done; the work is negotiating the versions. Read every constraint with terraform providers, which shows required versions per module. Then either upgrade the old module to a major that satisfies 5.x, the right fix, or relax your root constraint until the module catches up. Run init -upgrade, review the provider changelog for breaking changes, and re-plan carefully, because major provider bumps change plans, not just downloads. Constraint negotiation plus changelog review is the expected resolution story in these provider Terraform interview questions.
Your team renamed a widely used module and moved every resource into it. How do you ship that without a destroy storm?
Answer: Renames are address changes, and addresses are metadata, so plan the metadata move first. Add moved blocks for every old-to-new address, commit, and run terraform plan: the correct result is zero changes, because each moved block rewrites state in place. If anything shows a destroy, the mapping is incomplete or the configuration actually changed too, and you stop there. Ship in one PR containing only moves; mix in behavior changes and you cannot tell refactor damage from intended change. Zero-change plan as the acceptance gate is the discipline module-refactor Terraform interview questions are looking for.
terraform plan hangs, then reports “Error: acquiring the state lock.” Someone is holding it. What is your sequence?
Answer: Read the error’s lock metadata first: it names the operation, who created it, when, and from where, and that metadata answers the real question, is the holder alive? Ask the named person, check the CI run it points to. A live apply finishes in minutes and you wait; a stale holder is released with terraform force-unlock LOCK_ID after confirming no process is running. Never force-unlock blind: killing a lock under a running apply is how state gets two writers and a corruption ticket. Verify, then force, is the whole discipline this scenario Terraform interview question tests.
An apply fails with “resource already exists” for an object Terraform wants to create. What happened and what is the fix?
Answer: The real object predates your state: someone made it by hand, or a previous apply partially completed and the record never landed. The fix is reconciliation, not deletion, in most cases: terraform import the existing object’s ID into the pending address, then re-run plan to confirm the diff is clean or only trivial. Decide deliberately in the rare case where the existing object is wrong and replacement is intended, because importing the wrong ancestor binds your code to an artifact you did not choose. Import, verify, apply is the order, and knowing when to choose destroy instead is the judgment layer of these Terraform interview questions.
A routine plan suddenly wants to destroy and recreate the production database. What do you do before touching apply?
Answer: Stop and read the diff line: the gray attribute lines name the property that forced replacement, an engine version, an instance class the API cannot mutate, a subnet move. Then run the ladder: was the change intended, and if not, where did it come from, a module bump, a variable default, a provider behavior change? Block it with prevent_destroy if the guard is missing, and decide the real path: revert the property, or plan a proper migration with create_before_destroy, snapshots, and a change window. Naming the forcing attribute from the plan output is the moment interviewers know you have seen this scenario, which is the entire point of database-destroy Terraform interview questions.
Plan looks perfect in CI, but apply fails with access denied on half the resources. How do you debug that split?
Answer: Plan and apply used different credentials or different permissions, so first establish identity: print the caller identity or token claims each job runs as, and diff them. Common causes: plan runs with broad read-only role while apply uses a scoped role missing one service, an OIDC trust policy drifted, or the apply pipeline assumed an old role after an account migration. Fix the IAM gap deliberately instead of granting admin, and add a preflight sts get-caller-identity check to both jobs. The lesson to state: a plan passing proves nothing about apply permissions, because reads and writes are different capabilities, and that asymmetry is what these pipeline Terraform interview questions teach.
State says an EC2 instance exists, but the console and API say it does not. What will happen, and what should you do?
Answer: Someone deleted it out-of-band, and the next refresh-driven plan will propose recreating it, because state claims ownership the world no longer honors. First decide whether recreation is wanted: if the instance should exist, apply and let Terraform rebuild it, ideally before something auto-applies. If it should not, remove the address from state with state rm so Terraform forgets it cleanly. The dangerous middle is leaving it to a scheduled pipeline that applies unattended, which turns drift into a surprise rebuild. Aligning state with intent on purpose, rather than by accident, is the reasoning scenario Terraform interview questions reward here.
An apply has been stuck on “Still creating…” for an RDS instance for 25 minutes. What are your options?
Answer: Diagnose before interrupting: open the cloud console or CLI events for the object, because the API knows whether it is progressing, restoring a snapshot, or waiting on a dependency like a missing parameter group or subnet that has no free addresses. Provider timeouts for databases are deliberately long, so patience is often correct. Ctrl+C is graceful: Terraform finishes or cancels cleanly and leaves truthful state, but the cloud-side operation usually continues, so verify what the API is doing before re-applying. Telling that story, check API events, understand the wait, then choose, is exactly the composure these stuck-apply Terraform interview questions test.
A colleague ran terraform destroy against the wrong workspace and production resources are deleting. What is the playbook?
Answer: Two clocks are running: the apply itself, and the recovery afterward. Interrupt the run if you can, Ctrl+C stops scheduling new destroys; then assess from state and cloud inventory what is gone, what is stopping, and what has backups. Recovery order: restore data-first systems from snapshots and backups, then let Terraform recreate structures with a fresh apply, then re-point systems and validate. Prevention gets named in the same answer: prevent_destroy on stateful resources, separate credentials and backends for production, approvals on destructive plans. Prevention named during the incident story is what elevates this answer above panic in senior Terraform interview questions.
You discover database credentials sitting in plaintext inside a state file that three contractors could read. What now?
Answer: Treat it as a live credential exposure, because it is: rotate the secret first, database passwords, API tokens, anything in that state, since you cannot un-leak a file that was copied. Then scope: check backend access logs for reads, revoke unnecessary state permissions, and tighten the bucket policy or platform ACL. Then fix the pipeline: secrets enter through Vault or a secrets-manager data source at apply time, state access shrinks to the pipeline identity, and the incident gets a writeup. Rotate, scope, redesign is the order, and leading with rotation instead of redaction is the instinct security-flavored Terraform interview questions are probing for.
Two engineers applied against the same stack this morning and one set of changes silently lost. What broke, and how do you prevent it?
Answer: The backend had no locking, so both plans diffed the same base state and the second apply overwrote what the first recorded, a classic lost-update. Check the backend config first: local state files, or a remote backend without locking enabled, explain it immediately. Recover by diffing intent against state and re-applying the lost change, then fix the root cause: remote backend with locking on, one apply identity via CI, and laptop applies to shared stacks blocked at the IAM layer. Locking is not bureaucracy, it is the serialization that makes shared infrastructure safe, and saying why makes this answer land in Terraform interview questions.
terraform init fails with provider checksum verification errors on CI but works on laptops. What is going on?
Answer: The lock file records SHA-256 checksums per platform, and CI, frequently linux_amd64 or arm64, is failing for a checksum that is missing or mismatched. Diagnose in order: does the lock file contain hashes for CI’s platform, an old lock created before multi-platform h1 hashes is the classic cause; is CI fetching from a mirror or proxy that serves different bytes; did someone commit an edited lock file? Regenerate with terraform providers lock -platform=... to cover all platforms, commit, and rerun. Checksum discipline exists precisely to catch supply-chain surprises, and explaining that purpose is the depth these init Terraform interview questions want.
A developer ran apply from a feature branch and resources landed in the staging account instead of dev. How did it happen and what now?
Answer: The backend and provider config on that branch pointed somewhere else: a changed backend key, a workspace variable, or an inherited tfvars precedence surprise where a flag overrode the intended environment. Freeze and assess first: which account, which resources, any shared names now colliding. Recovery is usually apply in the wrong place to destroy what was just created, then apply in the right place, sequenced so nothing depended on the misplaced objects. Prevention: backend keys derived per workspace and environment, CI as the only apply identity, and a plan review that reads the provider and region lines, because that is exactly the header detail this class of Terraform interview questions is teaching people to check.
Every plan shows a diff on one resource even though nothing changed. The diff is the same every time. What is your approach?
Answer: A perpetual diff means the provider writes a value, then reads back something different, an idempotency bug, a normalizing API, or another system editing the attribute between runs. Read the exact attribute first: timestamps and default tags that the API injects are the usual suspects. Check the provider changelog and issues for the resource type, since known cases have documented workarounds. Then scope the fix: ignore_changes on that attribute if it is cosmetic and truly owned elsewhere, an upgrade if the bug is fixed upstream, or upstreaming the report if it is not. Naming the mechanism, write-read mismatch, instead of just reaching for ignore_changes is what separates the answers interviewers remember in these Terraform interview questions.
You upgraded a shared module from v1 to v2 and one stack’s plan now shows twelve destroys. What do you do?
Answer: Stop before applying and classify the destroys: address changes the module made without a moved block, renamed resources, or genuinely changed defaults. For renames, the module should ship moved blocks inside itself, which make the same plan show zero changes; if v2 lacks them, pin callers back to v1 and contribute the moves upstream. For changed defaults, decide per stack whether to pin old values explicitly, migration variables, or accept the change with a window. Version-pinned rollback first, then fix the module, is the order that keeps ten consumer stacks safe while one is migrating, and that multiplier awareness is what these module-upgrade Terraform interview questions are really testing.
You inherit 400 console-built resources and must bring them under Terraform. How do you plan the import at scale?
Answer: Sequence it: inventory first with cloud-native export tooling and tag sweeps, then group by lifecycle, network, databases, compute, and import one group per PR, never a 400-resource mega change. Use import blocks with plan -generate-config-out to draft HCL, then reconcile the generated code: rename defaults, extract variables, and drive each PR’s plan to zero changes before apply. Verify ownership boundaries as you go, some objects should stay unmanaged deliberately. Small verified batches, zero-change gates, and an explicit not-managing list are the three habits that make bulk import answers credible in Terraform interview questions.
A CI plan wants to destroy everything: 200 resources, all of them. What is the first thing you check?
Answer: State mismatch, always first: the pipeline is planning against empty or wrong state, so Terraform believes it owns nothing and proposes rebuilding the world. Check which backend the job initialized, a missing init -reconfigure, a backend block changed on the branch, or the wrong workspace selected via TF_WORKSPACE, and confirm with state list in that context: empty or five entries where there should be 200 confirms it. Never approve that plan; the fix is making CI plan against the same state humans do. Denying the plan and naming the state-mismatch check within seconds is the response this classic of scenario Terraform interview questions exists to elicit.
A large apply keeps failing partway with provider rate-limit errors. How do you get it through?
Answer: The apply is out-pacing the API’s quota, so reduce concurrent pressure and add resilience. Drop -parallelism from the default to a number the provider tolerates, split the stack so unrelated resources apply in separate runs, and check the provider’s retry behavior, newer provider versions back off better. For chronic cases, request a quota raise, since throttling during disaster recovery is a capacity problem, not just a tuning one. Naming the mechanism, unbounded graph concurrency against a metered API, and giving both the immediate knob and the structural fix is the complete shape for these rate-limit Terraform interview questions.
Last night’s CI job was killed mid-apply, and every run since fails waiting for the state lock. What is your cleanup?
Answer: The lock outlived its process, which locking systems expect and handle deliberately. Verify the holder is truly dead: check the lock metadata’s operation and creator, confirm in CI that the job terminated, and check for any still-running runner. Then release with terraform force-unlock LOCK_ID, or delete the lock object per your backend’s documented recovery, and immediately run terraform plan to see the truthful leftover diff before anyone applies. Prevention closes the answer: pipeline timeouts that cancel gracefully, and alerts on locks older than a threshold. Verify, unlock, plan is the triad this stale-lock Terraform interview question wants recited under pressure.
After apply, a downstream automation read an output and got a stale or empty value. Why does that happen and how do you fix the flow?
Answer: Outputs are computed from state at the end of apply, but the value may have been unknown at plan time or the automation read it before the apply finished, racing the run. Fix the contract rather than adding sleeps: have automation consume terraform output -json after apply completes, from the same pipeline, or have downstream systems read the remote state data source on their own schedule. For genuinely eventual values, a DNS name that resolves late, add the readiness check at the consumer. Naming the race, apply finishing versus read happening, is the mechanism these output Terraform interview questions are quietly testing.
terraform validate fails with “cyclic dependency” involving three resources. How do you find and break the cycle?
Answer: Read the error’s address list, it names the exact cycle, then trace the references between those resources in code: a reference, a for_each over an attribute, or a depends_on that loops back. Break it by removing the false dependency: derive the value with a data source or a local instead of a direct reference, split one resource into two so ordering becomes acyclic, or replace a self-referencing attribute with an expression that does not need it. If the cycle is genuinely needed behavior, the design is wrong, not the graph. Reading the named addresses before guessing is the habit this circular-dependency Terraform interview question is checking for.
A resource was created in the wrong region: the code said us-east-1, the object is in eu-west-1. What do you check and how do you fix it?
Answer: Check which provider configuration that resource actually binds to: an inherited default provider where an alias was intended, or a variable feeding the region that resolved differently in that workspace. The fix is two-part: correct the provider binding so future applies are right, then deal with the object, recreate in the right region and destroy the stray, or, if recreation is expensive, leave it and transfer it to the correct provider’s scope only where the provider genuinely supports it, usually it does not, so plan the migration. Proving the binding with terraform providers and the plan’s provider lines is the diagnostic rigor these wrong-region Terraform interview questions reward.
Your organization runs 60 stacks on Terraform 1.5 and wants to standardize on 1.9. How do you roll that out without an incident?
Answer: Treat it as a migration with a canary: read the changelogs for behavior changes affecting your patterns, then pick two low-risk stacks, upgrade their pinned version, run plans and applies, and watch for diff surprises for a cycle. Encode the version check in required_version per stack so drift fails fast, and automate detection, a CI job that reports version skew across stacks makes the fleet visible. Roll out in batches by risk, databases last, keeping the rollout reversible by pinning. Core upgrades are usually boring when done this way, and saying why, small verified batches beat big-bang, is the judgment these upgrade Terraform interview questions are scoring.
Hands-on scenario labs
Reading answers builds vocabulary; building reflexes takes repetition, and the scenario tier of Terraform interview questions is graded on reflexes. Each lab below is a safe, self-inflicted incident that runs on your laptop with the free local provider, no cloud account needed. Do them three times: once with the checklist open, once from memory, once narrating out loud as if an interviewer were listening.
Lab 1: lose state and recover it
- Create a root module with one resource:
resource "local_file" "notes" { content = "hello" filename = "notes.txt" }, then runterraform initandterraform apply. - Inspect the machinery:
terraform state listfor the address, andterraform showto see the recorded attributes Terraform will diff against. - Simulate loss:
mv terraform.tfstate state.bak, then runterraform planand read the create Terraform now wants, because it owns nothing. - Restore with
mv state.bak terraform.tfstate, re-runterraform plan, and confirm the calming No changes message. - Finish by writing the recovery order from memory: freeze applies, find backups, restore, verify with plan.
Lab 2: manufacture and resolve drift
- From Lab 1’s directory, edit the file behind Terraform’s back:
echo "console edit" >> notes.txt. - Run
terraform planand read the diff proposing to revert your edit, which is drift detection working as designed. - Isolate detection with
terraform plan -refresh-onlyand confirm it shows the world change with no proposed action. - Rehearse both branches: adopt by updating the
contentargument until the plan is clean, then revert it back in code and watch the plan want to restore it. - Narrate the adopt-or-revert decision out loud, including why
state rmis never the answer.
Lab 3: convert count to for_each without a destroy
- Write one resource with
count = 3and per-index content, apply it, and list the addresses withterraform state list. - Convert the resource to
for_eachwith keysweb,api,cache, runterraform plan, and read the three destroys you must never apply. - Add a
movedblock for every instance,from = local_file.app[0]toto = local_file.app["web"]and so on. - Re-run
terraform planand confirm zero changes, then apply, because the addresses are now the new names. - Optionally remove the moved blocks in a second commit to understand why they must ship inside the refactor PR.
Cheat sheet: the commands behind the answers
Nearly every item in this bank of Terraform interview questions resolves to one of the commands below, in the same order you would reach for them live. Learn the table, then learn one mechanism sentence per row, and you can walk any scenario round without improvising.
| Command | What it tells you |
|---|---|
terraform version | Binary and provider versions in one line, the first sanity check |
terraform init -upgrade | Refreshes providers and modules within constraints and rewrites the lock file |
terraform fmt -recursive / validate | Style and syntax gates that cost nothing and catch the cheap bugs |
terraform plan -refresh-only | Only what the world changed, drift detection isolated from action |
terraform plan -out=tfplan | Freezes the reviewed diff as an artifact CI can apply exactly |
terraform apply tfplan | Executes precisely the reviewed plan, nothing recomputed |
terraform apply -replace=ADDR | Planned destroy and recreate of one object, the taint successor |
terraform state list | Every address Terraform manages, the map of what it owns |
terraform state show ADDR | Recorded attributes of one object, for diff debugging |
terraform state pull > backup.tfstate | A backup before any state surgery, always the first move |
terraform state mv OLD NEW | Renames an address in state only, no cloud call |
terraform state rm ADDR | Forgets an object while leaving it running in place |
terraform import ADDR ID | Adopts an existing object into management |
terraform plan -generate-config-out=gen.tf | Drafts HCL for import blocks at scale |
terraform force-unlock LOCK_ID | Releases a verified-dead lock, never a live one |
terraform workspace list / select | Switches between state instances of one root module |
terraform providers | Provider requirements and constraints across the module tree |
terraform providers lock -platform=... | Regenerates multi-platform checksums when CI verification fails |
terraform output -json | Machine-readable outputs for downstream automation |
terraform show -json tfplan | Stable JSON schema that policy and review tooling parse |
terraform console | Evaluates expressions against real config and state, free and safe |
terraform test | Native assertions in .tftest.hcl files, unit and integration |
terraform graph | dot -Tsvg | Visualizes the dependency DAG you are about to execute |
terraform destroy -target=ADDR | Scoped teardown, used sparingly and always with a reviewed plan |
The full CLI reference lives at developer.hashicorp.com/terraform/cli, and the language documentation, including the state, modules, and expressions pages this bank leans on, is at developer.hashicorp.com/terraform/language.
Key takeaways and FAQ
The through-line of every tier above: Terraform interview questions reward people who can pair a command with its mechanism. The command alone reads as memorization; the mechanism alone reads as theory; together they read as someone who has carried a production state file. Keep that pairing in every answer you rehearse, and the bank above becomes a script for the whole loop.
How long should I prepare for Terraform interview questions?
With daily Terraform use, a focused week: two days speaking the beginner tier aloud, two on intermediate mechanics, one on scenarios, the weekend on the labs. Without hands-on practice, plan three to four weeks and actually run every command once, because state surgery you have never performed is state surgery you will describe badly.
Are Terraform interview questions different for DevOps and platform roles?
The tiers are identical; the emphasis moves. DevOps loops concentrate on workflow, modules, variables, and CI integration, while platform loops go deeper on state design, workspace strategy, cross-stack references, and policy enforcement. Prepare the whole bank either way, because panels mix, and the scenario tier is common to both.
Do Terraform interview questions require a cloud account to practice?
Not for the mechanics: every lab on this page runs with the local provider on a laptop, and LocalStack or a free-tier account covers the rest. What interviewers do notice is whether you have actually applied something, so get one real apply done somewhere before the round, even on a throwaway account.
What single topic decides most Terraform interview questions?
State: what it stores, where it lives, how locking protects it, what corruption and loss actually mean, and how drift shows up in a plan. If you can narrate state fluently, most follow-up questions become extensions, because providers, workspaces, imports, and CI safety are all downstream of how Terraform remembers the world.
Should I learn Terraform or OpenTofu for interviews in 2026?
Learn the shared core, which is nearly everything on this page, and know the split: Terraform is the industry default under the Business Source License, OpenTofu is the Linux Foundation fork that teams standardize on for licensing or policy reasons. Interviewers care that you understand the tooling landscape, not which binary you personally ran last.
What should I read after this page?
Continue with the Kubernetes interview questions and Docker interview questions banks, since most Terraform-managed infrastructure ships containers on those platforms, or ground yourself first with the Linux interview questions that underpin everything. The AWS interview questions page pairs naturally with the provider-specific answers here, and the DevOps Prep hub lists the rest of the series as it ships.