Terraform has become the go-to Infrastructure as Code (IaC) tool for DevOps engineers, and for good reason. It’s declarative, cloud-agnostic, and integrates well into CI/CD workflows. But anyone who’s worked with it long enough knows: Terraform can bite you when you least expect it.
1. State File Mismanagement
What Happens:
The Terraform state file tracks the current status of your infrastructure. If it’s lost, corrupted, or not managed properly, you risk inconsistencies—or worse, complete infra recreation.
Avoid It:
- Always use remote state backends like AWS S3 with locking via DynamoDB.
- Encrypt state at rest and in transit.
- Enable versioning for recovery.
2. create_before_destroy and prevent_destroy Misuse
What Happens:
Terraform might destroy a resource before creating a replacement. This could mean downtime, lost data, or broken dependencies.
Avoid It:
- Use
create_before_destroy = truein lifecycle blocks for resources like load balancers and DNS records. - Add
prevent_destroy = trueon critical infrastructure components like databases and S3 buckets.
hclCopyEditlifecycle {
create_before_destroy = true
prevent_destroy = true
}
3. Misusing count or for_each
What Happens:
Changing the order or logic behind count can lead to recreation of resources, even when unnecessary.
Avoid It:
- Prefer
for_eachwhen dealing with key-based maps to retain resource identity. - Never tie
countvalues to external resources that might fluctuate unexpectedly.
4. Dynamic Blocks Confusion
What Happens:
Dynamic blocks are great for conditional logic, but when misused, they create confusing configs and unexpected diffs.
Avoid It:
- Keep dynamic blocks minimal and readable.
- Test with
terraform planfrequently. - Use locals for complex expressions to avoid repetition.
5. Provider Version Drift
What Happens:
If you don’t lock your provider versions, newer releases might introduce breaking changes or deprecations without warning.
Avoid It:
- Pin provider versions in your Terraform configuration:
hclCopyEditterraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
6. Insecure Secrets Handling
What Happens:
Hardcoding secrets in .tf files or using variables without care can expose sensitive credentials.
Avoid It:
- Use environment variables or secret managers (e.g., AWS Secrets Manager, Vault).
- Never commit
.tfstateor.terraformfolders to version control. - Redact outputs with
sensitive = true.
hclCopyEditoutput "db_password" {
value = var.db_password
sensitive = true
}
7. Ignoring Infrastructure Drift
What Happens:
Manual changes to infra outside of Terraform create drift—Terraform thinks your infra is in one state, but reality says otherwise.
Avoid It:
- Schedule regular
terraform planand drift detection in CI/CD. - Use tools like
InfracostandDriftctlto analyze state vs reality. - Train teams to follow a “no manual changes” policy.
Terraform is powerful—but with great power comes great responsibility (and the occasional panic moment).
By understanding these gotchas and implementing guardrails, you’ll save yourself from headaches, minimize downtime, and make your IaC truly reliable.