Ignore changes to an environment variable in a k8s deployment

I have a TF resource defined as follows (example is simplified):

resource "kubernetes_deployment" "this" {
  # [... some stuff removed for simplification]
  spec {
    replicas = 3

    # [... more stuff removed]

    template {
      metadata {
        # [... removed]
      }

      spec {
        container {
          name  = local.name
          image = "some_image:some_tag"

          env {
            name  = "SOME_ENV_VARIABLE_1"
            value = "SOME_VALUE"
          }

          env {
            name  = "SOME_ENV_VARIABLE_2"
            value = "SOME_OTHER_VALUE"
          }
[...]
}

When I run the plan for this I get something like the following:

Terraform will perform the following actions:

  # module.my_module.kubernetes_deployment.this will be updated in-place
  ~ resource "kubernetes_deployment" "this" {
        id               = "some/id"
        # (1 unchanged attribute hidden)

      ~ spec {
            # (5 unchanged attributes hidden)

          ~ template {
              ~ spec {
                    # (13 unchanged attributes hidden)

                  ~ container {

                        # [some stuff removed here that isn't important]

                        # (8 unchanged attributes hidden)

                      - env {
                          - name  = "SOME_OTHER_DYNAMICALLY_CREATED_ENV_VARIABLE" -> null
                          - value = "some_value" -> null
                        }

                        # (15 unchanged blocks hidden)
                    }

I’ve been trying to figure out how I can instruct TF to ignore changes to an environment variable named SOME_OTHER_DYNAMICALLY_CREATED_ENV_VARIABLE but not other variables.

The only solution I’ve thought of would be to actually define the SOME_OTHER_DYNAMICALLY_CREATED_ENV_VARIABLE environment variable in my resource as the first env block and then add spec[0].template[0].spec[0].container[0].env[0] to my lifecycle.ignore_changes list.

But that is a very brittle solution to this if somebody accidentally adds an env block before that one.

Is there any way to specify that this environment variable specifically should be ignored?

With this provider schema shaped in this way, unfortunately what you thought of is the best we can do today. The provider schema says that blocks of this type are to be identified by their position in a resulting list and so that’s what ignore_changes wants to see.

Hopefully a comment left adjacent to the relevant block would at least give a future maintainer a hint about what they shouldn’t change. If you want to make it more resilient then this could be something to check in a policy rule enforced between plan and apply (using a tool such as Open Policy Agent) that says that this particular environment variable must always be the first item in this list.

To get the ability you wanted here the provider would need to define this as being a map rather than a list, and then the elements could each be identified by name instead of by index. But that would be a breaking change to the provider, so I don’t know if the provider team would consider it.

1 Like

Thanks for the reply. Good to get confirmation that I’m not missing anything obvious.

I did discover that the operator causing this is actually configurable and instead of it setting an environment variable, I can configure it to set an annotation instead. That would be trivial to add to the ignore_changes list.