Quiz: Terraform Deep Dive¶
6 questions
L1 (3 questions)¶
1. You have 3 EC2 instances created with count. You need to rename index 1 without destroying and recreating the other two. What happens if you switch from count to for_each, and how do you migrate safely?
Show answer
Switching from count to for_each changes the resource address from aws_instance.server[0] to aws_instance.server["name"]. Terraform sees every old index-based resource as destroyed and every new key-based resource as created — full replacement. To migrate safely:1. Use 'terraform state mv' to rename each resource from its numeric index to its new map key before applying.
2. Run 'terraform plan' to confirm zero changes after the moves.
3. Apply. This is why for_each is preferred from the start — keys are stable, indices shift when items are removed. *Common mistake:* count creates implicit dependencies on index ordering. Removing index 1 from a list of 3 shifts index 2 to index 1, causing Terraform to destroy and recreate the wrong instance.
2. terraform plan hangs with 'Acquiring state lock'. The lock was created 4 hours ago by a crashed CI job. What is the correct recovery sequence?
Show answer
1. Verify no other apply is actually running (check CI, ask the team).2. Note the Lock ID from the error message.
3. Run 'terraform force-unlock
4. Run 'terraform plan' to confirm state is consistent. Never force-unlock while another operation is genuinely running — two concurrent applies can corrupt state. If unsure, check the DynamoDB lock table (for S3 backend) to see the lock holder details. After recovery, add CI job timeouts and lock-retry logic to prevent recurrence.
3. Your state file in S3 is corrupt and S3 versioning is disabled. You have daily backups in another bucket. Walk through the recovery process.
Show answer
1. Do NOT run terraform apply — it will overwrite what remains.2. Copy the most recent backup to a temporary location.
3. Inspect the backup with 'terraform show' against a local copy.
4. Replace the corrupt state file in S3 with the backup.
5. Run 'terraform plan' — it will show drift for any changes made between the backup time and now.
6. Review the drift carefully: for resources that were created after the backup, either import them or accept they'll be recreated.
7. Apply when satisfied. Then enable S3 versioning and DynamoDB locking immediately. Without versioning, every state write is destructive and unrecoverable.
L2 (3 questions)¶
1. You need to reference an existing S3 bucket that was created manually. When should you use 'terraform import' vs a data source, and what are the long-term implications of each?
Show answer
terraform import brings the resource under Terraform management — future plans will show drift if someone modifies it outside Terraform, and 'terraform destroy' will delete it. A data source is read-only: it queries the bucket's attributes at plan time but never modifies or destroys it. Use import when you want Terraform to own the lifecycle (enforce config, detect drift, control deletion). Use a data source when the resource is managed by another team or process and you just need its attributes (ARN, ID). Importing requires writing a matching resource block; data sources are simpler but give you no drift protection.2. You use ignore_changes on tags because ASG modifies a 'LastModified' tag. A month later, someone manually changes the instance type in the console and terraform plan shows no drift. Why is this dangerous?
Show answer
ignore_changes applies to the entire attribute lifecycle, not just tags. If you specified ignore_changes = [tags], only tags are ignored — instance type drift would still show. But if you used ignore_changes = [tags, instance_type] or the broad ignore_changes = all, Terraform stops tracking those attributes entirely. The danger: real infrastructure drift becomes invisible. The fix: be surgical — only ignore the specific attributes that legitimately change outside Terraform, never use 'all', and pair ignore_changes with external drift detection (AWS Config rules or periodic 'terraform plan' in CI that flags any ignored-attribute drift).3. Two security groups need to reference each other: SG-A allows inbound from SG-B, and SG-B allows inbound from SG-A. Terraform throws a cycle error. How do you break the cycle?