DevOpsInterviewPrep logo
Infrastructure as Code & Configuration / 01
easyNewHashiCorpAmazon & AWSInfosys

Walk me through terraform init, plan, apply and destroy. What is each one actually doing?

Four commands, and the interesting one is plan, because it is the only point where you see the three-way comparison Terraform is actually making before anything changes.

Updated Sep 2026 · Grounded in researched DevOps, SRE and platform engineering interview loops, written to a senior-engineer editorial bar, and never padded to hit a word count.

TL;DR: init downloads providers and connects to the backend, plan compares your code against state against reality and prints the difference, apply executes that difference, destroy removes what state says it owns. Always save the plan to a file and apply that file, or you approved one thing and ran another.

How to approach it

Spend most of the answer on plan, since the other three are short and plan is where the understanding shows. Specifically, say what it compares: configuration, state, and the live infrastructure. Candidates who describe it as "shows what will change" have not said where the information comes from.

A strong answer

terraform init prepares the working directory. It downloads the provider plugins your configuration references, downloads any modules, and configures the backend, which is where state will live. It writes .terraform.lock.hcl pinning provider versions with checksums, and that file belongs in git so every engineer and the pipeline resolve identical providers. Running init is safe and idempotent, and needed again whenever you add a provider or module.

terraform plan is the three-way comparison. It reads your configuration for the desired state, reads the state file for what Terraform believes it created, and refreshes against the provider API for what actually exists. Then it prints the actions that would reconcile them:

  # aws_instance.api will be updated in-place
  ~ resource "aws_instance" "api" {
      ~ instance_type = "t3.medium" -> "t3.large"
    }

Plan: 0 to add, 1 to change, 0 to destroy.

The symbols carry the whole risk assessment. + create, ~ update in place, - destroy, and -/+ destroy and recreate, which is the one to read carefully because it means the resource is being replaced. On a database or a stateful volume, a -/+ you did not expect is the plan you stop and investigate.

The refresh step is where drift appears. Something changed in the console, state does not know, and the plan shows it as a difference. That is the feedback loop the whole tool is built on.

terraform apply executes. Run bare, it produces a plan, prompts, and applies it, and the problem is that the plan it applies is a fresh one, not the one you read. In a pipeline that matters, so save and apply the file:

terraform plan -out=tfplan
terraform apply tfplan

Now the approval is bound to the exact change, and nothing that happened in between can slip in. Apply takes a lock on the state for its duration, which is what stops two people applying at once and corrupting it.

terraform destroy removes everything in state for this configuration. Scoped to that state, which is the safety property worth naming: it cannot touch resources it does not track. It is genuinely useful for ephemeral environments and genuinely dangerous anywhere else, which is why production state should be in a workspace nobody can run it against.

Worth mentioning: terraform fmt for formatting and terraform validate for syntax and type checking, both of which belong as pull request checks because they cost seconds. And terraform state subcommands for the surgical cases, where state rm forgets a resource without deleting it and import adopts an existing one.

What interviewers probe next

"What is in the state file, and why not just read the cloud?" It maps your resource addresses to real resource IDs, holds dependency ordering, and caches attributes. Without it Terraform cannot tell a resource it created from one it did not. It also contains resource attributes in plaintext, including some secrets, so it is a sensitive artifact and belongs in an encrypted remote backend rather than in git.

"Why does a plan sometimes show changes when nothing changed?" Usually drift from a manual change, a provider defaulting a field you did not set, or a computed attribute that changes on read. Persistent phantom diffs usually mean a missing lifecycle block or a provider bug.

"How do two engineers avoid applying at the same time?" State locking, via DynamoDB for the S3 backend or natively in Terraform Cloud and the GCS backend. Without a lock, concurrent applies can corrupt state.

Common mistakes

Running apply without a saved plan, so the reviewed change and the executed change are not the same thing.

Not committing the lock file, so providers resolve differently for different people.

Skimming past a -/+ replacement on a stateful resource.

Keeping state locally or in git, which loses locking, exposes secrets in a diff, and breaks the moment a second person is involved.

That one was free, and so are 18 answers per topic without an account. Signing in doubles that to 28, keeps your bookmarks, and tracks which topics you keep getting wrong.one Google click · no card · nothing to cancel
HOW DID IT GO?
0
UP NEXT ON YOUR JOURNEY
DISCUSSION · 0

Nothing here yet. Say how you would answer it.