首页 > 解决方案 > Terraform:如何在 aws_lb 中为子网循环 aws_instances

问题描述

我有以下variable定义实例的 Terraform

variable "instance_types" {

  default = {
    k8_east_1_control_plane = {
      count                  = 1
      role                   = "control-plane"
      ami                    = "ami-xxx"
      instance_type          = "t2.large"
      iam_instance_profile   = "xxx-user"
      subnet_id              = "subnet-xxx-0"
    }
    k8_east_2_control_plane = {
      count                  = 3
      role                   = "contro-plane"
      ami                    = "ami-xxx"
      instance_type          = "t2.large"
      iam_instance_profile   = "xxx-user"
      subnet_id              = "subnet-xxx-1"
    }
    ...
   }

我有N很多aws_instances(下面的例子)

locals {

  instance_types = flatten([

    for instance_key, instance in var.instance_types : [

      for type_count in range(1, instance.count + 1) : {

        new_key              = "${instance_key}-${type_count}"
        type                 = instance_key
        role                 = instance.role
        ami                  = instance.ami
        instance_type        = instance.instance_type
        iam_instance_profile = instance.iam_instance_profile
        subnet_id            = instance.subnet_id
      }
    ]
  ])
}

resource "aws_instance" "k8s-node" {

  for_each = { for instance_type in local.instance_types : instance_type.new_key => instance_type }

  ami                    = each.value.ami
  instance_type          = each.value.instance_type
  iam_instance_profile   = each.value.iam_instance_profile
  subnet_id              = each.value.subnet_id

  ...
}

问题:如何循环这些以从“控制平面”类型中aws_instances填充subnetsrole

resource "aws_lb" "k8s_load_balancer" {

  depends_on = [aws_instance.k8s-node]

  name               = "k8_load_balancer"
  load_balancer_type = "network"

  dynamic "subnet_mapping" {


// PROBLEM HERE :: How do you create for loop to populate `subnet_mapping`

//    for_each = [for i in aws_instance.k8s-node: i.private_ip if i.tags.Role == "control-plane" {
//      subnet_id = control_planes[i].subnet_id
//      private_ip = control_planes[i].private_ip
//    }]
    content {
      subnet_id = subnet_mapping.value.subnet_id
      private_ipv4_address = subnet_mapping.value.private_ip
    }
  }
}

伪代码中的目标,传统的 for 循环

resource "aws_lb" "k8s_load_balancer" {

  depends_on = [aws_instance.k8s-node]

  name               = "k8_load_balancer"
  load_balancer_type = "network"

  dynamic "subnet_mapping" {

  for(aws_instance instance : aws_instance.k8s-node) {

    if(instance.role.equls("control-plane")){

      subnet_mapping {
        subnet_id            = instance.subnet_id
        private_ipv4_address = instance.private_ip
      }
    }
  }
}

标签: amazon-ec2terraformaws-load-balancer

解决方案


由于您var.instance_types在 youraws_instance和 for 动态块中都使用了,因此应该可以进行以下操作:

dynamic "subnet_mapping" {

    for_each = { for key, value in variable.instance_types:
                   key => {
                      subnet_id = value.subnet_id
                   } if value.role == "control-plane"  
               }

    content {
      subnet_id            = subnet_mapping.value.subnet_id
      private_ipv4_address = aws_instance.k8s-node[subnet_mapping.key].private_ip
    }
    
}


推荐阅读