如何从 terraform 中的 EC2 实例列表中提取 ID 以在 ALB 中使用?

Posted

技术标签:

【中文标题】如何从 terraform 中的 EC2 实例列表中提取 ID 以在 ALB 中使用?【英文标题】:How can i extract the id from a list of EC2 instances in terraform to use in a ALB? 【发布时间】:2021-12-18 23:38:56 【问题描述】:

我目前正在练习 terraform 来编写 mi AWS 基础设施。

我无法创建应用程序负载平衡器。在模块中,您需要将要定位的实例的 id 放在目标组中。

我的 EC2 模块如下所示

module "ec2_private" 
  depends_on = [module.vpc]
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "3.2.0"
  # insert the 34 required variables here
  name                   = "$var.environment-PrivateVM"
  ami                    = data.aws_ami.amzlinux2.id
  instance_type          = var.instance_type
  key_name               = var.instance_keypair
  #monitoring            = true
  for_each               = toset(["0","1"])
  subnet_id              = module.vpc.private_subnets[each.value]
  user_data              = file("$path.module/app1-install.sh")
  vpc_security_group_ids = [module.private_sg.security_group_id]
  tags                   = local.common_tags  

这会创建 2 个实例,每个实例位于我创建的两个私有子网之一中。

现在我需要从这个模块中提取 id,以便在 ALB 中使用

    module "alb" 
      source  = "terraform-aws-modules/alb/aws"
      version = "6.5.0"
      # insert the 4 required variables here
      name = "$local.name-alb01"
      load_balancer_type = "application"
      vpc_id = module.vpc.vpc_id
      subnets = [module.vpc.public_subnets[0],module.vpc.public_subnets[1]]
      security_groups = [module.loadbalancer_sg.security_group_id]

  # Listeners

      http_tcp_listeners = [
        
          port               = 80
          protocol           = "HTTP"
          target_group_index = 0
        
      ]
      # Target Groups
      target_groups = [
        # App1 Target Group - TG index 0
        
          name_prefix          = "h1"
          backend_protocol     = "HTTP"
          backend_port         = 80
          target_type          = "instance"
          deregistration_delay = 10
          health_check = 
            enabled             = true
            interval            = 30
            path                = "/example/index.html"
            port                = "traffic-port"
            healthy_threshold   = 3
            unhealthy_threshold = 3
            timeout             = 6
            protocol            = "HTTP"
            matcher             = "200-399"
          
          protocol_version = "HTTP1"
          # App1 Target Group - Targets
          targets = 
            my_app1_vm1 = 
              target_id = element(module.ec2_private.id,0)
              port      = 80
            ,
            my_app1_vm2 = 
              target_id = element(module.ec2_private.id,1)
              port      = 8080
            
          
          tags= local.common_tags
        
      ]
    

使用此代码我收到此错误

│ Error: Unsupported attribute
│
│   on c10-02-ALB-application-loadbalancer.tf line 43, in module "alb":
│   43:           target_id = element(module.ec2_private.id,0)
│     ├────────────────
│     │ module.ec2_private is a list of object, known only after apply
│
│ Can't access attributes on a list of objects. Did you mean to access attribute "id" for a specific element of the
│ list, or across all elements of the list?

我已尝试使用确切的索引来解决此问题

  targets = 
    my_app1_vm1 = 
      target_id = module.ec2_private.id[0]
      port      = 80
    ,
    my_app1_vm2 = 
      target_id = module.ec2_private.id[1]
      port      = 8080
    
  

但我得到同样的错误

│ Error: Unsupported attribute
│
│   on c10-02-ALB-application-loadbalancer.tf line 47, in module "alb":
│   47:           target_id = module.ec2_private.id[1]
│     ├────────────────
│     │ module.ec2_private is a list of object, known only after apply
│
│ Can't access attributes on a list of objects. Did you mean to access attribute "id" for a specific element of the
│ list, or across all elements of the list?

有没有其他方法可以提取特定索引?

谢谢。

【问题讨论】:

【参考方案1】:

在这种情况下,您需要使用Terraform outputs。在你的 ec2_private 模块中,你可能想要这样的东西:

output "ec2_instance_ids" 
  value = [aws_instance.my_first_instance.id, aws_instance.my_second_instance.id]

模块的输出可以这样引用:

module.<MODULE NAME>.<OUTPUT NAME>

例子:

targets = 
  my_app1_vm1 = 
    target_id = module.ec2_private.ec2_instance_ids[0]
      port      = 80
  ,
  my_app1_vm2 = 
    target_id = module.ec2_private.ec2_instance_ids[1]
    port      = 8080
  

【讨论】:

我在另一条评论中回复了您的评论。坦克!

以上是关于如何从 terraform 中的 EC2 实例列表中提取 ID 以在 ALB 中使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Terraform 部署 Open*** EC2 实例? [关闭]

Terraform AWS subnet_id 列表被视为 ec2 实例的单值字符串

使用 Terraform 时从实例获取 EC2 Windows 密码

如何使用 terraform 在 LocalStack 上创建 EC2 实例?

如何通过 Terraform 启动没有密钥对的 EC2 实例?

如何使用 terraform 将负载均衡器添加到 ec2 实例