Terraform - AWS - 创建多个实例 - 不同的可用区(其中实例数大于可用区列表长度)

Terraform - AWS - create multiple instances - different AZ (where instance count is greater than AZ list length)

我在使用 Terraform (v0.12) 使用计数变量和子网 ID 列表创建多个实例时遇到问题,其中计数大于子网 ID 列表的长度。

例如;

resource "aws_instance" "main" {
  count                     = 20
  ami                       = var.ami_id
  instance_type             = var.instance_type
  # ...
  subnet_id                 = var.subnet_ids_list[count.index]
}

我的计数是“20”而 length(var.subnet_ids_list) 是 2。它抛出以下错误:

count.index is 2
    var.instance_subnet_id is tuple with 2 elements

The given key does not identify an element in this collection value.

我尝试将 "subnet_ids_list" 设为逗号分隔的字符串并使用 "split",但它也给出了相同的错误。

后来想到将子网元素附加到 "subnet_ids_list" 以使其成为“20”。类似的东西;

Python 2.7
>>> subnet_ids_list = subnet_ids_list * 10

有人可以帮助我如何使用 Terraform 或任何其他方法来解决这个问题。

原创喜欢;

subnet_ids_list = ["sub-1", "sub-2"]

转换为-满足提供给count的值;

subnet_ids_list = ["sub-1", "sub-2", "sub-1", "sub-2",....., "sub-1", "sub-2",] (length=20).

我不想为此目的使用 AWS 自动缩放组。

每当您需要启动一个新的 EC2 时创建一个新的子网是没有意义的。我建议你看一下关于 VPC 和子网基础知识的官方文档:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html#vpc-subnet-basics

For example, if you create a VPC with CIDR block 10.0.0.0/24, it supports 256 IP addresses. You can break this CIDR block into two subnets, each supporting 128 IP addresses. One subnet uses CIDR block 10.0.0.0/25 (for addresses 10.0.0.0 - 10.0.0.127) and the other uses CIDR block 10.0.0.128/25 (for addresses 10.0.0.128 - 10.0.0.255).

在您的 Terraform 示例中,看起来您有 2 个子网(私有和 public?),因此在访问 subnet_ids_list 时您的计数器必须是 0 或 1。更好的解决方案是标记您的子网:https://www.terraform.io/docs/providers/aws/r/subnet.html#inner

您可能有另一个计数器来控制实例数。希望对您有所帮助!

编辑:根据您的评论,Map 是一种更好的数据结构来控制 instance/subnet。键可以是实例或子网本身,例如{ "aws_instance" = "sub-1" }

参考:https://www.terraform.io/docs/configuration-0-11/variables.html#maps

如果您需要循环访问链接文档中提到的事物列表,您可以使用 element function

The index is zero-based. This function produces an error if used with an empty list.

Use the built-in index syntax list[index] in most cases. Use this function only for the special additional "wrap-around" behavior described below.

> element(["a", "b", "c"], 3)
a