I keep finding that my state is dirty after a resource is first created - ie, the second terraform apply
results in a “Objects have changed outside of Terraform” warning. I can’t figure out if that’s just expected behaviour and everyone runs terraform apply -refresh-only
all the time, or I’m managing to trigger a bug that it seems like everyone ought to be running into.
Here’s a trivial example:
terraform {
required_version = ">= 0.14.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.74"
}
}
}
provider "aws" {
}
resource "aws_iam_user" "terraformtest" {
name = "terraformuser1"
}
resource "aws_iam_user" "terraformtest2" {
name = "terraformuser2"
tags = {
foo = "bar"
}
}
In the first run, it creates two users (one with tags, one without) :
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_iam_user.terraformtest will be created
+ resource "aws_iam_user" "terraformtest" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "terraformuser1"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# aws_iam_user.terraformtest2 will be created
+ resource "aws_iam_user" "terraformtest2" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "terraformuser2"
+ path = "/"
+ tags = {
+ "foo" = "bar"
}
+ tags_all = {
+ "foo" = "bar"
}
+ unique_id = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_iam_user.terraformtest: Creating...
aws_iam_user.terraformtest2: Creating...
aws_iam_user.terraformtest: Creation complete after 1s [id=terraformuser1]
aws_iam_user.terraformtest2: Creation complete after 1s [id=terraformuser2]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Then if I immediately run terraform apply
again, it claims that terraformuser1 has gained a new (empty) tags attribute.
aws_iam_user.terraformtest: Refreshing state... [id=terraformuser1]
aws_iam_user.terraformtest2: Refreshing state... [id=terraformuser2]
Note: Objects have changed outside of Terraform
Terraform detected the following changes made outside of Terraform since the last "terraform apply":
# aws_iam_user.terraformtest has changed
~ resource "aws_iam_user" "terraformtest" {
id = "terraformuser1"
name = "terraformuser1"
+ tags = {}
# (5 unchanged attributes hidden)
}
Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
No changes. Your infrastructure matches the configuration.
Your configuration already matches the changes detected above. If you'd like to update the Terraform state to match, create and apply a refresh-only plan:
terraform apply -refresh-only
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Refreshing shows that the tags attribute in the state file changed from null
to {}
, and then subsequent runs show a clean state.
Is something weird going on or is this just expected behaviour?