Если ключи var.VPC_CIDR
выбираются вызывающей стороной, то может быть лучше объединить префикс CIDR и количество новых битов, которые будут использоваться для его подсетей, вместе в переменной. Поскольку обычный способ именования переменных Terraform осуществляется строчными буквами, я собираюсь также переименовать его в vpc_cidr
в следующих примерах.
variable "vpc_cidr" {
type = map(object({
cidr_block = string
subnet_bits = number
}))
default = {
dev = {
cidr_block = "10.10.0.0/24"
subnet_bits = 3
}
prod = {
cidr_block = "10.10.0.0/16"
subnet_bits = 4
}
}
}
variable "pri_subnet_count" {
type = number
default = 1
}
locals {
vpc_subnets = flatten([
for name, vpc in var.vpc_cidr : [
for i in count(var.pri_subnet_count) : {
name = "${name}-${i}"
vpc_name = name
cidr_block = vpc.cidr_block
subnet_bits = vpc.subnet_bits
network_num = i + 2
}
]
])
}
resource "aws_vpc" "example" {
for_each = var.vpc_cidr
cidr_block = each.value.cidr_block
}
resource "aws_subnet" "private" {
for_each = { for s in local.vpc_subnets : s.name => s }
vpc_id = aws_vpc.example[each.value.vpc_name].id
cidr_block = cidrsubnet(each.value.cidr_block, each.value.subnet_bits, each.value.network_num)
# ...
}
Если имена «prod» и «dev» являются фиксированнымии, таким образом, ваш модуль будет предполагать, что они всегда будут указаны, вы можете автоматически получить значения subnet_bits
способом, аналогичным описанному вами, например:
variable "vpc_cidr" {
type = object({
# Force caller to provide "dev" and "prod" values, so
# that it will match up with the attributes in
# local.subnet_bits defined below.
dev = string
prod = string
})
value = {
dev = "10.10.0.0/24"
prod = "10.10.0.0/16"
}
}
variable "pri_subnet_count" {
type = number
default = 1
}
locals {
subnet_bits = {
dev = 3
prod = 4
}
vpcs = {
for name, cidr_block in var.vpc_cidr : name => {
cidr_block = cidr_block
subnet_bits = local.subnet_bits[name]
}
}
vpc_subnets = flatten([
for name, vpc in local.vpcs : [
for i in count(var.pri_subnet_count) : {
name = "${name}-${i}"
vpc_name = name
cidr_block = vpc.cidr_block
subnet_bits = vpc.subnet_bits
network_num = i + 2
}
]
])
}
resource "aws_vpc" "example" {
for_each = local.vpcs
cidr_block = each.value.cidr_block
}
resource "aws_subnet" "private" {
for_each = { for s in local.vpc_subnets : s.name => s }
vpc_id = aws_vpc.example[each.value.vpc_name].id
cidr_block = cidrsubnet(each.value.cidr_block, each.value.subnet_bits, each.value.network_num + 2)
# ...
}
Общая схема, показанная выше, строитструктура данных local.vpc_subnets
, которая содержит один элемент для каждой подсети, которую вы хотите создать. Это позволяет затем повторять aws_subnet.private
для каждого элемента и собирать вместе все значения, необходимые для заполнения аргументов vpc_id
и cidr_block
в подсети.