Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

google_storage_bucket with two lifecycle rules with different values for no_age always reports change #17314

Comments

@kustodian
Copy link

kustodian commented Feb 19, 2024

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request.
  • Please do not leave +1 or me too comments, they generate extra noise for issue followers and do not help prioritize the request.
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment.
  • If an issue is assigned to a user, that user is claiming responsibility for the issue.
  • Customers working with a Google Technical Account Manager or Customer Engineer can ask them to reach out internally
    to expedite investigation and resolution of this issue.

Terraform Version

Terraform v0.15.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/google v5.16.0

Affected Resource(s)

google_storage_bucket

Terraform Configuration

If we create a bucket with two lifecycle rules, but with those rules having different values for no_age likes this:

resource "google_storage_bucket" "buckets-test2" {
  name     = "bucket-lifecycle-testing-3"
  location = "europe-west1"

  lifecycle_rule {
    action {
      type = "Delete"
    }
    condition {
      days_since_noncurrent_time = 10
      no_age                     = true
    }
  }

  lifecycle_rule {
    action {
      type = "Delete"
    }
    condition {
      age    = 30
      no_age = false
    }
  }
}

Debug Output

Terraform will always report a change like this:

➜  bucket-lifecycle-test git:(master) ✗ terraform apply         
google_storage_bucket.buckets-test2: Refreshing state... [id=bucket-lifecycle-testing-3]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # google_storage_bucket.buckets-test2 has been changed
  ~ resource "google_storage_bucket" "buckets-test2" {
        id                          = "bucket-lifecycle-testing-3"
        name                        = "bucket-lifecycle-testing-3"
        # (14 unchanged attributes hidden)

      ~ lifecycle_rule {

          - condition {
              - age                        = 30 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 0 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = false -> null
              - num_newer_versions         = 0 -> null
            }
          + condition {
              + age                        = 30
              + days_since_custom_time     = 0
              + days_since_noncurrent_time = 0
              + matches_prefix             = []
              + matches_storage_class      = []
              + matches_suffix             = []
              + no_age                     = true
              + num_newer_versions         = 0
              + with_state                 = "ANY"
            }
            # (1 unchanged block hidden)
        }
        # (1 unchanged block 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.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # google_storage_bucket.buckets-test2 will be updated in-place
  ~ resource "google_storage_bucket" "buckets-test2" {
        id                          = "bucket-lifecycle-testing-3"
        name                        = "bucket-lifecycle-testing-3"
        # (14 unchanged attributes hidden)

      ~ lifecycle_rule {

          - condition {
              - age                        = 30 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 0 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = true -> null
              - num_newer_versions         = 0 -> null
              - with_state                 = "ANY" -> null
            }
          + condition {
              + age                   = 30
              + matches_prefix        = []
              + matches_storage_class = []
              + matches_suffix        = []
              + no_age                = false
              + with_state            = (known after apply)
            }
            # (1 unchanged block hidden)
        }
        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 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

google_storage_bucket.buckets-test2: Modifying... [id=bucket-lifecycle-testing-3]
google_storage_bucket.buckets-test2: Modifications complete after 1s [id=bucket-lifecycle-testing-3]

Expected Behavior

Terraform shouldn't report any changes outside of TF or direct changes.

Actual Behavior

Terraform reports changes, but what's even more interesting is that it also reports changes outside of Terraform, which is odd because it reports the same changes as the real change.

If we change no_age = false in the first lifecycle rule then all works fine, except that there is something odd as well with TF reporting changes outside TF which I'll explain further.

Steps to reproduce

Just run terraform apply of the code above multiple times (change bucket name because those are globally unique).

Important Factoids

If in the resource above we set no_age = false and run terraform apply, TF reports changes both outside and proper change, then I run terraform apply again and TF now reports just the change outside TF, then if I run terraform apply for the third time, then TF doesn't report any changes. This is also a bug.

Here is the output of three consecutive terraform apply before changing no_age = false in the first lifecycle rule above:

➜  bucket-lifecycle-test git:(master) ✗ terraform apply         
google_storage_bucket.buckets-test2: Refreshing state... [id=bucket-lifecycle-testing-3]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # google_storage_bucket.buckets-test2 has been changed
  ~ resource "google_storage_bucket" "buckets-test2" {
        id                          = "bucket-lifecycle-testing-3"
        name                        = "bucket-lifecycle-testing-3"
        # (14 unchanged attributes hidden)

      ~ lifecycle_rule {

          - condition {
              - age                        = 30 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 0 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = false -> null
              - num_newer_versions         = 0 -> null
            }
          + condition {
              + age                        = 30
              + days_since_custom_time     = 0
              + days_since_noncurrent_time = 0
              + matches_prefix             = []
              + matches_storage_class      = []
              + matches_suffix             = []
              + no_age                     = true
              + num_newer_versions         = 0
              + with_state                 = "ANY"
            }
            # (1 unchanged block hidden)
        }
        # (1 unchanged block 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.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # google_storage_bucket.buckets-test2 will be updated in-place
  ~ resource "google_storage_bucket" "buckets-test2" {
        id                          = "bucket-lifecycle-testing-3"
        name                        = "bucket-lifecycle-testing-3"
        # (14 unchanged attributes hidden)

      ~ lifecycle_rule {

          - condition {
              - age                        = 0 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 10 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = true -> null
              - num_newer_versions         = 0 -> null
              - with_state                 = "ANY" -> null
            }
          + condition {
              + days_since_noncurrent_time = 10
              + matches_prefix             = []
              + matches_storage_class      = []
              + matches_suffix             = []
              + no_age                     = false
              + with_state                 = (known after apply)
            }
            # (1 unchanged block hidden)
        }
      ~ lifecycle_rule {

          - condition {
              - age                        = 30 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 0 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = true -> null
              - num_newer_versions         = 0 -> null
              - with_state                 = "ANY" -> null
            }
          + condition {
              + age                   = 30
              + matches_prefix        = []
              + matches_storage_class = []
              + matches_suffix        = []
              + no_age                = false
              + with_state            = (known after apply)
            }
            # (1 unchanged block hidden)
        }
    }

Plan: 0 to add, 1 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

google_storage_bucket.buckets-test2: Modifying... [id=bucket-lifecycle-testing-3]
google_storage_bucket.buckets-test2: Modifications complete after 0s [id=bucket-lifecycle-testing-3]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
➜  bucket-lifecycle-test git:(master) ✗ terraform apply
google_storage_bucket.buckets-test2: Refreshing state... [id=bucket-lifecycle-testing-3]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # google_storage_bucket.buckets-test2 has been changed
  ~ resource "google_storage_bucket" "buckets-test2" {
        id                          = "bucket-lifecycle-testing-3"
        name                        = "bucket-lifecycle-testing-3"
        # (14 unchanged attributes hidden)

      ~ lifecycle_rule {

          - condition {
              - age                        = 0 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 10 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = false -> null
              - num_newer_versions         = 0 -> null
            }
          + condition {
              + age                        = 0
              + days_since_custom_time     = 0
              + days_since_noncurrent_time = 10
              + matches_prefix             = []
              + matches_storage_class      = []
              + matches_suffix             = []
              + no_age                     = false
              + num_newer_versions         = 0
              + with_state                 = "ANY"
            }
            # (1 unchanged block hidden)
        }
      ~ lifecycle_rule {

          - condition {
              - age                        = 30 -> null
              - days_since_custom_time     = 0 -> null
              - days_since_noncurrent_time = 0 -> null
              - matches_prefix             = [] -> null
              - matches_storage_class      = [] -> null
              - matches_suffix             = [] -> null
              - no_age                     = false -> null
              - num_newer_versions         = 0 -> null
            }
          + condition {
              + age                        = 30
              + days_since_custom_time     = 0
              + days_since_noncurrent_time = 0
              + matches_prefix             = []
              + matches_storage_class      = []
              + matches_suffix             = []
              + no_age                     = false
              + num_newer_versions         = 0
              + with_state                 = "ANY"
            }
            # (1 unchanged block 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.
➜  bucket-lifecycle-test git:(master) ✗ terraform apply
google_storage_bucket.buckets-test2: Refreshing state... [id=bucket-lifecycle-testing-3]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

These are two bugs, but I guess the core of the problem is the same.

b/327610882

@c2thorn c2thorn added the bug label Feb 20, 2024
@c2thorn c2thorn self-assigned this Feb 20, 2024
@c2thorn
Copy link
Collaborator

c2thorn commented Feb 23, 2024

Confirmed bug. The logic for setting no_age always refers to the first condition entry: https://github.com/hashicorp/terraform-provider-google/blob/main/google/services/storage/resource_storage_bucket.go#L1284

@roaks3
Copy link
Collaborator

roaks3 commented Feb 29, 2024

It looks like the initial ticket did not include the affected resources, but they were edited in later. Should be ready to forward now.

@kustodian
Copy link
Author

The reason why there was no affecter resource and many other things is because from the Google Terraform provider page I clicked on the file a bug link, which just opens an empty new bug page, but doesn't use the Bug template.

Could you see with Hashicorp to include replace that URL with the bug URL: https://github.com/hashicorp/terraform-provider-google/issues/new?assignees=&labels=bug&projects=&template=00_bug.yml

@roaks3
Copy link
Collaborator

roaks3 commented Mar 6, 2024

Thanks @kustodian for pointing that out. I've filed #17502 to have that fixed.

Copy link

github-actions bot commented Apr 8, 2024

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.