-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
Terraform Core Version
1.11.1
AWS Provider Version
5.90.0
Affected Resource(s)
- aws_s3_bucket_lifecycle_configuration
Expected Behavior
This problem definitely does not exist of 5.80.0, but does on 5.90.0. I haven't bisected to check the middle versions. I believe it is related to all the default value changes recently
Let's say you start with the follow configuration:
resource "aws_s3_bucket" "this" {
bucket = "test-<name>-lifecycle-policy-20250312"
}
resource "aws_s3_bucket_lifecycle_configuration" "this" {
bucket = aws_s3_bucket.this.id
rule {
id = "del asdf1"
status = "Enabled"
filter { # the issue happens even without prefix, keeping it to show how disastrous the result is
prefix = "asdf1"
}
expiration {
days = 1
}
}
rule {
id = "expire delete markers"
status = "Enabled"
expiration {
expired_object_delete_marker = true
}
}
}Now, let's remove the first rule, so that the lifecycle configuration looks like
resource "aws_s3_bucket_lifecycle_configuration" "this" {
bucket = aws_s3_bucket.this.id
rule {
id = "expire delete markers"
status = "Enabled"
expiration {
expired_object_delete_marker = true
}
}
}Here's the output of the apply:
# aws_s3_bucket_lifecycle_configuration.this will be updated in-place
~ resource "aws_s3_bucket_lifecycle_configuration" "this" {
id = "test-purj-lifecycle-policy-20250312"
# (3 unchanged attributes hidden)
~ rule {
~ id = "del asdf1" -> "expire delete markers"
+ prefix = (known after apply)
# (1 unchanged attribute hidden)
~ expiration {
~ expired_object_delete_marker = false -> true
# (1 unchanged attribute hidden)
}
- filter {
- prefix = "asdf1" -> null
}
}
- rule {
- id = "expire delete markers" -> null
- status = "Enabled" -> null
# (1 unchanged attribute hidden)
- expiration {
- days = 0 -> null
- expired_object_delete_marker = true -> null
}
}
}This is a bad change - notice that rule[0] has not been fully cleared out - notably, the expiration.days entry should be nullified (set to 0), but it isn't, meaning the final rule is a garbled combination of the two rules. Applying results in an error, but only after changes have already been made:
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to aws_s3_bucket_lifecycle_configuration.this, provider
│ "provider[\"registry.terraform.io/hashicorp/aws\"]" produced an unexpected new value:
│ .rule[0].expiration[0].expired_object_delete_marker: was cty.True, but now cty.False.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
Indeed, checking the UI, I see
This is an incredibly dangerous change - essentially, we initially set an expiration of 1 day for all objects under a prefix, and now, without asking for it, we've unexpectedly set an expiration of 1 day for the entire bucket, and on top of that, we've completely undone the Delete expired object markers rule, even though we'd expect to have it based on the terraform definition and the rule name. This happened to two of our buckets, and we had to do a sprawling data recovery.
Actual Behavior
Rules should resemble the final state we ask for. Here is the plan from provider version 5.80.0, which is correct (though ultimately having rules blocks indexed by id rather than array index would be ideal for diffs, if possible):
# aws_s3_bucket_lifecycle_configuration.this will be updated in-place
~ resource "aws_s3_bucket_lifecycle_configuration" "this" {
id = "test-purj-lifecycle-policy-20250312"
# (3 unchanged attributes hidden)
~ rule {
~ id = "del asdf1" -> "expire delete markers"
# (2 unchanged attributes hidden)
~ expiration {
~ days = 1 -> 0
~ expired_object_delete_marker = false -> true
# (1 unchanged attribute hidden)
}
~ filter {
- prefix = "asdf1" -> null
# (2 unchanged attributes hidden)
}
}
- rule {
- id = "expire delete markers" -> null
- status = "Enabled" -> null
# (1 unchanged attribute hidden)
- expiration {
- days = 0 -> null
- expired_object_delete_marker = true -> null
# (1 unchanged attribute hidden)
}
- filter {
# (3 unchanged attributes hidden)
}
}
}
Steps to Reproduce
terraform apply
# remove aws_s3_bucket_lifecycle_configuration.this.rules[0]
terraform apply
Would you like to implement a fix?
None



