使用 Terraform 的 AWS Provider 时模运算如何将 EC2 实例分配给子网的简单说明

Simple explanation of how modulo operations can assign EC2 instances to subnets when using Terraform's AWS Provider

无示例代码; docs:

这一段看不懂

Each instance provisioned by the resource block with count will have a different incrementing value for count.index - starting with zero. This configuration uses count.index and modulo division to assign each instance to a private subnet.

指的是这块代码的变化:

 resource "aws_instance" "app" {
 +  count = var.instances_per_subnet * length(module.vpc.private_subnets)
 +   
    ami           = data.aws_ami.amazon_linux.id   instance_type = var.instance_type
-  subnet_id              = module.vpc.private_subnets[0]
+  subnet_id              = module.vpc.private_subnets[count.index % length(module.vpc.private_subnets)]   vpc_security_group_ids = [module.app_security_group.this_security_group_id]
   ## ...
 }

有人可以向我解释这里发生了什么,或者告诉我相关文档吗?

试图解释“这里发生了什么”。请原谅冗长。

objective是创建N个实例并将它们平均“分布”在M个可用子网中。

假设此示例有 3 个私有子网(比如每个可用区一个)。即 length(module.vpc.private_subnets) 的值为 3.
这 3 个子网的子网 ID 可以从 vpc 模块返回的数组访问:

  • module.vpc.private_subnets[0]
  • module.vpc.private_subnets[1]
  • module.vpc.private_subnets[2]

假设您要为每个子网创建 2 个实例。即变量 var.instances_per_subnet 的值为 2.

资源块中第一个表达式的计数值为 2 * 3 = 6

资源块将创建 6 个实例。

我喜欢想象 Terraform 在创建 6 个实例时从 0 到 5“迭代”count.index(这只是我的理解;一般来说,您并不真正关心它是如何实际发生的,因为 HCL 是声明式 )

下面我尝试展开表达式

subnet_id = module.vpc.private_subnets[count.index % length(module.vpc.private_subnets)]

对于创建的 6 个实例中的每一个:

注意:在 HCL 中,模运算符 (%) 的工作方式大致类似于 python % operator

  • 对于与 count.index = 0 关联的实例,子网 ID 将为 module.vpc.private_subnets[0 % 3],即我们将使用 module.vpc.private_subnets[0][ 给出的子网 ID =54=]
  • 对于count.index = 1 => module.vpc.private_subnets[1 % 3],即subnet_id = module.vpc.private_subnets[1]
  • 对于count.index = 2 => module.vpc.private_subnets[2 % 3],即subnet_id = module.vpc.private_subnets[2]
  • 对于 count.index = 3 我们回到了第一个子网,因为 3 % 3 = 0 => subnet_id = module.vpc.private_subnets[0]
  • 对于count.index = 4 => module.vpc.private_subnets[4 % 3],即subnet_id = module.vpc.private_subnets[1]
  • 对于count.index = 5 => module.vpc.private_subnets[5 % 3],即subnet_id = module.vpc.private_subnets[2]

最终结果是我们将创建的 6 个实例 [0,1,...,5]“平均”分配给 3 个可用子网 [0,1,2]