Terraform: Interpolated config keys

Created on 22 May 2015  ยท  7Comments  ยท  Source: hashicorp/terraform

This seems like a not-very-common issue, but when it comes to AWS tags it is... we do a lot of tags where the key is dynamic. I can't figure out a way to do this in Terraform. Any ideas on a proposal to allow this?

core enhancement

Most helpful comment

Thought I'd mention another option, if you needed to combine a number of tags with interpolated keys, zipmap() is great. Construct two lists of the keys and values, then zipmap them together. You can also combine this with the merge() function...

locals {
  keys = [
    "${var.foo}",
    "${var.bar}",
  ]

  values = [
    "foo",
    "bar",
  ]
}

tags = "${zipmap(local.keys, local.values)}"

All 7 comments

This should work:

tags {
    "${foo}" = "bar"
}

Can you test that and report back? Thanks!

Used Terraform v0.5.2:

resource "aws_instance" "node" {
  // ...
  tags {
    "${var.name}" = "bar"
  }
}

Plan output:

  tags.${var.name}:            "" => ""

EC2 tags:
Key: ${var.name}
Value:

It's odd it also cleared the value. But main thing is it does not interpolate the quoted key, which is what I originally tried I thought might work.

Hi @progrium! Sorry for the long silence here.

In the mean time since you filed this, Terraform's support for dynamic maps got a little better. Although the syntax is non-ideal, it's now possible (since 0.7) to express what you wanted to express here using the map function, like this:

  tags = "${map(var.name, "bar")}"

It's also possible to use the merge function to combine several maps, allowing piecemeal construction from a literal map provided as a variable with some additional computed keys using this map function.

We know that the syntax is non-ideal here and plan to address it in future as part of some holistic language improvements, though we've not yet got all the details figured out. Since the requested feature is now supported -- albeit in a non-ideal way for now -- I'm going to close this as part of our effort to close out some older, neglected issues. Once we have some more concrete plans for evolving the configuration language we'll open some new issues/PRs for those.

@apparentlymart - Sorry to dig up an old subject. On the topic of tags interpolations, do you know if there's a way to pass in the tags attribute from an aws_instance data source to a different aws_instance resource?

For example, this can't work:

tags = "${data.aws_instance.instance.tags}"

because it's not a map and that's not how the tags attribute works. I'm not sure if there's some fancy trick to achieve it though. This doesn't work either:

  tags {
    "${data.aws_instance.instance.tags.*.???}" = "${data.aws_instance.instance.tags.*.??}"
  }

I imagine it's just not possible? Thanks!

@artburkart that's a good question... my first thought would've been what you did in your first example here, and indeed that is how it would ideally work but probably there is some silly detail that prevents it from working today. If you're willing to share some more details in a new issue (including the exact error message you got when you tried your first example) I'm happy to look a little deeper and try to understand why this isn't working today and if there's a relatively-easy fix.

Thought I'd mention another option, if you needed to combine a number of tags with interpolated keys, zipmap() is great. Construct two lists of the keys and values, then zipmap them together. You can also combine this with the merge() function...

locals {
  keys = [
    "${var.foo}",
    "${var.bar}",
  ]

  values = [
    "foo",
    "bar",
  ]
}

tags = "${zipmap(local.keys, local.values)}"

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.

Was this page helpful?
0 / 5 - 0 ratings