【问题标题】:creating multiple subnets per availability zone using terraform使用 terraform 为每个可用区创建多个子网
【发布时间】:2019-11-22 05:30:38
【问题描述】:

我是 terraform 的新手。我想使用 terraform 在 AWS 的特定区域中为每个可用区创建单个公有子网和三个私有子网。通过引用以下链接https://medium.com/@maneetkum/create-subnet-per-availability-zone-in-aws-through-terraform-ea81d1ec1883,我可以为每个可用区创建一个私有和公共子网。但是我需要将创建的一个私有子集拆分为另一个 2。这在 terraform 中可能吗?

data "aws_availability_zones" "available" {}resource "aws_vpc" "myVpc" {
  cidr_block           = "10.20.0.0/16"
  enable_dns_hostnames = true
  tags {
    Name = "myVpc"
  }
}
resource "aws_subnet" "public_subnet" {
  count = "${length(data.aws_availability_zones.available.names)}"
  vpc_id = "${aws_vpc.myVpc.id}"
  cidr_block = "10.20.${10+count.index}.0/24"
  availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
  map_public_ip_on_launch = true
  tags {
    Name = "PublicSubnet"
  }
}
resource "aws_subnet" "private_subnet" {
  count = "${length(data.aws_availability_zones.available.names)}"
  vpc_id = "${aws_vpc.myVpc.id}"
  cidr_block = "10.20.${20+count.index}.0/24"
  availability_zone= "${data.aws_availability_zones.available.names[count.index]}"
  map_public_ip_on_launch = false
  tags {
    Name = "PrivateSubnet"
  }
}

以上代码用于为每个可用区创建一个私有和公共子网。

【问题讨论】:

  • 为什么不复制 private_subnet 资源元素并更改 CIDR 块以创建额外的 2 个子网?
  • 感谢您的建议...如果可行...您能否提供代码格式,因为我是 terraform 的新手,我不知道代码?

标签: amazon-web-services terraform vpc


【解决方案1】:

可以创建多个子网,并自动将它们放入可用区,而无需重复代码。让我们保留DRY。为避免重复代码,请使用 Terraform 元参数和内置函数的魔力。具体来说,使用“count”和“cidrsubnet”。 “count”会根据需要生成尽可能多的子网副本。

如果您想为每个子网提供唯一的值,例如子网的标签 Name,您可以为每个子网指定一个唯一的、助记的名称,方法是使用您希望使用的名称创建数据字典希望分配给每个子网。然后在创建子网时使用“count.index”分配它们。如果工作量太大,您也可以在名称中嵌入 count.index

不同区域有不同数量的可用区。为确保您将子网分配给实际退出的可用区,您应该动态生成list of the Availability Zones。这样,您就知道列表中的所有可用区实际上在您工作的区域中可用。

如果您的子网数量超过该区域的可用区数量,会发生什么情况?使用modulo 算法来包装您的工作索引。与其直接使用index.count,不如在index.count 上使用modulo,使用列表中的length。这将环绕索引,因此您的工作索引永远不会溢出可用区列表的长度。

但是,真正的魔力是“cidrsubnet”命令。下面的示例将采用传递的基本 CIDR 块的大小(恰好是 /16),添加第二个参数 (4),并生成 /20 CIDR 块。第三个参数通过可用的 CIDR 块进行索引,从而确保每个子网获得不同的子 CIDR 块。

注意:相关的cidrsubnets 命令有点不同。所以,要小心,不要混淆这两个功能。

resource "aws_subnet" "area_subnets" {
  count                   = 4 # creates four subnets
  vpc_id                  = var.area_vpc_id
  map_public_ip_on_launch = var.map_public_ip_on_launch

  cidr_block           = cidrsubnet(var.area_subnet_cidr, 4, count.index)
  availability_zone_id = data.aws_availability_zones.available.zone_ids[count.index % length(data.aws_availability_zones.available.zone_ids)]

  tags = tomap({ "Name" = "${var.subnet_names[count.index]}" })
}

variable "subnet_names" {
  type = list(string)
  default = [
    "Primary NAT Gateway Subnet",
    "Secondary NAT Gateway Subnet",
    "Channel A Subnet",
    "Channel B Subnet"
  ]
}

variable "map_public_ip_on_launch" {
  type    = bool
  default = true
}

variable "area_vpc_id"
    documentation = "The Terraform ID of the containing VPC"
    type = string
    default = "vpc-abcdefghijklmno"
}

variable "area_subnet_cidr"
    documentation = "The base CIDR that you are working with"
    type = string
    default = "10.0.0.0/16"
}

data "aws_availability_zones" "available" {
  state = "available"

  filter { # Only fetch Availability Zones (no Local Zones)
    name   = "opt-in-status"
    values = ["opt-in-not-required"]
  }
}

【讨论】:

    【解决方案2】:

    您只需复制 private_subnet 资源元素即可在每个 AZ 中创建两个新子网:

    ...
    resource "aws_subnet" "private_subnet" {
      count = "${length(data.aws_availability_zones.available.names)}"
      vpc_id = "${aws_vpc.myVpc.id}"
      cidr_block = "10.20.${20+count.index}.0/24"
      availability_zone= "${data.aws_availability_zones.available.names[count.index]}"
      map_public_ip_on_launch = false
      tags {
        Name = "PrivateSubnet"
      }
    }
    resource "aws_subnet" "private_subnet_2" {
      count = "${length(data.aws_availability_zones.available.names)}"
      vpc_id = "${aws_vpc.myVpc.id}"
      cidr_block = "10.30.${20+count.index}.0/24"
      availability_zone= "${data.aws_availability_zones.available.names[count.index]}"
      map_public_ip_on_launch = false
      tags {
        Name = "PrivateSubnet2"
      }
    }
    

    您需要修改每个子网的 CIDR 块,以确保它们不会相互重叠。

    【讨论】:

    • Thanyou..thanx 让我使用代码并对此进行更新
    • 是的,我可以登录,但对 Ip 的修改很少,例如 10.20.${20+count.index}.0/24" , 10.20${30+count.index}.0/24 "等等
    • 好的,很好。如果它回答了问题,您能否将答案标记为正确。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 2021-12-09
    • 2020-11-30
    • 2018-07-29
    • 2022-09-28
    • 2021-08-09
    • 1970-01-01
    相关资源
    最近更新 更多