Terraform ignore_changes: Controlling Drift Detection in Lifecycle Blocks
The ignore_changes argument in a Terraform lifecycle block tells Terraform to skip tracking specific resource attributes after initial creation, preventing unnecessary updates when those values drift or are managed externally.
The hashicorp/terraform repository provides this mechanism to give practitioners fine-grained control over resource drift detection. By excluding designated attributes from comparison logic, ignore_changes eliminates noise from volatile fields or manual console modifications while preserving your originally configured values in state.
What Is Terraform ignore_changes?
ignore_changes is a meta-argument defined inside a resource’s lifecycle block that controls how Terraform detects configuration drift. During the first apply, Terraform records the values supplied in your configuration. On subsequent runs, Terraform normally compares these desired values against actual infrastructure state and proposes changes for any differences.
When you specify ignore_changes, Terraform excludes the listed attributes from this comparison. Any drift in these fields is silently accepted, and Terraform retains the original configured value rather than forcing an update. This is particularly useful for attributes managed outside of Terraform—such as tags added manually in a cloud console—or volatile properties like database endpoints that providers update automatically.
How ignore_changes Works Under the Hood
Runtime Behavior in node_resource_abstract_instance.go
During the planning phase, Terraform’s diff computation logic resides in internal/terraform/node_resource_abstract_instance.go. Here, the system identifies attributes listed in ignore_changes and marks them for exclusion from the diff. According to the source code, these ignored values are then stored in the resource’s planned state to preserve the original configuration, ensuring subsequent plans continue to treat them as unchanged.
Validation Logic in resource.go and node_resource_validate.go
Before applying any lifecycle rules, Terraform parses the configuration in internal/configs/resource.go, which validates that ignore_changes contains either a list of relative attribute traversals or the literal string all. Further validation occurs in internal/terraform/node_resource_validate.go, where Terraform checks for redundant entries and ensures you are not attempting to ignore computed-only attributes—those set solely by the provider with no user-supplied value.
Supported Syntax Patterns
Ignoring Specific Attributes
Pass a list of attribute names as strings to ignore particular fields while continuing to track all others:
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
lifecycle {
ignore_changes = ["tags"]
}
}
You can ignore multiple attributes by adding elements to the list:
resource "azurerm_storage_account" "demo" {
name = "demostorageacct"
resource_group_name = azurerm_resource_group.demo.name
location = azurerm_resource_group.demo.location
account_tier = "Standard"
account_replication_type = "LRS"
lifecycle {
ignore_changes = ["account_kind", "access_tier"]
}
}
Ignoring All Attributes with the all Keyword
Use the special keyword all to instruct Terraform to ignore every attribute of the resource. Use this with extreme caution, as it effectively disables drift detection for the entire resource:
resource "google_compute_instance" "vm" {
name = "my-vm"
machine_type = "e2-medium"
zone = "us-central1-a"
lifecycle {
ignore_changes = all
}
}
Validation Rules and Restrictions
The Terraform source code enforces strict validation rules for ignore_changes to prevent configuration errors:
- No wildcard syntax: Attempting to use
["*"]is invalid and raises the diagnostic “Invalid ignore_changes wildcard.” as enforced ininternal/configs/resource.go. - Computed-only protection: You cannot ignore attributes that are computed-only (set entirely by the provider). Attempts generate a “Redundant ignore_changes element” warning because there is no user-supplied value to retain.
- Relative traversals only: All entries must be valid relative attribute references within the resource schema.
Practical Terraform ignore_changes Examples
Example 1: Ignoring Externally Managed Tags
Prevent Terraform from reverting manual tag changes made in the AWS console:
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t3.medium"
lifecycle {
ignore_changes = ["tags"]
}
}
Example 2: Ignoring Volatile Provider-Managed Fields
Skip updates to fields that the cloud provider modifies automatically, such as storage account kinds that change based on usage patterns:
resource "azurerm_storage_account" "data" {
name = "examplestorage"
resource_group_name = azurerm_resource_group.main.name
location = "East US"
account_tier = "Standard"
account_replication_type = "GRS"
lifecycle {
ignore_changes = ["account_kind", "access_tier"]
}
}
Example 3: Freeze Entire Resource State
Use ignore_changes = all to prevent any modifications to a legacy resource you are migrating out of Terraform management:
resource "google_compute_instance" "legacy" {
name = "legacy-server"
machine_type = "n1-standard-4"
zone = "us-west1-a"
lifecycle {
ignore_changes = all
}
}
Summary
- Terraform ignore_changes suppresses drift detection for specified resource attributes after initial creation.
- The argument is parsed and validated in
internal/configs/resource.goandinternal/terraform/node_resource_validate.go. - During planning,
internal/terraform/node_resource_abstract_instance.goexcludes ignored attributes from the diff and preserves original values in the planned state. - Valid forms include a list of attribute names (
["tags", "instance_type"]) or the keywordall. - You cannot ignore computed-only attributes or use wildcard syntax like
["*"].
Frequently Asked Questions
Can I use wildcards like ["*"] in ignore_changes?
No. Terraform explicitly rejects wildcard syntax in ignore_changes. According to the validation logic in internal/configs/resource.go, using ["*"] generates an “Invalid ignore_changes wildcard” error. You must explicitly list each attribute name or use the all keyword to ignore every attribute.
What happens if I try to ignore a computed-only attribute?
Terraform emits a “Redundant ignore_changes element” warning and ignores the directive. As implemented in internal/terraform/node_resource_validate.go, computed-only attributes (those set solely by the provider) cannot be ignored because there is no user-configured value to preserve.
Does ignore_changes affect the initial resource creation?
No. ignore_changes only affects drift detection on subsequent plan and apply operations after the resource exists in state. During the initial creation, Terraform uses your configured values exactly as written, regardless of what is listed in the lifecycle block.
When should I use ignore_changes = all versus specific attributes?
Use ignore_changes = all only when you want to completely detach a resource from Terraform’s drift detection, such as during resource import migrations or when handing management to external systems. For day-to-day operations, prefer listing specific attributes to ignore only volatile or externally-managed fields while keeping Terraform’s protection for your critical configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s https://instagit.com/install.md