Day 34: Mastering Terraform Drift

Adrian Rubico

|

Jun 6, 2025

12:14 AM GMT+8

Day 34: Mastering Terraform Drift

Today, we dive into the concept of Terraform Drift. Drift occurs when infrastructure managed by Terraform changes outside of its control. Understanding how to detect and fix drift is critical for maintaining the accuracy and reliability of your infrastructure as code.

What is Terraform Drift?

Terraform Drift refers to any change made to infrastructure resources that is not captured or tracked in the Terraform configuration. This means what’s declared in your .tf files no longer matches the real-world deployed resources.

Why the Drift Happens?

Drift can occurs for several reasons:

  • Manual changes made via cloud portals or CLI tools
  • Automated scripts or pipelines altering infrastructure
  • Resource behaviors or third-party tools modifying settings

Such untracked changes introduce inconsistencies that can lead to errors or unexpected behavior in future Terraform runs.

How to Detect Terraform Drift?

Terraform provides a simple command to detect drift:

bash
terraform plan

This command compares the current state file with the actual deployed infrastructure. Any differences will be highlighted in the output.

To update the state file without modifying infrastructure, you can run:

bash
terraform apply -refresh-only

This syncs the state file with real-world changes, allowing us to regain alignment.

Task

Let’s walk through practical drift detection and resolution steps.

Step 1: Clone the repository and navigate to the drift directory

bash
git clone https://github.com/git-adrianrubico/learn-terraform
cd learn-terraform/06-Drift

Step 2: Review the existing main.tf

hcl
resource "azurerm_resource_group" "rg-example" {
  name     = "rg-example"
  location = var.azregion
  
  tags = {
    environment = local.env
  }
}

resource "azurerm_storage_account" "sa-example" {
  name                     = "stgacsample${local.env}01"
  resource_group_name      = azurerm_resource_group.rg-example.name
  location                 = azurerm_resource_group.rg-example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  
  tags = {
    environment = azurerm_resource_group.rg-example.location
  }
}

Apply to the infrastructure:

bash
terraform init
terraform plan
terraform apply

Step 3: Simulate Drift

1️⃣ Open The Azure Portal.

2️⃣ Navigate to the Storage Account created by Terraform.

3️⃣ Change Replication Type from LRS to GRS manually.

Change Azure Storage Account Replication Type from LRS to GRS.

Step 4: Detect the Drift

Back to your terminal:

bash
terraform plan

Terraform will show a drift has occurred in the account_replication_type.

Shows terraform drift output.

Step 5: Sync Drifted State

To update your Terraform state without modifying infrastructure:

bash
terraform apply -refresh-only
Applied terraform apply -refresh-only

Next, update the main.tf to redirect the new replication type:

account_replication_type = "GRS"

Verify the terraform state using terraform plan command:

Synced with terraform main.tf file and statefile

Terraform Import

Terraform Import is used to bring existing infrastructure resources, created outside of Terraform, into Terraform's state file. This allows you to manage those resources without recreating them. It is especially useful when working with legacy resources or manual changes.

Step 1: Create the Azure Key Vault manually in the Azure Portal

Create Azure Key Vault via Azure Portal.

Step 2: Add the resource block in main.tf

hcl
data "azurerm_client_config" "current" {}

resource "azurerm_key_vault" "kv-example" {
  name                      = "kv-example"
  location                  = azurerm_resource_group.rg-example.location
  resource_group_name       = azurerm_resource_group.rg-example.name
  tenant_id                 = data.azurerm_client_config.current.tenant_id
  enable_rbac_authorization = true
  sku_name                  = "standard"
}

Step 3: Get the Resource ID and Run the import command

First, we need to get the Resource ID of Azure Key Vault under Properties

Get Resource ID of Azure Key Vault.

Once you locate the Resource ID, replace <RESOURCE_ID> with your actual Resource ID.with your actual IDs.

bash
terraform import azurerm_key_vault.kv-example <RESOURCE_ID>
Run Terraform import command for Azure Key Vault

Step 4: Verify the import

This ensures your configuration matches the imported resource.

bash
terraform plan
Verify the terraform import.

Step 5: Apply to finalize

This synchronizes Terraform’s state and ensures consistency moving forward.

bash
terraform apply

Summary of terraform apply -refresh-only and terraform import

The following table provides a quick comparison and summary of two important Terraform commands used in managing and syncing infrastructure state.

CommandPurposeWhen to Use
terraform apply -refresh-onlySyncs Terraform state file with real-world infrastructureWhen external changes are made manually (e.g. via portal, cli)
terraform importBrings existing infrastructure under Terraform managementWhen a resource was created outside of Terraform

Wrapping Up

In this article, we examined Terraform drift, detailing its nature, common causes, and methods for detection and remediation. We explored the terraform apply -refresh-only command to sync the state file with real-world infrastructure and used terraform import to bring existing resources under Terraform management.

Understanding and managing drift is essential for maintaining consistency, especially in teams or environments where manual changes can occur outside of Terraform.

In the next blog, we will dive into Terraform Modules, a powerful feature for organizing and reusing your Terraform configurations efficiently.

Discussion