Search code examples
amazon-web-servicesterraformterraform-template-file

Inappropriate value - string expected - when used with count+ index


I am stuck with the below problem (terraform v0.12.8);

Where i am trying to use below as my module code and passing them to below resource;

module "nat_gateway" {
    source           = "../providers/aws/network/nat_gw/"
    total_nat_gws    = "${length(var.availability_zones)}"
    eip_id           = "${module.eip.*.eip_id}"
    target_subnet_id = "${module.public_subnet.*.subnet_id}"
    nat_gw_name_tag  = "NAT-${var.stack_name}"
}
resource "aws_nat_gateway" "nat_gw" {
    count         = "${var.total_nat_gws}"
    allocation_id = "${element("${var.eip_id}", count.index)}"
    subnet_id     = "${element("${var.target_subnet_id}", count.index)}"

    tags = {
        Name = "${var.nat_gw_name_tag}"
    }
}

I expected, it would create multiple NAT gateways with the provided multiple EIP's and subnet's. But fails with below error;

Error: Incorrect attribute value type

  on ../providers/aws/network/nat_gw/nat_gateway.tf line 12, in resource "aws_nat_gateway" "nat_gw":
  12:     allocation_id = "${element("${var.eip_id}", count.index)}"

Inappropriate value for attribute "allocation_id": string required.


Error: Incorrect attribute value type

  on ../providers/aws/network/nat_gw/nat_gateway.tf line 12, in resource "aws_nat_gateway" "nat_gw":
  12:     allocation_id = "${element("${var.eip_id}", count.index)}"

Inappropriate value for attribute "allocation_id": string required.


Error: Incorrect attribute value type

  on ../providers/aws/network/nat_gw/nat_gateway.tf line 13, in resource "aws_nat_gateway" "nat_gw":
  13:     subnet_id     = "${element("${var.target_subnet_id}", count.index)}"

Inappropriate value for attribute "subnet_id": string required.


Error: Incorrect attribute value type

  on ../providers/aws/network/nat_gw/nat_gateway.tf line 13, in resource "aws_nat_gateway" "nat_gw":
  13:     subnet_id     = "${element("${var.target_subnet_id}", count.index)}"

Can someone please help correct me.


Solution

  • You're incorrectly interpolating things there with your nested braces.

    Instead this should look like the following:

    resource "aws_nat_gateway" "nat_gw" {
      count         = "${var.total_nat_gws}"
      allocation_id = "${element(var.eip_id, count.index)}"
      subnet_id     = "${element(var.target_subnet_id, count.index)}"
    
      tags = {
        Name = "${var.nat_gw_name_tag}"
      }
    }
    

    As you aren't relying on the behaviour of element that allows looping back through list by selecting indexes that are longer than the length you can simplify this to:

    resource "aws_nat_gateway" "nat_gw" {
      count         = "${var.total_nat_gws}"
      allocation_id = "${var.eip_id[count.index]}"
      subnet_id     = "${var.target_subnet_id[count.index]}"
    
      tags = {
        Name = "${var.nat_gw_name_tag}"
      }
    }
    

    Because you're using Terraform 0.12 you could also directly use the variables instead of using the interpolation syntax to go even further with:

    resource "aws_nat_gateway" "nat_gw" {
      count         = var.total_nat_gws
      allocation_id = var.eip_id[count.index]
      subnet_id     = var.target_subnet_id[count.index]
    
      tags = {
        Name = var.nat_gw_name_tag
      }
    }