Trying to create a simple VPC and a Subnet by iterating over a JSON file to Terraform code.
I already figured most of it out.. the only variable missing is the cidr_block for my subnet, How do i approach this?
{
"vpc1" : {
"name": "first-vpc",
"cidr": "192.168.0.0/16",
"subnets" :[
{"name":"subnet-one", "cidr": "192.168.1.0/24"}, {"name":"subnet-two", "cidr":
"192.168.4.0/24"}
]
},
"vpc2" : {
"name": "second-vpc",
"cidr": "172.16.0.0/16",
"subnets" :[
{"name":"subnet-three", "cidr": "172.16.1.0/24"}, {"name":"subnet-four", "cidr":
"172.16.7.0/24"}
]
}
}
resource "aws_vpc" "main" {
for_each = { for index, vm in local.json : vm.name => vm }
cidr_block = each.value.cidr
tags = {
Name = each.value.name
}
}
resource "aws_subnet" "main" {
for_each = { for key, map in local.json : key => map.subnets }
vpc_id = each.key
cidr_block = each.value
}
Terraform console output :
> { for key, map in local.json : key => map.subnets }
{
"vpc1" = [
{
"cidr" = "192.168.1.0/24"
"name" = "subnet-one"
},
{
"cidr" = "192.168.4.0/24"
"name" = "subnet-two"
},
]
"vpc2" = [
{
"cidr" = "172.16.1.0/24"
"name" = "subnet-three"
},
{
"cidr" = "172.16.7.0/24"
"name" = "subnet-four"
},
]
}
Error message
Error: Incorrect attribute value type
│
│ on main.tf line 15, in resource "aws_subnet" "main":
│ 15: cidr_block = each.value
│ ├────────────────
│ │ each.value is tuple with 2 elements
│
│ Inappropriate value for attribute "cidr_block": string required.
@Cloudkollektiv Thanks for the instructions
CodePudding user response:
You have to flatten your json structure. For example:
locals {
json_flat = merge([
for vpc in local.json: {
for subnet in vpc.subnets:
"${vpc.name}-${subnet.name}" => {
vpc_name = vpc.name
vpc_cidr = vpc.cidr
subnet_name = subnet.name
subnet_cidr = subnet.cidr
}
}
]...)
}
then
resource "aws_vpc" "main" {
for_each = { for index, vm in local.json : vm.name => vm }
cidr_block = each.value.cidr
tags = {
Name = each.value.name
}
}
resource "aws_subnet" "main" {
for_each = local.json_flat
vpc_id = aws_vpc.main[each.value.vpc_name].id
cidr_block = each.value.subnet_cidr
}