2
votes

Just been trying to use the new terraform aws_route53_resolver_endpoint resource. It takes the subnet ids as a block type list. Unfortunately there appears to be no way to populate this from a list of subnets read from an output variable from the previous step.

Basically I have a set of subnets created using the count on the subnet resources in a previous step. Im trying to use these and setup aws_route53_resolver_endpoint in each of these subnets:

resource "null_resource" "management_subnet_list" {
  count = "${length(var.subnet_ids)}"

  triggers {
    subnet_id = "${element(data.terraform_remote_state.app_network.management_subnet_ids, count.index)}"
  }
}

resource "aws_route53_resolver_endpoint" "dns_endpoint" {
  name               = "${var.environment_name}-${var.network_env}-dns"
  direction          = "OUTBOUND"
  security_group_ids = ["${var.security_groups}"]

  ip_address = "${null_resource.management_subnet_list.*.triggers}"
}

The above when run, results in an error: ip_address: should be a list

If I modify the code as follow:

ip_address = ["${null_resource.management_subnet_list.*.triggers}"]

I get the error: ip_address: attribute supports 2 item as a minimum, config has 1 declared

I can't seem to figure out any other way to create the resource list dynamically from a list of subnets.

Any help will be appreciated.

1
Are you expecting the list of subnets to change often? If so is it just the subnet IDs that will change or also the amount of subnets?ydaetskcoR
Looks like a case for Terraform 0.12's for loops (it's currently in beta).StephenKing
Yes, the list of subnets can vary between 2 or 3. I am managing the creation of on demand vpc's and in each VPC a team can decide to use 2 or three AZ, hence based on the subnets in 2 or 3 AZ I need to create the outbound resolver endpoints. The terraform 0.12 dynamic block with for loop will work but we cant use terraform 0.12 for now.Ali Gardezi
without v0.12, you can work around with this github.com/hashicorp/terraform/issues/…BMW

1 Answers

1
votes

Per the resource reference for aws_route53_resolver_endpoint, the subnet_id in the ip_address block is a single string value.

To specify multiple subnets, you need to have multiple ip_address blocks.

Since you state that you're creating subnets with a count argument, you could potentially reference each individually with the index like: aws_subnet.main[0].id, aws_subnet.main[1].id and so on, each in it's own ip_address block. (or for Terraform 0.11, I think it was "${aws_subnet.main.0.id}".)

However, a better way would be to use the Dynamic Blocks available in Terraform 0.12 +

Dynamic Blocks allow you to create repeatable nested blocks within top-level blocks.(resource, data, provider, and provisioner blocks currently support dynamic blocks).

A dynamic ip_address block within the aws_route53_resolver_endpoint resource could look like:

  dynamic "ip_address" {
    for_each = aws_subnet.main[*].id
    iterator = subnet

    content {
      subnet_id = subnet.value
    }
  }

Which would result in a separate ip_address nested block for each subnet created in the aws_subnet.main resource.

The for_each argument is the complex value to iterate over. It accepts accepts any collection or structural value, typically a list or map with one element per desired nested block.

For complete info on the dynamic nested block expression, see the Terraform documentation at: https://www.terraform.io/docs/language/expressions/dynamic-blocks.html