map variables should support interpolation
albertsj1 opened this issue · 8 comments
I hit this problem while trying to find a solution to using the count parameter to create 3 subnets and then use those 3 subnets for 3 new instances. Mitchell suggested I use a map variable and then a lookup to get the subnet_id. Here's the code I tried.
resource "aws_subnet" "public" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "${concat(lookup(var.vpc_cidr_base, var.aws_region), ".", count.index ,".0/24")}"
availability_zone = "${lookup(concat("aws_region_", var.aws_region), concat("key", count.index))}"
count = 3
}
variable "public_ids" {
default = {
key0 = "${aws_subnet.public.0.id}"
key1 = "${aws_subnet.public.1.id}"
key2 = "${aws_subnet.public.2.id}"
}
}
resource "aws_instance" "nat" {
ami = "${lookup(var.aws_nat_amis, var.aws_region)}"
availability_zone = "${lookup(concat("aws_region_", var.aws_region), concat("key", count.index))}"
instance_type = "t2.micro"
key_name = "${var.aws_key_name}"
security_groups = ["${aws_security_group.nat.id}"]
subnet_id = "${lookup(var.public_ids, concat("key", count.index))}"
associate_public_ip_address = true
source_dest_check = false
count = 3
depends_on = ["aws_subnet.public", "aws_security_group.nat"]
}
The error I received when running 'terraform plan' was:
- Variable 'public_ids': cannot contain interpolations
It was suggested by @mitchellh that I use a variable map to get to the newly created subnet_ids via the lookup function. Is there another way to do this that I'm not seeing?
Besides this not working, this is a really verbose and messy solution. I initially tried to use just a number for the key name, but terraform gave me an error. It seems like key names must start with a letter. This required me to use 'concat' to specify the correct key name for the lookup.
Ideally, I wish I was able to simply define in the aws_instance resource declaration the following:
subnet_id = "${aws_subnet.public.${count.index}.id}"
This would require recursive string interpolation to be added though.
Ah, this isn't quite what I meant. I think there is a better solution to this problem. We're not very interested at this time to support interpolations within variables since then variables also need to be a separate phase of the dependency graph and we don't want to do that yet.
There is another issue (tagged "docs") tracking this. We'll come up with some solution there.
Just wondering what the suggested solution for this is? I am running into the same issue
Can someone please link to the issue mentioned by mitchellh:
There is another issue (tagged "docs") tracking this. We'll come up with some solution there.
I've spent at least 15 minutes looking and have been unable to find a related one having label:documentation
.
I don't know which one @mitchellh was talking about but this looks a lot like #4084 to me.
I posted a workaround there of using a module as a place to stash some data, but I don't think that workaround would work for storing a map as shown in this issue, since modules can only export flat strings.
I have suffered same problem :(
So no insights on this yet? It got me too.
While recursive interpolation and interpolation within variables are still not features, I find the interpolation methods that are available now work well enough to get the job done.
For example, instead of this:
subnet_id = "${aws_subnet.public.${count.index}.id}"
do this:
subnet_id = "${element(aws_subnet.public.*.id, count.index)}"
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.