terraform 从 vpc 端点子网选项卡获取子网集成 ip

Posted

技术标签:

【中文标题】terraform 从 vpc 端点子网选项卡获取子网集成 ip【英文标题】:terraform get subnet integration ips from vpc endpoint subnets tab 【发布时间】:2020-01-13 03:58:29 【问题描述】:

流程是这样的

1.vpc-->vpc_endpoint(com.amazonaws.us-east-1.transfer.server) --> [subnet_1, subnet_2]

2.net --> nlb --> targetgroups --> [subnet_ip_1, subnet_ip_2]

我正在创建一个 NLB,其目标组指向为“AWS 传输用于 sftp”com.amazonaws.us-east-1.transfer.server 创建的 VPC 端点,但 terraform 不返回与 VPC 端点集成的子网的 ips

所以,目前我正在从 vpc 端点下的子网选项卡手动复制 ips。 但是,我想使用 terraform 自动化这个完整的过程

任何帮助将不胜感激

resource "aws_eip" "nlb" 
  count = length(var.public_subnet_ids)
  vpc   = true


resource "aws_lb" "network" 
  name               = "$var.service_name-$var.env-nlb"
  load_balancer_type = "network"

  dynamic subnet_mapping 
    for_each = [for i in range(length(module.vpc.public_subnet_ids)) : 
      subnet_id     = var.public_subnet_ids[i]
      allocation_id = aws_eip.nlb[i].id
    ]
    content 
      subnet_id     = subnet_mapping.value.subnet_id
      allocation_id = subnet_mapping.value.allocation_id
    
  


resource "aws_lb_target_group" "target-group" 
  name        = "$var.service_name-$var.env-nlb-target-group"
  port        = 22
  protocol    = "TCP"
  target_type = "ip"
  vpc_id      = var.vpc_id


// TODO need to add vpc endpoint subnet ip addresses manually to nlb target group as terraform doesn't export the subnet ip addresses
//resource "aws_lb_target_group_attachment" "vpc-endpoint" 
//  count = length(var.public_subnet_ids)
//  target_group_arn = aws_lb_target_group.target-group.arn
//  target_id        = this needs ip of subnets intgerated with vpc endpoint 
//  port             = 22
//

resource "aws_vpc_endpoint" "transfer" 
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.$var.aws_region.transfer.server"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.public_subnet_ids
  private_dns_enabled = true


resource "aws_transfer_server" "sftp" 
  identity_provider_type = "API_GATEWAY"
  endpoint_type = "VPC_ENDPOINT"
  endpoint_details 
    vpc_endpoint_id = aws_vpc_endpoint.transfer.id
  
  url = aws_api_gateway_deployment.deploy.invoke_url
  invocation_role = aws_iam_role.transfer-identity-provider-role.arn
  logging_role = aws_iam_role.transfer-logging-role.arn

  depends_on = [aws_vpc_endpoint.transfer]

【问题讨论】:

您能否编辑您的问题以包含您编写的 Terraform 代码? terraform 代码有效且没有错误。但是,我找不到获取 vpc 端点子网集成 ips 的方法 您仍应添加minimal reproducible example,以便我们了解您的进度。 这是您要问的:terraform.io/docs/providers/aws/d/subnet_ids.html? 没有 ID 无济于事,它必须是集成 IP 【参考方案1】:

从the docs 看来,VPC 终端节点具有主机名而不是静态 IP 地址,这通常意味着主机名可能引用多个 IP 地址或可能随时间而变化。因此,您想在此处执行的操作可能无法实现,或者至少随着时间的推移可能无法保持可靠。

话虽如此,您可以使用dns 提供程序在 Terraform 运行时获取与这些主机名对应的 IP 地址,只要这些主机名立即可用:

resource "aws_vpc_endpoint" "transfer" 
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.$var.aws_region.transfer.server"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.public_subnet_ids
  private_dns_enabled = true


data "dns_a_record_set" "endpoints" 
  # dns_a_record_set.endpoints is a map from hostname to an object containing "addrs"
  for_each =  for e in aws_vpc_endpoint.transfer.dns_entry : e.dns_name => e 

  host = each.key


locals 
  # Flatten the IP addresses down into a single set.
  endpoint_ip_addrs = toset(flatten(dns_a_record_set.endpoints[*].addrs))


resource "aws_lb_target_group_attachment" "vpc-endpoint" 
  for_each = local.endpoint_ip_addrs

  target_group_arn = aws_lb_target_group.target-group.arn
  target_id        = each.value
  port             = 22

不幸的是,我希望 aws_vpc_endpointdns_entry 属性中的主机名只有在应用后才能知道,因此它们不是用于 for_each 的好键。如果这是真的,那么上面将产生错误,指出 for_each 值不合适,除非您使用 -target 逐渐应用此值。

aws_vpc_endpoint 的设计似乎不适合您在此处尝试执行的操作,因为它没有提供任何明确指示哪些主机名属于哪个子网,因此没有足够的信息可用于构造具有配置中已知键的映射或设置值。可能值得考虑从等式中完全删除负载平衡器的替代方法,而只使用aws_vpc_endpoint 提供的 DNS 主机名,因为考虑到资源类型的设计方式,这似乎是预期的用途。

【讨论】:

问题是我使用 NLB 通过 IP 白名单将 SFTP 服务器暴露给外部网络。 aws.amazon.com/sftp/faqs “问:我可以过滤传入流量以访问我的 SFTP 服务器的 VPC 端点吗?”。所以,我不能在这种情况下删除 NLB【参考方案2】:

试试这样的:

## Data Section
data "aws_network_interface" "eni_0" 
  id = "$aws_vpc_endpoint.transfer.network_interface.ids 0"


  data "aws_network_interface" "eni_1" 
  id = "$aws_vpc_endpoint.transfer.network_interface.ids 1"



## Resource Section
resource "aws_alb_target_group_attachment" "tg_att_0" 
  target_group_arn = "$aws_lb_target_group.group.arn"
  target_id = "$data.aws_network_interface.eni_0.private_ips[0]"
  port = 22


resource "aws_alb_target_group_attachment" "tg_att_1" 
  target_group_arn = "$aws_lb_target_group.group.arn"
  target_id = "$data.aws_network_interface.eni_1.private_ips[0]"
  port = 22

这确实有效,但还没有时间优化代码... 它将允许您将 NLB 附加到 VPC 端点内部地址。

祝你好运。

【讨论】:

以上是关于terraform 从 vpc 端点子网选项卡获取子网集成 ip的主要内容,如果未能解决你的问题,请参考以下文章

AWS VPC 模块公有和私有子网 - Terraform

Terraform 和 GCP - 在现有的共享 VPC 和子网中创建新的计算 VM

如何在带有 Terraform 的 AWS VPC 中的两个子网之间进行路由?

如何将使用 cidrsubnets 的子网的 CIDR 范围传递给 Terraform 版本 0.14 中的 VPC 模块

Terraform EKS 标记

Terraform 模块 - 输出变量作为另一个模块的输入