Skip to main content

Top 50 Terraform Interview Questions for DevOps Engineers

· 10 min read
Goel Academy
DevOps & Cloud Learning Hub

Whether you are preparing for your first DevOps role or interviewing for a senior platform engineering position, Terraform questions will come up. This post covers 50 questions organized by difficulty, each with a concise answer and code snippet where relevant. Use it as a study guide, a refresher, or a reference to evaluate candidates.

Beginner (Questions 1-15)

1. What is Terraform and how does it differ from Ansible?

Terraform is a declarative infrastructure as code tool that manages cloud resources through providers. You describe the desired end state, and Terraform figures out how to get there. Ansible is procedural — you write step-by-step playbooks. Terraform excels at infrastructure provisioning; Ansible excels at configuration management.

2. What is the Terraform workflow?

terraform init      # Download providers, initialize backend
terraform plan # Preview changes
terraform apply # Apply changes to infrastructure
terraform destroy # Tear down all managed resources

3. What is Terraform state and why does it matter?

State is a JSON file (terraform.tfstate) that maps your HCL configuration to real cloud resources. Terraform uses it to determine what exists, what changed, and what needs to be created or destroyed. Without state, Terraform cannot manage existing infrastructure.

4. What is a Terraform provider?

A provider is a plugin that lets Terraform interact with a specific API. AWS, Azure, GCP, Kubernetes, and GitHub all have providers. You declare them in your configuration:

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

5. What is the difference between terraform plan and terraform apply?

plan is read-only. It compares your code against the state and the cloud, then shows what would change. apply executes those changes. Always run plan before apply to review changes.

6. How do you define a variable in Terraform?

variable "instance_type" {
type = string
default = "t3.micro"
description = "EC2 instance type"
}

# Usage
resource "aws_instance" "web" {
instance_type = var.instance_type
}

7. What are the ways to pass values to Terraform variables?

In order of precedence (highest to lowest): -var flag, -var-file, TF_VAR_ environment variables, terraform.tfvars, terraform.tfvars.json, *.auto.tfvars.

8. What is an output in Terraform?

Outputs expose values from your configuration — useful for passing data between modules or displaying information after apply:

output "instance_ip" {
value = aws_instance.web.public_ip
description = "Public IP of the web server"
}

9. What is the difference between resource and data source?

A resource creates and manages infrastructure. A data source reads existing infrastructure without managing it. Resources have full CRUD; data sources are read-only.

10. What does terraform init do?

It initializes the working directory: downloads providers, configures the backend, and installs modules. It is the first command you run in any Terraform project.

11. What is the .terraform.lock.hcl file?

It is the dependency lock file. It pins the exact provider versions used, ensuring every team member and CI pipeline uses the same versions. Commit it to version control.

12. What is terraform fmt and terraform validate?

terraform fmt formats HCL code to the canonical style. terraform validate checks syntax and internal consistency without accessing any APIs.

13. How do you destroy a specific resource without destroying everything?

terraform destroy -target=aws_instance.web

14. What is the purpose of terraform.tfvars?

It provides default variable values for your configuration. Terraform automatically loads terraform.tfvars and *.auto.tfvars files without any flags.

15. What are locals in Terraform?

Locals are computed values that simplify repeated expressions:

locals {
common_tags = {
Environment = var.environment
ManagedBy = "terraform"
Team = var.team_name
}
}

Intermediate (Questions 16-35)

16. What is a Terraform module?

A module is a reusable container for related resources. Any directory with .tf files is a module. The root module is your working directory; child modules are called with module blocks:

module "vpc" {
source = "./modules/vpc"
cidr = "10.0.0.0/16"
}

17. What is the difference between count and for_each?

count creates N identical copies indexed by number. for_each creates copies indexed by a map or set key. Use for_each when each instance is distinct:

# count — identical copies
resource "aws_instance" "web" {
count = 3
instance_type = "t3.micro"
}

# for_each — distinct instances
resource "aws_iam_user" "users" {
for_each = toset(["alice", "bob", "carol"])
name = each.key
}

18. What are Terraform workspaces?

Workspaces let you manage multiple state files from one configuration. Each workspace has its own state:

terraform workspace new staging
terraform workspace select staging
terraform apply

19. How does remote state work?

Remote state stores the state file in a shared location (S3, Azure Blob, GCS, Terraform Cloud) instead of locally. This enables team collaboration and state locking:

terraform {
backend "s3" {
bucket = "my-state-bucket"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}

20. What is state locking and why is it important?

State locking prevents two people from running terraform apply simultaneously, which would corrupt state. DynamoDB (AWS), Blob leases (Azure), or Terraform Cloud provide locking.

21. How do you import an existing resource into Terraform?

terraform import aws_s3_bucket.my_bucket my-existing-bucket

This adds the resource to state. You must also write the corresponding HCL code.

22. What is the depends_on meta-argument?

It creates an explicit dependency when Terraform cannot infer one from resource references:

resource "aws_instance" "app" {
depends_on = [aws_iam_role_policy.app_policy]
}

23. What are dynamic blocks?

Dynamic blocks generate repeating nested blocks from a collection:

resource "aws_security_group" "web" {
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}

24. What is the lifecycle block?

It controls resource behavior during create, update, and delete:

resource "aws_instance" "web" {
lifecycle {
create_before_destroy = true
prevent_destroy = true
ignore_changes = [tags]
}
}

25. What is a provisioner and when should you use one?

Provisioners run scripts on resources after creation (e.g., remote-exec, local-exec). They are a last resort — prefer cloud-init, user data, or configuration management tools.

26. How do you handle secrets in Terraform?

Never hardcode secrets. Use environment variables, vault providers, or sensitive variable marking:

variable "db_password" {
type = string
sensitive = true
}

27. What is the moved block?

It tells Terraform a resource was renamed or restructured without recreating it:

moved {
from = aws_instance.web
to = aws_instance.web_server
}

28. What is the difference between taint and replace?

taint (deprecated) marks a resource for recreation on next apply. replace is the modern equivalent:

terraform apply -replace=aws_instance.web

29. How do you reference module outputs?

module.vpc.vpc_id
module.vpc.private_subnet_ids

30. What are Terraform expressions?

HCL supports conditionals, loops, and functions:

instance_type = var.environment == "prod" ? "m5.large" : "t3.micro"
upper_name = upper(var.project_name)
subnet_ids = [for s in aws_subnet.main : s.id]

31. What is terraform_remote_state data source?

It reads outputs from another Terraform state file, enabling cross-stack references:

data "terraform_remote_state" "networking" {
backend = "s3"
config = {
bucket = "state-bucket"
key = "networking/terraform.tfstate"
}
}

32. What is the null_resource?

A resource that does nothing but can trigger provisioners. Often used with triggers to run scripts when values change. In modern Terraform, terraform_data replaces it.

33. How do you lock provider versions?

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0, < 6.0"
}
}
required_version = ">= 1.5"
}

34. What is a backend in Terraform?

A backend defines where state is stored and where operations run. Common backends: s3, azurerm, gcs, remote (Terraform Cloud).

35. How do you pass variables to modules?

Through input variables defined in the module, passed as arguments in the module block:

module "web" {
source = "./modules/web"
instance_type = "t3.medium"
vpc_id = module.networking.vpc_id
}

Advanced (Questions 36-50)

36. Explain Terraform state surgery. When would you use terraform state mv?

State surgery modifies the state file without affecting real infrastructure. terraform state mv moves resources between state addresses — useful during refactoring:

# Rename a resource
terraform state mv aws_instance.web aws_instance.web_server

# Move a resource into a module
terraform state mv aws_instance.web module.compute.aws_instance.web

37. How do you write a custom Terraform provider?

Use the Terraform Plugin SDK v2 in Go. Define a provider schema, implement CRUD functions for each resource, write acceptance tests, and publish to the registry.

38. What testing frameworks exist for Terraform?

terraform test (built-in since v1.6), terratest (Go-based integration testing), terraform-plugin-testing (provider acceptance tests), and checkov/tflint for static analysis.

39. How do you set up CI/CD for Terraform?

Plan on pull request, apply on merge to main. Use remote state with locking, run terraform fmt -check and terraform validate as early gates.

40. What is state blast radius and how do you reduce it?

Blast radius is the amount of infrastructure one state file controls. Reduce it by splitting state into smaller, independent modules scoped by lifecycle (networking, compute, data).

41. How does Terraform detect drift?

terraform plan compares the state file against the cloud API. Any differences are drift. Use -detailed-exitcode to automate drift detection in CI.

42. What is Terraform Cloud and when should you use it?

Terraform Cloud provides remote state, remote execution, policy enforcement (Sentinel), and team management. Use it when you need governance, audit trails, or centralized execution.

43. Explain the terraform state rm command.

It removes a resource from state without destroying it in the cloud. The resource becomes unmanaged:

terraform state rm aws_instance.web
# The EC2 instance still runs but Terraform no longer tracks it

44. What is Sentinel in Terraform Cloud?

Sentinel is a policy-as-code framework that enforces rules on Terraform plans before apply — for example, "all S3 buckets must have encryption enabled."

45. How do you handle multi-region deployments?

Use provider aliases:

provider "aws" {
alias = "us_west"
region = "us-west-2"
}

resource "aws_instance" "west" {
provider = aws.us_west
instance_type = "t3.micro"
}

46. What is the terraform console command?

It opens an interactive REPL for evaluating Terraform expressions against the current state and configuration:

terraform console
> length(var.subnet_ids)
3
> cidrsubnet("10.0.0.0/16", 8, 1)
"10.0.1.0/24"

47. How do you manage Terraform in a monorepo with multiple teams?

Use path-based CI triggers, CODEOWNERS files for review enforcement, separate state files per directory, and a shared module registry.

48. What is the difference between terraform refresh and terraform plan?

refresh updates the state file to match cloud reality but proposes no changes. plan refreshes state and then compares it against your code, showing proposed changes. Since Terraform 0.15.4, plan includes a refresh step by default.

49. How do you recover from a corrupted state file?

Restore from the backup file (terraform.tfstate.backup), from S3 versioning, or rebuild state by importing every resource. Always enable versioning on your state bucket.

50. What are check blocks in Terraform 1.5+?

Check blocks define continuous assertions that validate infrastructure without blocking applies:

check "website_health" {
data "http" "site" {
url = "https://example.com"
}
assert {
condition = data.http.site.status_code == 200
error_message = "Website is not responding"
}
}

Closing Note

Terraform interviews test both theoretical knowledge and practical experience. Knowing the commands matters, but explaining when and why you would use state mv instead of destroying and recreating, or why you split state by blast radius rather than by resource type — that is what separates senior candidates. Review these questions, practice the code snippets, and be ready to discuss real scenarios from your experience.