10 Terraform Interview Questions That Can Decide a ₹30 LPA DevOps Interview
10 Terraform Interview Questions That Can Decide a ₹30 LPA DevOps Interview
State Management | Modules | Secrets | Drift Detection | Remote Backend | Production Troubleshooting
Terraform is easy to learn at the surface level. Writing a few .tf files, creating an EC2 instance, and provisioning an S3 bucket may feel straightforward.
But senior DevOps interviews test something deeper: Do you understand what Terraform is doing behind the scenes, how it manages infrastructure state, and how you recover when something goes wrong?
The interview scenario in the shared post highlights 10 important Terraform questions that can expose gaps in practical infrastructure engineering.
This guide answers all 10 questions using eight attributes:
Simple Concept
Why Do We Need It?
How Does It Work?
Production Example
Command / YAML
Common Interview Trap
Candidate-Style Answer
Memory Trick
The goal is not just to memorize Terraform commands. It is to understand how to use Terraform safely in real production environments.
Q1. What is the difference between terraform import and terraform taint?
Simple Concept
terraform import brings an existing infrastructure resource under Terraform state management.
terraform taint historically marked a resource for replacement during the next apply. In modern Terraform, the recommended approach is to use -replace with terraform plan or terraform apply, because the taint command is deprecated.
Why Do We Need It?
Import is useful when infrastructure already exists but was created manually or through another process.
Replacement is useful when a resource needs to be recreated because it is damaged, misconfigured, or cannot be safely updated in place.
How Does It Work?
Import associates an existing resource with a Terraform resource address. You must also write the corresponding Terraform configuration.
Replacement tells Terraform to destroy and recreate a resource according to its lifecycle and dependency requirements.
Production Example
Your organization has an S3 bucket created manually. You want Terraform to manage it without deleting and recreating it.
You define the resource configuration and import the existing bucket.
Separately, suppose an EC2 instance must be recreated because its configuration cannot be updated in place. You can request replacement through a Terraform plan.
Command / YAML
resource “aws_s3_bucket” “existing” {
bucket = “company-existing-bucket”
}Import an existing bucket:
terraform import \
aws_s3_bucket.existing \
company-existing-bucketPlan a resource replacement:
terraform plan \
-replace=”aws_instance.web”Review the plan before applying it.
Common Interview Trap
Confusing import with resource replacement.
Import does not automatically generate complete Terraform configuration. Also, replacement can cause downtime or data loss depending on the resource.
Candidate-Style Answer
“Terraform import is used to bring existing infrastructure into Terraform state management. Taint was traditionally used to mark a resource for recreation, but it is deprecated in modern Terraform. I use the -replace option to explicitly request replacement and review the plan before applying it.”
Memory Trick
Import = Manage Existing Resource.
Replace = Recreate Resource.
Q2. How do you manage secrets in Terraform without hardcoding them?
Simple Concept
Terraform secrets management means securely providing credentials, passwords, API keys, and tokens without exposing them in source code or configuration files.
Why Do We Need It?
Hardcoded secrets can leak through Git repositories, CI/CD logs, shared configuration files, and developer machines.
Even when a variable is marked sensitive, its value may still be stored in Terraform state.
How Does It Work?
Use a combination of:
Environment variables.
CI/CD secret stores.
AWS Secrets Manager or HashiCorp Vault.
IAM roles and short-lived credentials.
Restricted and encrypted Terraform state.
Least-privilege access.
For AWS, prefer IAM roles or workload identity federation over long-lived access keys wherever possible.
Production Example
A Terraform pipeline deploys an application infrastructure environment. The database password is retrieved through an approved secrets-management workflow rather than committed to a .tfvars file.
The Terraform state is stored in a restricted, encrypted remote backend.
Command / YAML
Define a sensitive variable:
variable “db_password” {
description = “Database password”
type = string
sensitive = true
}Provide the value through an environment variable:
export TF_VAR_db_password=”temporary-secret”
terraform planFor AWS Secrets Manager, Terraform can retrieve a secret:
data “aws_secretsmanager_secret_version” “db” {
secret_id = “production/database”
}Be careful: referencing a secret in Terraform can place its value in state. Protect state accordingly.
Common Interview Trap
Thinking that sensitive = true encrypts a secret or prevents it from being stored in state.
It primarily controls how Terraform displays sensitive values. It is not a complete secrets-management solution.
Candidate-Style Answer
“I avoid hardcoding credentials in Terraform files. I use CI/CD secret management, environment variables, workload identities, or a dedicated secret manager. I also protect remote state with encryption and strict access controls because sensitive values can still appear in Terraform state.”
Memory Trick
Never Hardcode → Retrieve Securely → Restrict Access → Protect State → Rotate.
Q3. What is the difference between count and for_each? Give a real-world use case.
Simple Concept
Both count and for_each create multiple instances of the same Terraform resource.
countuses a numeric index.for_eachuses stable keys from a map or set.
Why Do We Need It?
They help provision multiple similar resources without repeating configuration.
The choice matters because resource addresses affect Terraform state and future changes.
How Does It Work?
With count, resources are addressed using numeric indexes such as:
aws_instance.web[0]
aws_instance.web[1]With for_each, resources use keys:
aws_instance.web[”frontend”]
aws_instance.web[”backend”]If the collection changes, for_each often provides more predictable resource identity when the keys remain stable.
Production Example
You need three EC2 instances for a development environment. Their configuration is identical, so count can work well.
But suppose you manage different application servers with different names and configurations. for_each is more suitable because each resource has a meaningful key.
Command / YAML
Using count:
resource “aws_instance” “web” {
count = 3
ami = var.ami_id
instance_type = “t3.micro”
}Using for_each:
variable “servers” {
default = {
frontend = “t3.small”
backend = “t3.medium”
worker = “t3.micro”
}
}resource “aws_instance” “web” {
for_each = var.servers ami = var.ami_id
instance_type = each.value tags = {
Name = each.key
}
}Common Interview Trap
Saying that for_each is always better.
It depends on the resource collection and how its identity should behave. Also, changing keys can cause Terraform to treat resources as different instances unless state migration is handled appropriately.
Candidate-Style Answer
“I use count when I need a fixed number of similar resources. I prefer for_each when resources have meaningful names or keys, because it gives stable resource addresses and makes infrastructure easier to manage when the collection changes.”
Memory Trick
Count = Number.
For Each = Named Items.
Q4. How do you handle drift detection in Terraform?
Simple Concept
Infrastructure drift happens when the actual infrastructure differs from the configuration or state Terraform expects.
Why Do We Need It?
Someone may manually modify a security group, delete a resource, change an instance size, or update cloud configuration outside Terraform.
If drift goes unnoticed, the environment can become inconsistent and insecure.
How Does It Work?
Terraform compares the configuration, recorded state, and actual infrastructure during planning.
A normal terraform plan refreshes information from the provider before calculating proposed changes.
Review the differences and decide whether to:
Update Terraform configuration.
Reconcile the manual change.
Import an unmanaged resource.
Accept the external change and update the desired configuration.
Production Example
An engineer manually opens port 22 to the internet on a production security group.
Terraform detects that the real security group differs from the configuration.
The team investigates the change, confirms the intended access requirements, and restores the approved configuration.
Command / YAML
terraform planTo inspect state without proposing infrastructure changes:
terraform plan -refresh-onlyTo reconcile the refreshed state after review:
terraform apply -refresh-onlyCommon Interview Trap
Assuming Terraform automatically prevents manual changes.
Terraform can detect many forms of drift during refresh and planning, but detection depends on provider behavior and the resources being observed.
Candidate-Style Answer
“I handle drift through regular Terraform plans and automated CI/CD checks. When drift is detected, I identify what changed and whether it was intentional. I then update the configuration or reconcile the infrastructure and validate the result before applying changes.”
Memory Trick
Compare → Detect → Investigate → Reconcile → Prevent.
Q5. What is a Terraform remote backend, and why is it important?
Simple Concept
A backend determines where Terraform stores its state and, depending on the backend, how state operations are managed.
A remote backend stores state outside the local working directory.
Why Do We Need It?
In a team environment, storing state locally creates collaboration and consistency problems.
A remote backend helps teams share state, control access, protect sensitive data, and support locking where available.
How Does It Work?
Terraform connects to a configured backend during initialization.
For AWS, a common architecture uses an S3 bucket for state storage and a supported locking mechanism, such as S3 lockfiles in current Terraform versions.
The backend should also have appropriate encryption, versioning, and access policies.
Production Example
A team manages production EKS infrastructure. Instead of every engineer maintaining a separate local state file, Terraform uses a centrally managed S3 backend with restricted IAM permissions.
Command / YAML
Example S3 backend:
terraform {
backend “s3” {
bucket = “company-terraform-state”
key = “production/eks/terraform.tfstate”
region = “ap-south-1”
encrypt = true
use_lockfile = true
}
}Initialize:
terraform initThe S3 bucket must already exist, and the IAM identity must have the required permissions. Backend locking support and configuration should be checked against the Terraform version in use.
Common Interview Trap
Thinking that a remote backend automatically makes state secure.
You still need encryption, IAM restrictions, versioning, recovery procedures, and appropriate locking.
Candidate-Style Answer
“A remote backend stores Terraform state centrally so multiple engineers and CI/CD pipelines can work with the same infrastructure state. I commonly use S3 with encryption, versioning, restricted IAM access, and supported state locking to improve collaboration and protect state.”
Memory Trick
Remote Backend = Shared State + Access Control + Recovery + Locking.
Q6. How do you manage multiple environments such as development, staging, and production?
Simple Concept
Multi-environment management means maintaining separate infrastructure configurations and state for different deployment environments while reusing common Terraform code.
Why Do We Need It?
Development, staging, and production have different requirements for capacity, security, permissions, and availability.
Separating them reduces accidental production changes and makes deployments more predictable.
How Does It Work?
A common approach is:
Reusable Terraform modules.
Separate environment configuration.
Separate state files or state boundaries.
Environment-specific variable files.
Different IAM permissions.
Controlled CI/CD deployment approvals.
Terraform workspaces are another option for managing multiple state instances, but they do not automatically provide security or infrastructure isolation.
Production Example
A company uses one reusable EKS module for three environments.
Development uses smaller node groups, staging resembles production, and production has stricter access controls and high availability.
Command / YAML
Example folder structure:
terraform/
├── modules/
│ ├── vpc/
│ └── eks/
│
└── environments/
├── dev/
│ ├── main.tf
│ └── terraform.tfvars
├── staging/
│ ├── main.tf
│ └── terraform.tfvars
└── prod/
├── main.tf
└── terraform.tfvarsRun Terraform for development:
cd environments/dev
terraform init
terraform planCommon Interview Trap
Assuming that Terraform workspaces alone provide complete environment isolation.
Separate state does not automatically mean separate permissions, cloud accounts, credentials, or deployment controls.
Candidate-Style Answer
“I generally use reusable modules with separate environment configurations and state. Each environment has its own variables, permissions, and deployment workflow. Production changes go through stricter reviews and approval controls.”
Memory Trick
One Codebase → Reusable Modules → Separate Environments → Separate State.
Q7. What is the difference between local-exec and remote-exec provisioners?
Simple Concept
Both are Terraform provisioners that execute commands, but they run in different locations.
local-execruns commands on the machine executing Terraform.remote-execconnects to a remote resource and executes commands there.
Why Do We Need It?
They can perform certain actions after resource creation when those actions cannot be handled cleanly by the provider or another automation tool.
However, provisioners are generally a last resort because they can make infrastructure deployments harder to reproduce and recover.
How Does It Work?
local-exec executes a command in the local Terraform execution environment.
remote-exec connects to a remote machine using a supported connection method, such as SSH or WinRM, and runs commands remotely.
Production Example
A local command may update a deployment notification system after infrastructure creation.
A remote command may execute a bootstrap script on a newly created virtual machine, although cloud-init or configuration-management tools are often better choices.
Command / YAML
Local execution:
resource “null_resource” “local_example” {
provisioner “local-exec” {
command = “echo Infrastructure created”
}
}Remote execution:
resource “aws_instance” “web” {
ami = var.ami_id
instance_type = “t3.micro” provisioner “remote-exec” {
inline = [
“sudo systemctl status nginx”
] connection {
type = “ssh”
user = “ec2-user”
private_key = file(var.private_key_path)
host = self.public_ip
}
}
}This remote example is illustrative. It requires SSH connectivity, an appropriate user, and a secure connection setup. Avoid exposing private keys in Terraform state or logs.
Common Interview Trap
Using provisioners for every installation and configuration task.
Terraform is primarily for infrastructure provisioning. Prefer cloud-init, machine images, configuration-management tools, or application deployment systems when appropriate.
Candidate-Style Answer
“Local-exec runs a command on the Terraform execution machine, while remote-exec connects to a remote resource and executes commands there. I use provisioners only when necessary because they are less predictable than declarative infrastructure and dedicated configuration-management workflows.”
Memory Trick
Local = Terraform Runner.
Remote = Target Machine.
Q8. How do you safely roll back infrastructure changes after a failed deployment?
Simple Concept
Infrastructure rollback means returning a system to a known-good state after a change causes a failure.
Unlike application rollback, infrastructure rollback is not always as simple as restoring an earlier version.
Why Do We Need It?
A failed infrastructure change can break networking, compute, permissions, databases, or application connectivity.
An unsafe rollback can cause data loss or make the environment even less stable.
How Does It Work?
First, identify the changes that succeeded and the resources affected.
Then:
Stop further changes if necessary.
Review the failed apply output and current Terraform state.
Inspect actual cloud resources.
Determine whether to revert configuration or apply a corrective change.
Review the new Terraform plan.
Apply the safest recovery action.
Validate service health.
Terraform state backups and backend versioning can help recovery, but restoring an old state file does not automatically reverse real infrastructure changes.
Production Example
A Terraform change modifies production security group rules and causes application connectivity failures.
The team identifies the affected rules, restores the approved configuration, reviews the plan, applies the correction, and verifies application connectivity.
Command / YAML
terraform state list
terraform show
terraform plan
terraform plan -out=recovery.tfplan
terraform apply recovery.tfplanAlways inspect the plan before applying it. A saved plan should be generated after the relevant recovery configuration is prepared and reviewed.
Common Interview Trap
Blindly restoring an old state file or running terraform destroy after a failed deployment.
State represents Terraform’s knowledge of infrastructure. It is not a transactional rollback mechanism.
Candidate-Style Answer
“I would first assess which changes were completed and inspect the real infrastructure and Terraform state. I would correct the configuration, generate a fresh plan, review the impact, and apply a controlled recovery. I would then validate service health and investigate why the original deployment failed.”
Memory Trick
Stop → Inspect → Correct → Plan → Recover → Verify.
Q9. Explain terraform refresh vs. terraform plan.
Simple Concept
terraform refresh historically updated Terraform state to reflect the real infrastructure.
It is deprecated in modern Terraform workflows. The recommended approach is to use a refresh-only plan and apply it when appropriate.
terraform plan compares configuration, state, and observed infrastructure to propose changes.
Why Do We Need It?
Cloud resources can change outside Terraform. Refreshing helps update Terraform’s knowledge of the infrastructure, while planning helps determine what changes are required to reach the desired configuration.
How Does It Work?
A normal terraform plan refreshes resource information by default before calculating proposed changes.
A refresh-only plan focuses on updating state to reflect the remote infrastructure without proposing configuration-driven infrastructure changes.
Production Example
An engineer manually changes an EC2 instance configuration.
A normal plan detects the difference and may propose restoring the configured value.
A refresh-only plan updates Terraform state to reflect the observed infrastructure without attempting to reconcile it with the configuration.
Command / YAML
Normal plan:
terraform planRefresh-only plan:
terraform plan -refresh-onlyApply the refreshed state after reviewing:
terraform apply -refresh-onlyCommon Interview Trap
Saying that terraform refresh and terraform plan are interchangeable.
They serve different purposes. Also, a refresh-only operation does not bring infrastructure back to the desired configuration.
Candidate-Style Answer
“Terraform plan compares the desired configuration with the current infrastructure and state, then proposes changes. The old refresh command updated state from the real infrastructure and is deprecated. Today, I use refresh-only planning and apply when I specifically need to reconcile state.”
Memory Trick
Plan = What Needs to Change?
Refresh-Only = What Exists Right Now?
Q10. How do you write reusable Terraform modules?
Simple Concept
A Terraform module is a collection of Terraform configuration files that manage related infrastructure resources as a reusable unit.
Why Do We Need It?
Modules reduce duplicated code, improve consistency, and make infrastructure easier to maintain across multiple environments.
How Does It Work?
A reusable module typically contains:
main.tffor resources.variables.tffor inputs.outputs.tffor returned values.Documentation and examples.
Version constraints and validation where appropriate.
The root configuration calls the module and provides environment-specific values.
Production Example
A company creates a reusable VPC module that provisions public subnets, private subnets, route tables, and associated networking components.
The same module is used in development, staging, and production with different input values.
Command / YAML
Example module structure:
modules/
└── vpc/
├── main.tf
├── variables.tf
├── outputs.tf
└── README.mdModule resource:
resource “aws_vpc” “main” {
cidr_block = var.cidr_block tags = {
Name = var.name
}
}Variable:
variable “cidr_block” {
type = string
}variable “name” {
type = string
}Output:
output “vpc_id” {
value = aws_vpc.main.id
}Call the module:
module “vpc” {
source = “../../modules/vpc”
cidr_block = “10.0.0.0/16”
name = “production-vpc”
}Common Interview Trap
Creating a module that exposes every possible configuration option without clear defaults, validation, or documentation.
A good module should be reusable but not unnecessarily complicated.
Candidate-Style Answer
“I create reusable modules by separating resources, inputs, and outputs. I define clear variable types, validation, sensible defaults, and documentation. Then I call the modules from environment-specific root configurations and version shared modules so changes can be controlled.”
Memory Trick
Resources → Inputs → Outputs → Documentation → Reuse.
Production Terraform Best Practices
Understanding individual commands is important, but production Terraform requires a broader engineering approach.
Follow these practices:
Store state remotely with appropriate encryption and access controls.
Use state locking where supported.
Keep separate state boundaries for environments.
Use reusable, version-controlled modules.
Never commit credentials or sensitive state files.
Use short-lived cloud credentials where possible.
Review Terraform plans before applying changes.
Run validation and security checks in CI/CD.
Detect infrastructure drift regularly.
Protect production changes with approvals.
Maintain backups and recovery procedures.
Test infrastructure changes in non-production environments.
The Terraform Interview Mindset
When an interviewer presents a production scenario, don’t immediately jump to a command.
Explain your reasoning:
Understand the problem → Inspect state → Investigate actual infrastructure → Identify the root cause → Plan the change → Review risks → Apply safely → Validate.
This demonstrates that you understand Terraform as an infrastructure lifecycle tool, not just a command-line utility.
Final Thoughts
Terraform fundamentals are more than writing resource blocks.
You need to understand state management, remote backends, modules, secrets, drift detection, resource lifecycle, and recovery strategies.
A strong DevOps engineer should be able to explain not only how to create infrastructure, but also how to manage it safely when something changes unexpectedly.
Don’t just learn Terraform syntax. Learn how Terraform behaves in production.
That is the difference between someone who can write .tf files and someone who can confidently manage infrastructure.
About the Author
Arvind Verma | DevOps & Cloud Engineering
Explore practical DevOps learning resources:
https://topmate.io/arvindverma021/
Follow on LinkedIn:
https://www.linkedin.com/in/arvindverma021/
Read more on Medium:
https://medium.com/@arvindverma021
Subscribe on Substack:
Hashtags
#Terraform #TerraformInterview #DevOps #AWS #InfrastructureAsCode #IaC #TerraformModules #TerraformState #CloudEngineering #DevOpsInterview #PlatformEngineering #SRE #Jenkins #Kubernetes #DevSecOps #CloudAutomation #AWSDevOps #InfrastructureAutomation #TerraformBestPractices #ProductionEngineering
Arvind Verma is free today. But if you enjoyed this post, you can tell Arvind Verma that their writing is valuable by pledging a future subscription. You won't be charged unless they enable payments.
© 2026 Arvind Verma
548 Market Street PMB 72296, San Francisco, CA 94104