CSV driven terraform deployment for creating resources using for_each expressions

Terraform Version

Terraform v0.12.20

  • provider.aws v2.61.0
...

Terraform Configuration Files

locals {
vpc = csvdecode(file("./vpc.csv"))
subnet = csvdecode(file("./subnet.csv"))
}

resource "aws_vpc" "main" {
for_each = { for inst in local.vpc : inst.local_id => inst }
cidr_block = each.value.CIDR_Block
enable_dns_support = each.value.DNS_Support
enable_dns_hostnames = each.value.DNS_Hostnames

tags = {
Name = each.value.Name
Environment = each.value.Environment
}
}

resource "aws_subnet" "main" {
for_each = { for inst in local.subnet : inst.subnet_id => inst }
vpc_id = aws_vpc.main[each.key]
cidr_block = each.value.Subnets

tags = {
Name = each.value.Subnet_Names
}
}
Error Message:
Error: Incorrect attribute value type

  on vpc.tf line 22, in resource "aws_subnet" "main":
  22:   vpc_id     = aws_vpc.main[each.key]
    |----------------
    | aws_vpc.main is object with 1 attribute "1"
    | each.key is "1"

Inappropriate value for attribute "vpc_id": string required.


Error: Invalid index

  on vpc.tf line 22, in resource "aws_subnet" "main":
  22:   vpc_id     = aws_vpc.main[each.key]
    |----------------
    | aws_vpc.main is object with 1 attribute "1"
    | each.key is "2"

The given key does not identify an element in this collection value.


Error: Invalid index

  on vpc.tf line 22, in resource "aws_subnet" "main":
  22:   vpc_id     = aws_vpc.main[each.key]
    |----------------
    | aws_vpc.main is object with 1 attribute "1"
    | each.key is "3"

The given key does not identify an element in this collection value.

Hi @amansyed931,

Your first error is because aws_vpc.main[each.key] is a reference to a whole aws_vpc object, but this vpc_id argument expects a VPC ID string. You can fix that part by accessing the .id attribute:

   vpc_id     = aws_vpc.main[each.key].id

The other errors with summary “Invalid index” are appearing because your aws_vpc.main resource and your aws_subnet.main resource don’t use the same map keys in for_each and so you can’t use each.key from aws_subnet to look up an instance of aws_vpc.main: each.key there is an inst.subnet_id value, not an inst.local_id value.

You didn’t share what fields you have in your two CSV files, but in order to make this work you’ll need to have a field in subnet.csv to indicate which VPC each subnet belongs to using its “local id”, and then you can use that to find the corresponding VPC ID. For example, if your field in subnet.csv were called vpc_local_id then you could use it like this:

   vpc_id     = aws_vpc.main[each.value.vpc_local_id].id