What Terraform and Infrastructure as Code are and why they matter in 2026
Terraform is an open-source Infrastructure as Code (IaC) tool created by HashiCorp that lets you define, provision, and manage cloud and on-premises infrastructure using declarative configuration files written in HashiCorp Configuration Language (HCL). Instead of manually clicking through AWS Console or typing CLI commands to spin up EC2 instances, VPCs, and security groups, you write a .tf file that describes your desired state, and Terraform calculates the delta between current reality and your desired end-state, then executes the necessary API calls to make it happen. In 2026, IaC has become the standard practice across Indian enterprises—Cisco India, HCL, Akamai India, and Aryaka all require DevOps engineers to demonstrate Terraform proficiency during technical rounds because manual infrastructure provisioning cannot scale to multi-region, multi-cloud deployments that modern SaaS platforms demand.
Infrastructure as Code treats infrastructure configuration as software source code: you version it in Git, peer-review it through pull requests, test it in staging environments, and deploy it through CI/CD pipelines. This approach eliminates configuration drift (where production servers diverge from documentation), enables disaster recovery through code replay, and accelerates onboarding because new team members read the main.tf file instead of hunting through wiki pages. For freshers entering the DevOps job market in Bengaluru, Hyderabad, or Pune, Terraform skills directly translate to ₹6-10 LPA starting offers at companies like Movate, Wipro, and IBM, while mid-level engineers with 3+ years of Terraform experience command ₹15-22 LPA at product companies.
Our AWS DevOps course in Bangalore dedicates four weeks to Terraform fundamentals and advanced state management because hiring partners explicitly request candidates who can write modular Terraform code, not just run terraform apply on sample scripts. During the 4-month paid internship at our Network Security Operations Division, interns deploy real production infrastructure for client projects using Terraform workspaces, remote backends in S3, and state locking with DynamoDB—experience that appears on the 8-month verified experience letter and gets validated in technical interviews.
How Terraform works under the hood
Terraform operates through a three-phase execution model: init, plan, and apply. When you run terraform init in a directory containing .tf files, Terraform downloads provider plugins (AWS, Azure, GCP, VMware, Cisco ACI, etc.) specified in your configuration and initializes a local .terraform directory. Providers are Go binaries that translate HCL resource blocks into vendor-specific API calls—the AWS provider knows how to call ec2:RunInstances, the Azure provider knows how to call Azure Resource Manager REST endpoints, and the Cisco ACI provider knows how to interact with APIC controllers.
The terraform plan command performs a dry-run: Terraform reads your .tf files, queries the current state (stored in terraform.tfstate by default), calls provider APIs to fetch real-world resource attributes, then computes a dependency graph and execution plan. The plan output shows which resources will be created (green +), modified (yellow ~), or destroyed (red -). This plan is deterministic and idempotent—running plan twice without changing code produces identical output. Under the hood, Terraform builds a directed acyclic graph (DAG) of resource dependencies: if an EC2 instance depends on a security group, Terraform ensures the security group is created first.
When you approve the plan and run terraform apply, Terraform executes API calls in dependency order, respecting parallelism limits (default 10 concurrent operations). After each resource creation or modification, Terraform writes the resource's unique identifier and current attributes into the state file. The state file is the source of truth for Terraform's understanding of reality—it maps your HCL resource names to cloud provider resource IDs. For example, aws_instance.web in your code might map to i-0a1b2c3d4e5f6g7h8 in AWS. On subsequent runs, Terraform compares state file contents against both your code and live API responses to detect drift.
In our HSR Layout lab, we tested Terraform's drift detection by manually modifying an EC2 instance's security group through the AWS Console after Terraform provisioned it. The next terraform plan detected the out-of-band change and proposed reverting the security group to the code-defined configuration. This behavior is critical in production: if a junior engineer makes an emergency firewall change via GUI at 2 AM, the next automated Terraform run will either revert it (if the change wasn't committed to code) or preserve it (if the engineer updated the .tf file and merged the PR). This enforcement of "code as the single source of truth" prevents the configuration sprawl that plagues manually managed infrastructure.
State management and remote backends
By default, Terraform stores state in a local terraform.tfstate JSON file. This works for solo learning but breaks in team environments: if two engineers run terraform apply simultaneously against the same infrastructure, they race to update the state file, causing corruption or resource duplication. Production Terraform deployments use remote backends—S3 with DynamoDB state locking is the standard for AWS shops, while Azure Blob Storage and Google Cloud Storage serve the same role in their ecosystems. The backend configuration in terraform { backend "s3" {...} } tells Terraform to store state remotely and acquire a lock before any operation.
State files contain sensitive data: database passwords, private keys, API tokens. Encrypting the S3 bucket with KMS and restricting IAM access is mandatory. Terraform Cloud and Terraform Enterprise (HashiCorp's SaaS and self-hosted offerings) provide built-in state encryption, versioning, and role-based access control. Many Indian enterprises—particularly those in BFSI sectors under RBI scrutiny—prefer self-hosted Terraform Enterprise to keep state files within their VPC boundaries rather than transmitting them to HashiCorp's US-based infrastructure.
Terraform vs Ansible, CloudFormation, and Pulumi
Terraform is often confused with Ansible because both are "automation tools," but they serve different layers. Terraform provisions infrastructure (creates VMs, networks, load balancers), while Ansible configures software on existing infrastructure (installs packages, edits config files, restarts services). A typical workflow uses Terraform to create an EC2 instance, then Ansible to install Nginx and deploy application code. Terraform is declarative—you describe the desired end state, and Terraform figures out how to get there. Ansible can be declarative (using modules like yum or apt) but often includes imperative playbook steps.
AWS CloudFormation is Amazon's native IaC service, using JSON or YAML templates instead of HCL. CloudFormation is tightly integrated with AWS services and supports some features (like CloudFormation StackSets for multi-account deployments) that require workarounds in Terraform. However, CloudFormation only works with AWS, while Terraform is cloud-agnostic—the same Terraform codebase can provision AWS VPCs, Azure VNets, and on-premises VMware clusters by swapping provider blocks. For Indian enterprises running hybrid cloud (common in banking and telecom), Terraform's multi-cloud capability is decisive. Cisco India's internal DevOps teams use Terraform to manage both AWS infrastructure and Cisco ACI fabric policies through the aci provider.
Pulumi is a newer IaC tool that lets you write infrastructure code in general-purpose languages (Python, TypeScript, Go) instead of a domain-specific language like HCL. Pulumi appeals to developers who prefer for loops and functions over HCL's limited expressiveness, but Terraform's ecosystem maturity—15,000+ community modules in the Terraform Registry, extensive documentation, and a larger talent pool—makes it the safer enterprise choice in 2026. Aryaka and Akamai India both standardized on Terraform after evaluating Pulumi because hiring Terraform-skilled engineers in Bengaluru is significantly easier than finding Pulumi expertise.
| Tool | Primary Use Case | Language | Cloud Support | State Management |
|---|---|---|---|---|
| Terraform | Infrastructure provisioning | HCL (declarative) | Multi-cloud + on-prem | Local or remote backend |
| Ansible | Configuration management | YAML (mostly declarative) | Cloud-agnostic | No persistent state |
| CloudFormation | AWS infrastructure provisioning | JSON/YAML (declarative) | AWS only | AWS-managed state |
| Pulumi | Infrastructure provisioning | Python/TypeScript/Go | Multi-cloud | Pulumi-managed or self-hosted |
Writing your first Terraform configuration
A minimal Terraform configuration to launch an EC2 instance in AWS requires three components: a provider block, a resource block, and variable definitions. Create a file named main.tf with the following structure:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-south-1" # Mumbai region
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 in ap-south-1
instance_type = "t3.micro"
tags = {
Name = "terraform-demo"
Environment = "dev"
ManagedBy = "terraform"
}
}
output "instance_public_ip" {
value = aws_instance.web.public_ip
}
The terraform block specifies required provider versions—pinning to ~> 5.0 allows minor version upgrades (5.1, 5.2) but prevents breaking changes from major version bumps. The provider "aws" block configures the AWS provider with the Mumbai region (ap-south-1), which is the lowest-latency region for most Indian deployments. Terraform reads AWS credentials from environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) or the ~/.aws/credentials file created by aws configure.
The resource "aws_instance" "web" block declares an EC2 instance. The first label (aws_instance) is the resource type from the AWS provider documentation; the second label (web) is your local name for this resource. You reference this instance elsewhere in your code as aws_instance.web. The ami argument specifies the Amazon Machine Image ID—AMI IDs are region-specific, so an AMI in us-east-1 won't work in ap-south-1. The tags map adds metadata to the instance; the ManagedBy = "terraform" tag is a best practice that helps operations teams distinguish Terraform-managed resources from manually created ones.
The output block prints the instance's public IP address after terraform apply completes. Outputs are useful for passing values to other Terraform modules or external scripts. To execute this configuration, run:
terraform init # Download AWS provider plugin
terraform plan # Preview changes (should show +1 to add)
terraform apply # Execute changes (type 'yes' to confirm)
terraform show # Display current state
terraform destroy # Tear down all resources (type 'yes' to confirm)
In the AWS DevOps training at Networkers Home, students extend this basic example to include VPC creation, subnet allocation, security group rules, and an Application Load Balancer—building a production-ready three-tier architecture over four lab sessions. The hands-on approach ensures that by week three, students can independently write Terraform modules for common patterns like auto-scaling groups with CloudWatch alarms.
Variables and input validation
Hardcoding values like instance_type = "t3.micro" makes code inflexible. Terraform variables allow parameterization. Create a variables.tf file:
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
validation {
condition = can(regex("^t3\\.", var.instance_type))
error_message = "Instance type must be from the t3 family for cost optimization."
}
}
variable "environment" {
description = "Deployment environment"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
Reference variables in main.tf using var.instance_type syntax. Pass variable values via command-line flags (terraform apply -var="environment=prod"), environment variables (TF_VAR_environment=prod), or a terraform.tfvars file. The validation block enforces constraints—the first validation ensures only t3 instance types are used (to control costs in a learning environment), while the second restricts environment names to a whitelist. These validations catch errors before Terraform makes API calls, saving time and preventing accidental production deployments with dev configurations.
Terraform modules and code reusability
As Terraform codebases grow beyond 500 lines, duplication becomes painful. If you provision separate VPCs for dev, staging, and prod environments, copying and pasting the same 50-line VPC configuration three times creates maintenance hell—a security group rule change requires editing three files. Terraform modules solve this by packaging reusable infrastructure components. A module is simply a directory containing .tf files; you call it from a parent configuration using a module block.
Create a modules/vpc/main.tf file that defines a VPC, subnets, internet gateway, and route tables with input variables for CIDR blocks and availability zones. In your root main.tf, call the module three times:
module "vpc_dev" {
source = "./modules/vpc"
environment = "dev"
vpc_cidr = "10.0.0.0/16"
availability_zones = ["ap-south-1a", "ap-south-1b"]
}
module "vpc_staging" {
source = "./modules/vpc"
environment = "staging"
vpc_cidr = "10.1.0.0/16"
availability_zones = ["ap-south-1a", "ap-south-1b"]
}
module "vpc_prod" {
source = "./modules/vpc"
environment = "prod"
vpc_cidr = "10.2.0.0/16"
availability_zones = ["ap-south-1a", "ap-south-1b", "ap-south-1c"]
}
Each module invocation creates an isolated instance of the VPC infrastructure with different parameters. Modules expose outputs (like VPC ID and subnet IDs) that parent configurations can reference: module.vpc_prod.vpc_id. The Terraform Registry hosts thousands of community modules—the terraform-aws-modules/vpc/aws module is production-grade and maintained by AWS community experts. Using registry modules accelerates development but requires vetting: check the module's GitHub star count, last update date, and issue tracker before depending on it in production.
During the 4-month paid internship at Networkers Home, interns refactor monolithic Terraform code into modules as part of real client projects. One recent batch modularized a 1,200-line main.tf for an e-commerce client into separate modules for networking, compute, database, and monitoring. The refactored codebase reduced deployment time from 18 minutes to 11 minutes (due to better parallelism) and eliminated three recurring bugs caused by copy-paste errors in security group rules. This hands-on module design experience is exactly what Cisco India and HCL interviewers probe during technical rounds.
State file management and team collaboration
The terraform.tfstate file is a JSON document mapping Terraform resource names to real-world resource IDs and attributes. When you run terraform apply, Terraform locks the state file, reads it, compares it against your code and live infrastructure, computes changes, executes API calls, then writes updated resource data back to state. If two engineers run terraform apply simultaneously without state locking, both read the same initial state, compute overlapping changes, and write conflicting updates—resulting in duplicate resources or orphaned infrastructure.
Remote backends with state locking prevent this race condition. The S3 backend configuration in backend.tf looks like:
terraform {
backend "s3" {
bucket = "mycompany-terraform-state"
key = "prod/vpc/terraform.tfstate"
region = "ap-south-1"
dynamodb_table = "terraform-state-lock"
encrypt = true
}
}
Before any operation, Terraform writes a lock record to the DynamoDB table with a unique operation ID. If a second engineer tries to run terraform apply, Terraform detects the existing lock and blocks until the first operation completes or times out. The S3 bucket should have versioning enabled so you can recover from accidental state corruption—terraform state pull retrieves the current state, and you can manually restore a previous version from S3 if needed.
State files contain sensitive data: RDS passwords, private keys embedded in user data scripts, API tokens. Encrypting the S3 bucket with AWS KMS is mandatory for compliance with DPDP Act requirements (India's data protection regulation effective 2024). Restrict bucket access using IAM policies that grant read/write only to the CI/CD service account and senior DevOps engineers. Never commit terraform.tfstate to Git—add it to .gitignore immediately. Terraform Cloud provides a managed alternative: state is stored in HashiCorp's infrastructure with encryption at rest and in transit, plus a web UI for state inspection and rollback.
Workspaces for environment isolation
Terraform workspaces allow multiple state files within a single backend, useful for managing dev/staging/prod environments from the same codebase. The default workspace is created automatically; create additional workspaces with terraform workspace new staging. Each workspace maintains a separate state file in the S3 backend under different keys: env:/staging/terraform.tfstate and env:/prod/terraform.tfstate.
Reference the current workspace in your code using terraform.workspace:
resource "aws_instance" "app" {
instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"
tags = {
Environment = terraform.workspace
}
}
Workspaces are controversial in the Terraform community. Proponents appreciate the simplicity of switching environments with terraform workspace select prod. Critics argue that workspaces encourage code duplication and make it too easy to accidentally destroy production infrastructure (one mistyped terraform destroy in the prod workspace wipes everything). An alternative pattern uses separate directories for each environment (environments/dev/, environments/prod/) that call shared modules, making it physically impossible to affect prod without cd-ing into the prod directory. Akamai India's DevOps team uses the directory-per-environment pattern after a 2023 incident where a contractor ran terraform destroy in the wrong workspace.
Common pitfalls and interview gotchas
Interviewers at Cisco India, HCL, and Aryaka consistently probe three Terraform failure modes during technical rounds. First: state file corruption. If terraform apply is interrupted mid-execution (network failure, laptop crash, Ctrl+C), the state file may reflect partial changes while actual infrastructure is in an inconsistent state. The recovery procedure is to manually inspect AWS Console, identify which resources were created, then either import them into state with terraform import or delete them and re-run terraform apply. Candidates who answer "just delete the state file and start over" fail this question—deleting state orphans all existing resources, leaving them unmanaged and accumulating costs.
Second pitfall: dependency cycles. If Resource A depends on Resource B, and Resource B depends on Resource A, Terraform cannot construct a valid execution order and fails with "Cycle: aws_instance.a, aws_security_group.b". This occurs when security group rules reference instances, and instances reference security groups. The fix is to break the cycle using aws_security_group_rule resources instead of inline rules, or by using depends_on to explicitly declare dependencies. In our HSR Layout lab, we intentionally create dependency cycles during troubleshooting exercises so students learn to read Terraform's graph output and identify the circular reference.
Third gotcha: provider version drift. If your terraform block specifies version = "~> 4.0" for the AWS provider, and AWS releases version 5.0 with breaking changes, a team member running terraform init on a fresh clone might download version 5.x, causing plan output to differ from the rest of the team. The solution is to commit a .terraform.lock.hcl file (generated by terraform init) to Git, which pins exact provider versions. Terraform 0.14+ creates this lock file automatically; older versions require manual terraform providers lock commands.
A fourth interview question that trips up freshers: "What happens if you manually delete a resource that Terraform manages?" The answer: on the next terraform plan, Terraform queries the provider API, discovers the resource is missing, and proposes to recreate it. Terraform does not automatically detect out-of-band deletions until you run a plan or apply. If you want Terraform to forget about a resource without deleting it, use terraform state rm aws_instance.web to remove it from state, then remove the corresponding resource block from your code.
Handling secrets in Terraform
Hardcoding database passwords in .tf files is a critical security violation. Terraform supports several secret management patterns. The simplest is to define a variable with sensitive = true and pass the value via environment variable (TF_VAR_db_password) or a .tfvars file excluded from Git. Terraform will redact sensitive values in plan output, showing (sensitive value) instead of plaintext.
For production systems, integrate with AWS Secrets Manager or HashiCorp Vault using data sources:
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/mysql/master-password"
}
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
# other arguments...
}
Terraform retrieves the secret at plan time via API call, uses it to configure the RDS instance, but never writes the plaintext password to the state file—state contains only the Secrets Manager ARN. This pattern satisfies RBI and DPDP Act requirements for secret handling in BFSI applications. During the DevOps fundamentals course, students implement this pattern in a capstone project that deploys a three-tier web application with RDS backend, ensuring secrets are never committed to Git or logged in CI/CD output.
Real-world deployment scenarios in Indian enterprises
Terraform adoption in Indian enterprises follows predictable patterns based on industry vertical. BFSI companies (HDFC Bank, ICICI, Kotak) use Terraform to provision AWS infrastructure while keeping core banking systems on-premises, creating hybrid architectures where Terraform manages VPN gateways, Direct Connect links, and security groups that bridge cloud and datacenter. These organizations run Terraform in a centralized platform team model: application teams submit pull requests to a shared Terraform repository, and the platform team reviews, approves, and executes changes through Jenkins or GitLab CI pipelines.
Product companies and startups (Razorpay, Zerodha, Cred) give individual engineering teams autonomy to manage their own Terraform code, with guardrails enforced through policy-as-code tools like Sentinel or Open Policy Agent. A common policy prevents engineers from launching instances larger than t3.xlarge without manager approval, or blocks public S3 buckets to prevent data leaks. Founder Vikas Swami architected QuickZTNA's infrastructure using Terraform modules that provision Kubernetes clusters, Istio service mesh, and Cilium network policies across AWS and on-premises VMware—demonstrating Terraform's capability to manage both cloud-native and traditional infrastructure from a single codebase.
Service providers like HCL, Wipro, and TCS manage infrastructure for dozens of clients using Terraform workspaces or separate Git repositories per client. A typical engagement involves migrating a client's manually provisioned AWS infrastructure to Terraform: engineers use terraform import to bring existing resources under Terraform management, then refactor the imported code into modules. This "brownfield Terraform adoption" is messier than greenfield deployments but represents 70% of real-world Terraform work in the Indian IT services sector. Our 4-month paid internship exposes students to both greenfield (building new infrastructure from scratch) and brownfield (importing and refactoring existing infrastructure) scenarios because both skill sets are tested in job interviews.
Telecom operators (Airtel, Jio, Vodafone Idea) use Terraform to manage edge computing infrastructure: thousands of small Kubernetes clusters deployed in cell towers and regional data centers. Terraform's for_each meta-argument allows provisioning 500 identical clusters with different IP ranges and region tags from a single module invocation. The state file for such deployments can exceed 100 MB, requiring careful state file partitioning (separate state files per region) and aggressive use of -target flags to apply changes to subsets of infrastructure.
How Terraform connects to AWS DevOps certification and career paths
Terraform is not directly covered in AWS Certified Solutions Architect or AWS Certified DevOps Engineer exams, but the underlying concepts—infrastructure provisioning, state management, idempotency—are tested through CloudFormation questions. Candidates who understand Terraform's execution model find CloudFormation questions trivial because the mental models are identical: both tools maintain state, compute diffs, and execute changes in dependency order. The AWS DevOps Engineer – Professional exam (DOP-C02) includes scenario questions about CI/CD pipelines that provision infrastructure, where Terraform is a valid (and often superior) answer compared to CloudFormation.
In the Indian job market, "Terraform" appears in 68% of DevOps Engineer job descriptions on Naukri and LinkedIn (as of January 2026), compared to 45% for CloudFormation and 32% for Ansible. Cisco India's DevOps team requires Terraform proficiency for L2 and above positions, with interview questions covering module design, state management, and troubleshooting. Akamai India's SRE interviews include a live coding exercise where candidates write Terraform code to provision an auto-scaling web application with CloudWatch alarms—candidates have 45 minutes and access to Terraform documentation.
Career progression for Terraform specialists follows this path: Junior DevOps Engineer (writes Terraform code from templates, ₹6-10 LPA) → DevOps Engineer (designs modules, implements CI/CD for Terraform, ₹12-18 LPA) → Senior DevOps Engineer (architects multi-account AWS organizations with Terraform, mentors juniors, ₹18-28 LPA) → DevOps Architect (defines organizational Terraform standards, evaluates policy-as-code tools, ₹28-45 LPA). The 8-month verified experience letter from Networkers Home explicitly lists Terraform skills and projects, which hiring managers at Barracuda, Aryaka, and Movate validate during reference checks.
Terraform in CCNA, CCNP, and CCIE contexts
Traditional network engineers pursuing CCNA, CCNP, or CCIE certifications increasingly encounter Terraform in enterprise environments where network infrastructure is software-defined. Cisco ACI (Application Centric Infrastructure) and Cisco SD-WAN both expose REST APIs that Terraform providers can consume. The terraform-provider-aci allows network engineers to define tenant configurations, bridge domains, and contracts in HCL instead of clicking through APIC GUI. This "network as code" approach is tested in CCIE DevNet (formerly CCIE Collaboration) lab exams, where candidates must demonstrate API-driven network provisioning.
For CCNP Enterprise candidates, understanding Terraform's declarative model helps grasp Cisco DNA Center's intent-based networking: both systems let you declare desired state (Terraform: "I want 3 EC2 instances"; DNA Center: "I want QoS policy applied to all branch offices") and let the controller figure out the imperative steps. The mental model transfer is direct. In our HSR Layout lab's 24×7 rack access area, students practice Terraform provisioning of AWS infrastructure alongside traditional CCNP labs on physical Cisco routers and switches, building the hybrid skill set that modern network engineering roles demand.
Frequently asked questions
Can Terraform manage existing infrastructure that was created manually?
Yes, using terraform import. For each existing resource, you write the corresponding resource block in your .tf file (without attributes—just the resource type and name), then run terraform import aws_instance.web i-0a1b2c3d4e5f6g7h8 to import the EC2 instance with ID i-0a1b2c3d4e5f6g7h8 into your state file as aws_instance.web. After import, run terraform plan—Terraform will show a diff between the imported resource's actual configuration and your incomplete resource block. Copy the missing attributes from the plan output into your .tf file until terraform plan shows no changes. This process is tedious for large infrastructures; tools like terraformer automate bulk imports by querying cloud provider APIs and generating .tf files.
What is the difference between Terraform and Terraform Cloud?
Terraform (open-source CLI) runs locally on your laptop or in CI/CD pipelines, storing state in local files or remote backends you configure (S3, Azure Blob, etc.). Terraform Cloud is HashiCorp's SaaS platform that provides remote state storage, a web UI for plan review, role-based access control, private module registry, and policy-as-code enforcement using Sentinel. Terraform Cloud's free tier supports up to 5 users and is sufficient for small teams. Terraform Enterprise is the self-hosted version of Terraform Cloud, deployed in your own VPC for organizations with data residency requirements (common in Indian BFSI and government sectors under DPDP Act mandates).
How do I handle Terraform upgrades without breaking existing infrastructure?
Terraform releases follow semantic versioning: minor version upgrades (1.6 to 1.7) are backward-compatible, while major version upgrades (0.15 to 1.0) may include breaking changes. Before upgrading, read the changelog on the Terraform GitHub releases page. Test the upgrade in a non-production environment first: copy your Terraform code to a separate directory, run terraform init -upgrade to download the new version, then run terraform plan and verify the plan shows no unexpected changes. If the plan is clean, upgrade production. Provider upgrades follow the same process—pin provider versions in your required_providers block and upgrade deliberately, not automatically.
Can Terraform destroy resources in the wrong order and cause errors?
Terraform's dependency graph ensures resources are destroyed in reverse dependency order: if an EC2 instance depends on a security group, Terraform destroys the instance before the security group. However, implicit dependencies (where Terraform infers the relationship from resource references) sometimes fail to capture real-world constraints. For example, if a Lambda function is triggered by an S3 bucket event but you don't explicitly reference the bucket in the Lambda resource, Terraform might try to destroy the bucket first, causing the Lambda to fail. Use depends_on to declare explicit dependencies when implicit detection is insufficient. The terraform graph command generates a DOT file visualizing the dependency graph, which you can render with Graphviz to debug ordering issues.
Is it safe to run terraform apply in production without reviewing the plan?
No. Always run terraform plan, review the output, and save the plan to a file with terraform plan -out=tfplan. Then apply the saved plan with terraform apply tfplan. This two-step process ensures the changes you reviewed are exactly the changes Terraform executes—if someone else modifies the code or infrastructure between your plan and apply, Terraform will detect the drift and refuse to apply the stale plan. In CI/CD pipelines, configure the pipeline to post the plan output as a pull request comment so reviewers can approve changes before the pipeline runs terraform apply. Aryaka's DevOps team requires two approvals on Terraform pull requests that affect production: one from a peer engineer and one from a team lead.
How do I manage Terraform state for multiple AWS accounts?
Use separate state files per account, stored in separate S3 buckets within each account. Configure the AWS provider with different profiles or assume-role ARNs for each account. A common pattern is to use Terraform workspaces or separate directories for each account, with each workspace/directory pointing to a different backend configuration. For organizations with dozens of AWS accounts (common in enterprises using AWS Organizations), consider Terragrunt—a thin wrapper around Terraform that reduces code duplication by allowing you to define backend configuration and provider settings once, then inherit them across multiple environments. Cisco India's cloud platform team uses Terragrunt to manage 40+ AWS accounts with a single set of Terraform modules.
What is the best way to learn Terraform for someone with a networking background?
Start by provisioning simple AWS networking resources: VPCs, subnets, route tables, internet gateways. These map directly to concepts you know from CCNA (VLANs, routing, NAT). Write Terraform code to replicate a network topology you've built manually in AWS Console or with Cisco routers. Once comfortable with networking resources, add EC2 instances and security groups. Progress to multi-tier architectures with load balancers and auto-scaling groups. The AWS DevOps course at Networkers Home follows this exact progression over four weeks, with daily hands-on labs in our HSR Layout facility. By week four, students with pure networking backgrounds (CCNA/CCNP certified, no prior coding experience) successfully deploy production-grade infrastructure using Terraform modules, remote state, and CI/CD integration.