interview-prep

Crisp answer: State drift is when real infrastructure differs from what Terraform's state file records — usually because someone made a manual change in the console. You detect it with terraform plan and reconcile it either by importing the change into state or by reverting it with apply.

How drift happens:

  1. Manual change in AWS console (adding a tag, changing an instance type)
  2. Another tool modified the resource (CloudFormation, CDK, AWS CLI)
  3. A previous Terraform apply partially completed and left state inconsistent
  4. A resource was deleted outside Terraform

Detecting drift:

terraform plan
# If someone manually added a tag to an EC2 instance:
# ~ resource "aws_instance" "web" {
#     tags = {
#       + "ManualTag" = "AddedByPete"   # in reality but not in config
#     }
#   }
# Plan: 0 to add, 1 to change, 0 to destroy.

The plan shows the diff between the desired config and what Terraform last recorded in state. But Terraform first refreshes state from AWS before comparing — so it picks up the manual change.

terraform apply -refresh-only:

Accept the drift into state without applying your config changes:

terraform apply -refresh-only
# Updates state to match reality — config is not applied
# Use when: someone made a legitimate manual change you want to keep

Reverting drift:

If you want to discard the manual change and restore Terraform's desired config:

terraform apply
# Terraform sees the drift and will override it with your config values

Removing a resource from state (without deleting it):

If someone deleted a resource outside Terraform and you don't want Terraform to recreate it:

terraform state rm aws_instance.old
# Removes from state — Terraform forgets about it, resource stays deleted

Moving resources in state:

After a refactor that renames a resource in config:

# Old config: resource "aws_instance" "web_server"
# New config: resource "aws_instance" "api"

terraform state mv aws_instance.web_server aws_instance.api
# Renames in state — prevents destroy + recreate

The moved block (Terraform 1.1+):

# Declare the rename in config so anyone running plan sees it:
moved {
  from = aws_instance.web_server
  to   = aws_instance.api
}

What to say in the interview:

"State drift happens when someone makes a manual change outside Terraform. Running terraform plan detects it because Terraform refreshes state from AWS first. If the manual change should be kept, I use apply -refresh-only to absorb it into state. If it should be reverted, a normal apply overrides it. For resources that were deleted outside Terraform, I use terraform state rm to remove them from state so Terraform stops trying to manage them. terraform state mv is useful after renaming resources in config to avoid a destroy-and-recreate cycle."


My notes