terraform-provider-kubernetes: Variables not correctly interpreted when configuring labels on a namespace

When working with the kubernetes namespace resource, I ran into an issue where it seems that variables that are fetched from remote state are not interpreted and seem to be treated as literals. Only the labels seem to be affected, the name property does not have an issue.

Terraform Version

This is with terraform version 0.10-rc1

Affected Resource(s)

The labels within the kubernetes namespace

Terraform Configuration Files

data "terraform_remote_state" "globalvars" {
  backend = "local"
  config {
    path = "path/to/terraform.tfstate"
  }
}
resource "kubernetes_namespace" "k8s_namespace" {
  metadata {
    labels {
      application = "${data.terraform_remote_state.globalvars.application_name}"
    }
    name = "${data.terraform_remote_state.globalvars.application_name}"
  }
}

The remote state is filled through:

output "application_name" { value = "myapp" }

Debug Output

module.kubernetes-namespace.kubernetes_namespace.k8s_namespace: metadata.0.labels (“${data.terraform_remote_state.globalvars.application_name}”) a valid label must be an empty string or consist of alphanumeric characters, ‘-’, ‘’ or ‘.’, and must start and end with an alphanumeric character (e.g. ‘MyValue’, or ‘my_value’, or ‘12345’, regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9.]*)?[A-Za-z0-9])?’)

Expected Behavior

Label should be set to application = myapp

Actual Behavior

Get an error stating I try to create an invalid label (see debug output)

Steps to Reproduce

First run code that outputs variable in a state file Then create a tf file that includes the kubernetes namespace as a module

Important Factoids

If you replace the variable with a local one (${var.application_name}) then there is no issue. If you set the label to a hardcoded value, you’ll see it works with interpolation for name. I also tried to wrap the variable in a function (substr/length/chomp) but the error remains. Could it be that it doesn’t recognize the remote state variable as a valid variable?

References

The globalvars trick as described in https://github.com/hashicorp/terraform/issues/5480 is used here.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 5
  • Comments: 16 (4 by maintainers)

Most upvoted comments

@protomonk this problem should be resolved with the latest version of Terraform and of this provider (see #491 )

@pdecat @alexsomesan it’s still blocking for us too. I just tested if this problem is resolved with Terraform 0.12 but sadly not. In #357 you said that ValidateFunc on map attributes is in fact available and working, but on my test it doesn’t seem to work.

I created a minimal terraform provider to test if interpolation is working with ValidateFunc: https://github.com/pablo-ruth/terraform-provider-example

There is only one resource type “example_server” with two arguments: “address” of type string and “tags” of type map. Both have a ValidateFunc defined which expose values of each key as seen from inside.

With this simple main.tf, I test interpolation of attributes and variables:

resource "example_server" "my-server" {
  address = "127.0.0.1"
}

resource "example_server" "my-server2" {
  address = example_server.my-server.address

  tags = {
    env = "development"
    name = example_server.my-server.address
    var = var.foo
  }
}

variable "foo" {
  default = "bar"
}

And the plan output:

Terraform will perform the following actions:

  # example_server.my-server will be created
  + resource "example_server" "my-server" {
      + address = "127.0.0.1"
      + id      = (known after apply)
    }

  # example_server.my-server2 will be created
  + resource "example_server" "my-server2" {
      + address = "127.0.0.1"
      + id      = (known after apply)
      + tags    = {
          + "env"  = "development"
          + "name" = "127.0.0.1"
          + "var"  = "bar"
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Warning: simple -> value: 127.0.0.1

  on main.tf line 1, in resource "example_server" "my-server":
   1: resource "example_server" "my-server" {



Warning: complex -> key: env - value: development

  on main.tf line 5, in resource "example_server" "my-server2":
   5: resource "example_server" "my-server2" {



Warning: complex -> key: name - value: 74D93920-ED26-11E3-AC10-0800200C9A66

  on main.tf line 5, in resource "example_server" "my-server2":
   5: resource "example_server" "my-server2" {



Warning: complex -> key: var - value: 74D93920-ED26-11E3-AC10-0800200C9A66

  on main.tf line 5, in resource "example_server" "my-server2":
   5: resource "example_server" "my-server2" {

So it seems that ValidateFunc doesn’t support interpolation on maps… or I am missing something…

@radeksimko: I believe this is not an upstream bug, but at bug in the terraform-provider-kubernetes. The hashicorp/terraform#5480 issue is only an enhancement discussion about propagating variables, or being able to provide global variables.

This issue is triggered when a module output is given as input to the configmap resource:

provider "kubernetes" {}

resource "local_file" "tmpfile" {
  filename = "/tmp/resource.txt"
  content = "foo-bar"
}

data "local_file" "datafile" {
  filename = "/tmp/resource.txt"
  depends_on = ["local_file.tmpfile"]
}

resource "local_file" "this_works" {
  filename = "/tmp/resource2.txt"
  content = "${data.local_file.datafile.content}"
}

resource "kubernetes_config_map" "this_fails" {
  "metadata" {
    name = "test"
    labels {
      fromfile = "${data.local_file.datafile.content}"
    }
  }
}

It looks like variables that should have the computed state, as the actual value cannot be known before the apply phase.

What triggered this bug for me was the attempt to label a configmap with a value from the output of google_pubsub_subscription resource.

I hope you can remove the upstream-terraform label and re-investigate whether this is caused by a local bug/design flaw?