0
votes

I want to create a module that can accept inputs for environments(dev,test,prod) and create the number of subnets ("app" and "db" subnet for each environment) with proper tags. e.g Name=dev-app The module should be flexible to add/delete subnets as input variables are updated. My template looks like below

variable "environments" {
  type = map(object({
    app_subnet_cidr    = string
    db_subnet_cidr = string
  }))

  default = {
dev = {
    app_subnet_cidr = "192.168.219.0/24"
    db_subnet_cidr = "192.168.218.0/24"
  }
test = {
    app_subnet_cidr = "192.168.118.0/24"
    db_subnet_cidr = "192.168.119.0/24"
  }
}
}


resource "aws_subnet" "this" {
  for_each = var.environments
  vpc_id     = var.vpc_id
  cidr_block = {Don't know what to use here}

  tags {
  Name = {Don't know what to use here}
}
}

I was referring to the below articles. https://www.hashicorp.com/blog/terraform-0-12-rich-value-types/ Question-2: How "networks" variable could be defined for below module

module "subnets" {
  source = "./subnets"

  parent_vpc_id = "vpc-abcd1234"
  networks = {
    production_a = {
      network_number    = 1
      availability_zone = "us-east-1a"
    }
    production_b = {
      network_number    = 2
      availability_zone = "us-east-1b"
    }
    staging_a = {
      network_number    = 1
      availability_zone = "us-east-1a"
    }
  }
}

https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/

1

1 Answers

0
votes

The blog posts you are referring to were previews of forthcoming features not yet finished, so they are not the best reference for the final functionality that shipped. Instead, refer to the official documentation for resource for_each.

The documentation includes an example of declaring a number of azurerm_resource_group resource instances based on a map. We can adapt that example to work with your var.environments, with one resource block describing the "app" subnets, and a separate resource block describing the "db" subnets:

resource "aws_subnet" "app" {
  for_each = var.environments

  vpc_id     = var.vpc_id
  cidr_block = each.value.app_subnet_cidr

  tags = {
    Name = "${each.key}-app"
  }
}

resource "aws_subnet" "db" {
  for_each = var.environments

  vpc_id     = var.vpc_id
  cidr_block = each.value.db_subnet_cidr

  tags = {
    Name = "${each.key}-db"
  }
}

I'm not sure exactly how your second question relates to the first, but here's how to declare a variable networks so that it would accept a value like the one you showed in the second example.

variable "networks" {
  type = map(object({
    network_number    = number
    availability_zone = string
  }))
}

If you want to see more about that second example, I'd suggest starting a new separate question on Stack Overflow about it. The convention on Stack Overflow is to have a separate question for each topic, rather than to ask multiple questions at once.