When working with terraform, you may run into the error “objects have changed outside of Terraform”. This error means that your terraform state and application are out of sync. Making changes outside of terraform may occur in instances where you need to make immediate changes to problematic services or applications.
In this tutorial we will show how to edit your terraform code to reflect the new changes that you made outside of terraform.
How terraform tracks resources in terraform state
Information about your infrastructure is stored in a terraform.tfstate file either locally or remote. The terraform state file becomes available once you perform your first “terraform apply”.
The state file helps these main functions:
- Map resources in the client configuration with production resources
- track dependencies and their order
- collaboration among team members
In this example I will be deploying a security group in azure that looks like this:
resource "azurerm_network_security_group" "homelabsg" {
name = "homelab-security-group"
location = azurerm_resource_group.homelabrg.location
resource_group_name = azurerm_resource_group.homelabrg.name
security_rule {
name = "allow rdp inbound"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
Once applied and we run a “terraform state show azurerm_network_security_group” then we will be outputted the following format representing the security group from the tfstate file.
Terraform refresh only: Making changes outside of terraform
When you make changes outside of terraform, you create what is called drift. Drift means that your tfstate is different from the provisioned resources that were originally deployed.
We made a change to the azure security group from the azure portal. The rule was changed to deny traffic from 172.20.40.1 to rdp.
Once changes are made outside of azure, we run a “terraform plan -refresh-only”. This outputs the changes that are present outside of the state file. The red lines indicate whats being removed and the green + signs indicate what is being created.
For resources that can be updated we will need to update the attributes to reflect the new changes.
resource "azurerm_network_security_group" "homelabsg" {
name = "homelab-security-group"
location = azurerm_resource_group.homelabrg.location
resource_group_name = azurerm_resource_group.homelabrg.name
security_rule {
name = "allow rdp inbound"
priority = 100
direction = "Inbound"
access = "Deny"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "172.20.40.1"
destination_address_prefix = "*"
}
}
To fix objects have changed outside of terraform run a “terraform apply” to update the tfstate with the correct resource configuration. For resources that cannot be updated, terraform will destroy the original before recreate it.
Conclusion
When objects have changed outside of terraform, managing your environment becomes difficult. Your source of truth should always be your terraform configuration. To help manage your drift you should always keep these commands handy:
- Terraform –refresh-only to detect changes in your environment without your infrastructure being changed.
- Terraform plan to make sure what is being updated or configured is appropriate.