Терраформирование — Несколько циклов или карт

#amazon-web-services #terraform #terraform-provider-aws #terraform0.12

Вопрос:

Я создаю несколько общедоступных подсетей, частных подсетей, igw, nat, route_tables и запись route_table в AWS с использованием terraform. Ниже приведено количество ресурсов, которые я создаю.

terraform.tfvars

 vpc_cidr = "10.0.0.0/16"
public_subnet_count = 6
public_subnets_cidr  = ["10.0.1.0/24","10.0.2.0/24","10.0.3.0/24","10.0.4.0/24","10.0.5.0/24", "10.0.6.0/24"]
availability_zones = ["us-east-2a", "us-east-2b","us-east-2c","us-east-2d"]
 
 
resources.tf

resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true
  tags = {
    Name        = "${var.environment}-vpc"
    Environment = var.environment
  }
}

resource "aws_subnet" "public_subnet" {
  vpc_id                  = "${aws_vpc.vpc.id}"
  count                   = var.public_subnet_count
  cidr_block              = "${element(var.public_subnets_cidr, count.index)}"
  availability_zone       = length(var.availability_zones) > 1 ? var.availability_zones[count.index % length(var.availability_zones)] : var.availability_zones[0]
  map_public_ip_on_launch = false
  tags = {
    Name        = "${var.environment}-${element(var.availability_zones, count.index)}-public-subnet"
    Environment = "${var.environment}"
  }
}

resource "aws_internet_gateway" "ig" {
  count = 1
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name        = "${var.environment}-igw"
    Environment = "${var.environment}"
  }
}

resource "aws_route_table" "public" {
  count = length(var.availability_zones)
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name        = "${var.environment}-public-route-table"
    Environment = "${var.environment}"
  }
}

 resource "aws_route" "public_internet_gateway" {
  count = length(aws_route_table.public.*.id)
  route_table_id         = element(aws_route_table.public.*.id, count.index)
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.ig[0].id
}

resource "aws_route_table_association" "public" {
  count = length(var.availability_zones)
  subnet_id      = element(aws_subnet.public_subnet.*.id, count.index)
  route_table_id = element(aws_route_table.public.*.id, count.index)
}
 

Запрос в разделе aws_route_table_association.public.

Как мне подключить частную подсеть определенной сети az к идентификатору таблицы маршрутов. Например, если я использую 6 частных подсетей в tfvars, он создает по крайней мере 2 частные подсети в одной az (например, us-east-2a). Как мне зациклить и подключить 2 подсети из us-east-2a к одной таблице маршрутов, созданной для us-east-2a. Своего рода карта между несколькими подсетями в одной az для таблицы маршрутов в этой az.

Это делается для подключения каждого шлюза az nat к этой подсети az для маршрутизации.

Ответ №1:

Вам не нужно создавать таблицу маршрутов для каждой страны, таблицы маршрутов связаны с подсетями. Таким образом, вы можете просто создать единую таблицу маршрутов, а затем связать с ней все ваши общедоступные подсети:

 resource "aws_route_table" "public" {
  vpc_id = aws_vpc.vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.ig.id
  }
}

resource "aws_route_table_association" "public" {
  count = var.public_subnet_count
  subnet_id      = aws_subnet.public_subnet[count.index].id
  route_table_id = aws_route_table.public.id
}
 

Я включил один маршрут в route_table , чтобы уменьшить объем кода, так что вы можете удалить aws_route ресурс, если используете это.

[Редактировать] Извините, я только что заметил ваше упоминание о частных подсетях, но прикрепление таблиц маршрутов следует тому же принципу, и вам также не нужен шлюз NAT для каждой сети (это дорого!), Чтобы вы могли маршрутизировать все частные подсети через один шлюз NAT с одной таблицей маршрутов.

Если вам действительно нужны 4 шлюзы NAT, то вы могли бы сделать что-то вроде:

 resource "aws_route_table" "private" {
  count  = length(var.availability_zones)
  vpc_id = aws_vpc.vpc.id
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat[count.index].id
  }
}

resource "aws_route_table_association" "private" {
  count = var.private_subnet_count

  subnet_id = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private[
    count.index % length(var.availability_zones)
  ].id
}
 

Поскольку вы уже используете оператор модуля (%) для распределения подсетей, я думаю, что вы получите тот же результат, сделав это таким образом.

Комментарии:

1. Один NAT — не лучшее решение. Если один az отключен и все экземпляры подключены к одному и тому же nat, это также повлияет на экземпляры в других az. AWS предлагает использовать один nat на az(не менее 2 nat).

2. Честно говоря, я обновил свой ответ, чтобы включить опцию на случай, если потребуется несколько NAT.