引用创建的子网并将其与 NLB(aws 提供商)的给定 EIP 相关联

Referencing a created subnet and associate it with a given EIP for a NLB (aws provider)

我正在尝试参数化 NLB 的创建,并在同一计划中提供必要的 public 子网。

子网被指定为计划的变量:


variable "nlb_public_subnets" {
  type    = list(object({
    name              = string
    network_number    = number
    availability_zone = string
    elastic_ip        = string
  }))
  default = [
    {
      name              = "sftp_sub_A"
      network_number    = 1
      availability_zone = "eu-west-1a"
      elastic_ip        = "X.Y.Z.T"
    },
    {
      name              = "sftp_sub_B"
      network_number    = 2
      availability_zone = "eu-west-1b"
      elastic_ip        = "XX.YY.ZZ.TT"
    }
  ]
}
variable "common_tags" {
  description = "A map containing the common tags to apply to all resources"
  type        = map(string)
  default     = {}
}

locals {
  vpc_id = "dummy"
  base_cidr = "10.85.23.0/24"

  publicSubnets = { for s in var.nlb_public_subnets :
    s.name => {
      name              = s.name
      cidr_block        = cidrsubnet(var.base_public_subnet_cidr_block, 6, 
s.network_number )
      availability_zone = s.availability_zone
      elastic_ip        = s.elastic_ip
    }
  }
}

我正在指定一个名称、一个网络号(用于计算 cidr 块)、一个可用区和一个在创建 NLB 时要映射到的弹性 IP。

我在这里创建子网:


#Comment added after solution was given 
#This will result in a Map indexed by subnet.name provided in var.nlb_public_subnets
resource "aws_subnet" "sftp_nlb_subnets" {
  for_each          = { for subnet in local.publicSubnets :
    subnet.name => subnet
  }
  cidr_block        = each.value.cidr_block
  vpc_id            = local.vpc_id
  availability_zone = each.value.availability_zone
  tags              = {
    Name       = each.key
    Visibility = "public"
    Purpose    = "NLB"
  }
}

现在我需要创建我的 NLB,而这正是我苦苦思索如何将新创建的子网与配置中提供的弹性 IP 相关联的地方:


resource "aws_lb" "sftp" {
  name = var.name
  internal = false
  load_balancer_type = "network"
  subnets = [for subnet in aws_subnet.sftp_nlb_subnets: subnet.id]
  enable_deletion_protection = true
  tags = merge(var.common_tags,{
    Name=var.name
  })

  dynamic "subnet_mapping" {
    for_each = aws_subnet.sftp_nlb_subnets
    content {
      subnet_id = subnet_mapping.value.id
      allocation_id = ????Help???
    }
  }
}

我能否借助标签中的子网名称以某种方式查找配置对象?

更新1 更新了动态块,因为它有错字。

更新2 @tmatilai 给出了答案!

这是修改后的 aws_lb 块:

#
#This will result in a Map indexed by subnet.name provided in var.nlb_public_subnets
data "aws_eip" "nlb" {
  for_each  = local.publicSubnets
  public_ip = each.value.elastic_ip
}


resource "aws_lb" "sftp" {
  name                       = var.name
  internal                   = false
  load_balancer_type         = "network"
  subnets                    = [for subnet in aws_subnet.sftp_nlb_subnets : subnet.id]
  enable_deletion_protection = true
  tags                       = merge(var.common_tags, {
    Name = var.name
  })

  dynamic "subnet_mapping" {
    #subnet_mapping.key will contain subnet.name, so we can use it to access the Map data.aws_eip.nlb (also indexed by subnet.name) to get the eip allocation_id
    for_each = aws_subnet.sftp_nlb_subnets
    content {
      subnet_id     = subnet_mapping.value.id
      allocation_id = data.aws_eip.nlb[subnet_mapping.key].id
    }
  }
}

诀窍是认识到aws_subnet.sftp_nlb_subnetsdata.aws_eip.nlb都是一个Map,由local.publicSubnets的键索引。这允许我们使用映射 aws_subnet.sftp 中的这个公共键(子网名称)来查找从原始输入 local.publicSubnets.[=20 获得的数据 (data.aws_eip.nlb) 中的信息=]

谢谢。这是一个巧妙的技巧。

传递弹性 IP 的 IP 地址听起来很奇怪。如果您在别处创建 EIP,为什么不传递它们的(分配)ID?

但是使用此设置,您可以使用 aws_eip data source:

获取分配 ID
data "aws_eip" "nlb" {
  for_each  = local.publicSubnets
  public_ip = each.value.elastic_ip
}

resource "aws_lb" "sftp" {
  # ...

  dynamic "subnet_mapping" {
    for_each = aws_subnet.sftp_nlb_subnets
    content {
      subnet_id     = subnet_mapping.value.id
      allocation_id = data.aws_eip.nlb[subnet_mapping.key].id
    }
  }
}

但也许在这里创建 EIP 更有意义。例如这样的事情:

resource "aws_eip" "nlb" {
  for_each = local.publicSubnets

  vpc = true
}

resource "aws_lb" "sftp" {
  # ...

  dynamic "subnet_mapping" {
    for_each = aws_subnet.sftp_nlb_subnets
    content {
      subnet_id     = subnet_mapping.value.id
      allocation_id = aws_eip.nlb[subnet_mapping.key].id
    }
  }
}