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

Use of a "set" for containers.env prevents lifecycle ignoring individual environment variables #20663

Open
RussellRollins opened this issue Dec 11, 2024 · 5 comments
Labels
forward/linked persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work service/run upstream-terraform

Comments

@RussellRollins
Copy link

RussellRollins commented Dec 11, 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 & Provider Version(s)

Terraform v1.10.1
on darwin_arm64

  • provider registry.terraform.io/hashicorp/archive v2.7.0
  • provider registry.terraform.io/hashicorp/google v6.13.0

Affected Resource(s)

google_cloud_run_v2_service

Terraform Configuration

resource "google_cloud_run_v2_service" "example" {
  name                = "my-example"
  location            = "europe-west1"
  
  ...

  template {
    
    ...

    containers {
      name  = "example"
      image = "europe-west1-docker.pkg.dev/example/example"

     ...
     
      env {
        name  = "STATIC_FOO"
        value = "example"
      }
      env {
        name = "DYNAMIC_BAR"
        value = "set by outside process"
      }
    }
  }

  lifecycle {
    ignore_changes = [
      template[0].contains[0].env.dynamic_foo,
    ]
  }
}

Debug Output

No response

Expected Behavior

It does not seem like that uncommon of a use case to have some environment variables that are managed by Terraform, and other "dynamic" environment variables managed by another process. Perhaps a common example would be a "RELEASE" environment variable that is being auto-incremented by a continuous deployment process.

To that end, I would like to be able to use lifecycle ignore_changes on my google_cloud_run_v2_job environment.

When the env was retyped from ARRAY to SET in this PR: GoogleCloudPlatform/magic-modules#11199

The suggested workaround is to index by hash:

If you were relying on accessing an individual environment variable by index (for example, google_cloud_run_v2_job.template.containers.0.env.0.name), then that will now need to by hash (for example, google_cloud_run_v2_job.template.containers.0.env.<some-hash>.name).

I would expect to be able to use this method for lifecycle ignores.

Actual Behavior

╷
│ Error: Cannot index a set value
│ 
│   on cloud_run.tf line 128, in resource "google_cloud_run_v2_service" "example":
│  128:       template[0].containers[0].env.dynamic_foo,
│ 
│ Block type "env" is represented by a set of objects, and set elements do not have addressable keys. To find
│ elements matching specific criteria, use a "for" expression with an "if" clause.
╵

It is not possible to lifecycle ignore an item in a set, due to this Terraform issue: hashicorp/terraform#26359

Steps to reproduce

  1. Create google_cloud_run_v2_job with lifecycle ignored environment variable
  2. terraform plan

Important Factoids

No response

References

No response

b/384073894

@github-actions github-actions bot added forward/review In review; remove label to forward service/run labels Dec 11, 2024
@RussellRollins
Copy link
Author

I was able to devise a pretty terrible workaround. By pre-reading the existing job as a data source, and using a dynamic block, I can artificially set DYNAMIC_FOO to its current value, preventing the drift.

data "google_cloud_run_v2_service" "example" {
  name     = "example"
  location = "europe-west1"
}
      dynamic "env" {
        for_each = toset([
          for env in data.google_cloud_run_v2_service.example.template[0].containers[0].env :
          env if contains(["DYNAMIC_FOO"], env.name)
        ])

        content {
          name  = env.value.name
          value = env.value.value
        }
      }

@c2thorn
Copy link
Collaborator

c2thorn commented Dec 13, 2024

It's not apparent to me what we can do about this from the provider code. The lifecycle argument is controlled by core Terraform. Making the field a set is our best known fix for diffs related to the list ordering, which is what #17607 was.

Unless another solution can be found, I'm marking this as blocked by upstream Terraform hashicorp/terraform#26359

@c2thorn c2thorn added upstream-terraform persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work and removed bug forward/review In review; remove label to forward labels Dec 13, 2024
@RussellRollins
Copy link
Author

@c2thorn How about a map like substitutions on google_cloudbuild_trigger? That's a pretty similar use case, a map should be protected from reordering issues, and a map is addressable, so it could be lifecycle ignored.

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudbuild_trigger#substitutions-1

@c2thorn
Copy link
Collaborator

c2thorn commented Dec 13, 2024

@c2thorn How about a map like substitutions on google_cloudbuild_trigger? That's a pretty similar use case, a map should be protected from reordering issues, and a map is addressable, so it could be lifecycle ignored.

registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudbuild_trigger#substitutions-1

If I'm understanding what you mean, you want to represent container.env which is a list/set of objects in the API into a map where the key is the env name and the value would be an object containing the value and valueSource fields?

I suppose that could be done as a new field, with custom expander/flattener logic that translates to and from the API's structure. We normally do not want to deviate from the API's structure where possible, and we would definitely not want to change the original container.env field's structure yet again just to fix this issue.

A new Terraform-only field to workaround this problem could be possible, but very non-standard and would need to be maintained going forward. I'll leave it to the Cloud run service team to determine if this is the route they want to go for this issue.

@RussellRollins
Copy link
Author

If I'm understanding what you mean, you want to represent container.env which is a list/set of objects in the API into a map where the key is the env name and the value would be an object containing the value and valueSource fields?

@c2thorn That's exactly right. I think that would solve both the problem of ordering and addressability; which seems to me like it would make this resource a lot more usable for the end user.

I definitely understand the concern about making the resource more complicated to maintain and would also be fine with any other workaround; I'm just not sure how you'd do it with the current limitations of Terraform itself and my impression from the discussion in that issue is that there isn't an easy fix they can do either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
forward/linked persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work service/run upstream-terraform
Projects
None yet
Development

No branches or pull requests

3 participants