Been trying to create multiple subnet resources and got stuck at some point. So here is the code:
# variables.tf
variable "vpcs" {
type = map(object({
cidr = string
tags = map(string)
tenancy = string
}))
default = {
"RU" = {
cidr = "10.0.0.0/16"
tags = {
"Name" = "RU-VPC"
}
tenancy = "default"
}
"UZ" = {
cidr = "192.168.0.0/16"
tags = {
"Name" = "UZ-VPC"
}
tenancy = "default"
}
}
}
variable "subnets" {
type = map(object({
cidr = string
az = string
tags = map(string)
}))
default = {
"RU-Public-A" = {
az = "us-east-1a"
cidr = "10.0.1.0/24"
tags = {
"Name" = "RU-Public-A"
}
}
"RU-Public-B" = {
az = "us-east-1b"
cidr = "10.0.2.0/24"
tags = {
"Name" = "RU-Public-B"
}
}
"UZ-Public-A" = {
az = "us-east-1a"
cidr = "192.168.1.0/24"
tags = {
"Name" = "UZ-Public-A"
}
}
"RU-Public-B" = {
az = "us-east-1b"
cidr = "192.168.1.0/24"
tags = {
"Name" = "UZ-Public-B"
}
}
}
}
# main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_vpc" "main" {
for_each = var.vpcs
cidr_block = each.value["cidr"]
instance_tenancy = each.value["tenancy"]
tags = each.value["tags"]
}
resource "aws_internet_gateway" "main" {
for_each = aws_vpc.main
vpc_id = each.value.id
tags = {
"Name" = "${each.key}-IGW"
}
}
resource "aws_subnet" "public" {
}
So I was able to create multiple VPCs and attach Internet Gateways to them using a loop. But with the subnets I'm having a problem as I can't figure out how to implement nested looping of objects. Googled for it, but couldn't find a similar problem.
Any help or hint would be aprecciated. Thank you.
CodePudding user response:
Your subnets
has sub-optimal design leading to your issues. It would be much better and easier to make it in the following form:
variable "subnets" {
type = map(map(object({
cidr = string
az = string
tags = map(string)
})))
default = {
RU = {
"Public-A" = {
az = "ap-southeast-2a"
cidr = "10.0.1.0/24"
tags = {
"Name" = "RU-Public-A"
}
}
"Public-B" = {
az = "ap-southeast-2b"
cidr = "10.0.2.0/24"
tags = {
"Name" = "ap-southeast-2b"
}
}
},
UZ = {
"Public-A" = {
az = "ap-southeast-2a"
cidr = "192.168.1.0/24"
tags = {
"Name" = "UZ-Public-A"
}
}
"Public-B" = {
az = "ap-southeast-2b"
cidr = "192.168.2.0/24"
tags = {
"Name" = "UZ-Public-B"
}
}
}
}
}
then you flatten it:
locals {
flat_subnets = merge([
for vpck, vpcv in var.vpcs: {
for subnetk, subnetv in var.subnets[vpck]:
"${vpck}-${subnetk}" => {
vpc_key = vpck
subnet = subnetv
}
}
]...)
}
and use as:
resource "aws_subnet" "public" {
for_each = local.flat_subnets
vpc_id = aws_vpc.main[each.value.vpc_key].id
cidr_block = each.value.subnet.cidr
availability_zone = each.value.subnet.az
tags = each.value.subnet.tags
}