Amazon ec2 将一个terraform模块的输出引用到另一个模块时出错

Amazon ec2 将一个terraform模块的输出引用到另一个模块时出错,amazon-ec2,module,dependencies,terraform,aws-nlb,Amazon Ec2,Module,Dependencies,Terraform,Aws Nlb,我是terraform的新手,正在尝试在terraform v0.14.0中创建一个项目,该项目将执行以下步骤: 创建n台ec2机器(一台为主,其余为子) 创建NLB和terget组 通过引用步骤1(ec2模块)的输出变量,将子ec2实例私有ip连接到目标组 但当我运行terraform plan时,我得到了以下信息。这个问题能解决吗?或者采用其他方法一次性提供这些资源 Error: Invalid for_each argument on ../../../../modules/nlb_

我是terraform的新手,正在尝试在terraform v0.14.0中创建一个项目,该项目将执行以下步骤:

  • 创建n台ec2机器(一台为主,其余为子)
  • 创建NLB和terget组
  • 通过引用步骤1(ec2模块)的输出变量,将子ec2实例私有ip连接到目标组
  • 但当我运行terraform plan时,我得到了以下信息。这个问题能解决吗?或者采用其他方法一次性提供这些资源

    Error: Invalid for_each argument
    
      on ../../../../modules/nlb_new2/main.tf line 493, in resource "aws_lb_target_group_attachment" "tgr_attachment":
     493:   for_each = {
     494:           for pair in setproduct(keys(tomap({arn = lookup(aws_lb_target_group.main[0],"arn")})),  **var.target_id**) :
     495:           "${pair[0]},${pair[1]}" => {
     496:             target_group = aws_lb_target_group.main[0].arn
     497:             target       = length(split(":",pair[1])) > 0 ? split(":",pair[1])[0]: null
     498:             port         = length(split(":",pair[1])) == 2 ? split(":",pair[1])[1] : null
     499:           }
     500:     }
    
    #项目级main.tf

      region = lookup(var.lb_common_prop, "region", "us-east-1")
    }
    
    module "ec2_detail" {
      source = "../../../../modules/ec2_new2"
    
      for_each = var.ec2_detail
    
      instance_count = each.value.instance_count
    
      name =  format("%s-${var.ec2_name.suffix}",each.key)
      ami_name      = var.ec2_common_prop.ami_name
      instance_type = var.ec2_common_prop.instance_type
      subnet_id     = ""
      vpc_name      = var.ec2_common_prop.vpc_name
      
      subnet_names  = var.security.subnet_names
      vpc_security_group_names    = var.security.vpc_security_group_names
      
      associate_public_ip_address = var.ec2_common_prop.associate_public_ip_address
      tags                        = var.ec2_tags
      volume_tags                 = var.ec2_volume_tags
      key_name                    = var.ec2_common_prop.key_name
      user_data                   = ""
      iam_instance_profile        = var.ec2_common_prop.iam_instance_profile
      monitoring                  = var.ec2_common_prop.monitoring
      source_dest_check           = var.ec2_common_prop.source_dest_check
      placement_group             = var.ec2_common_prop.placement_group
      ebs_optimized               = var.ec2_common_prop.ebs_optimized
      disable_api_termination     = var.ec2_common_prop.disable_api_termination
      root_block_device = var.hardware.root_block_device
      ebs_block_device  = var.hardware.ebs_block_device
    
    }
    
    
    module "network_load_balancer" {
      depends_on=[module.ec2_detail]
      source = "../../../../modules/nlb_new2"
      
      for_each = var.all_load_balancer
      name = format("%s-${var.ec2_name.suffix}",each.key)
    
      load_balancer_type = each.value.load_balancer_type
    
      vpc_name      = var.ec2_common_prop.vpc_name
      subnet_names  = var.security.subnet_names
      internal      = lookup(merge(var.lb_tags, each.value.lb_tags), "internal", true)
       
      target_id = lookup(each.value.target_groups[0],"target_id",[])==[] ? [for pair in setproduct(module.ec2_detail["memsql-child"].private_ip, [lookup(var.lb_common_prop,"target_port")]) :  "${pair[0]}:${pair[1]}" ] : lookup(each.value.target_groups[0],"target_id",[])
      
      target_groups = each.value.target_groups
      http_tcp_listeners = each.value.http_tcp_listeners
      tags  = merge(var.lb_tags, each.value.lb_tags)
    }
    
    data aws_vpc "selected" {
        filter {
        name   = "tag:Name"
        values = [var.vpc_name] 
      }
    }
    
    data "aws_subnet_ids" "selected" {
      vpc_id=data.aws_vpc.selected.id
      filter {
        name   = "tag:Name"
        values = var.subnet_names
      }
    }
    
    #data "aws_subnet" "selected" {
    #  for_each = data.aws_subnet_ids.selected.ids
    #  id       = each.value
    #}
    
    resource "aws_lb" "this" {
      count = var.create_lb ? 1 : 0
    
      name        = var.name
      name_prefix = var.name_prefix
    
      load_balancer_type = var.load_balancer_type
      internal           = var.internal
      #security_groups    = var.security_groups
      
      #security_groups    = [for i in range(length(var.vpc_security_group_names)) : data.aws_security_group.selected.*.id[i]]
      
      #subnets            = var.subnets
      #subnets = [for s in data.aws_subnet_ids.selected : s.ids]
      subnets = data.aws_subnet_ids.selected.ids
    
      idle_timeout                     = var.idle_timeout
      enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
      enable_deletion_protection       = var.enable_deletion_protection
      enable_http2                     = var.enable_http2
      ip_address_type                  = var.ip_address_type
      drop_invalid_header_fields       = var.drop_invalid_header_fields
    
      # See notes in README (ref: https://github.com/terraform-providers/terraform-provider-aws/issues/7987)
      dynamic "access_logs" {
        for_each = length(keys(var.access_logs)) == 0 ? [] : [var.access_logs]
    
        content {
          enabled = lookup(access_logs.value, "enabled", lookup(access_logs.value, "bucket", null) != null)
          bucket  = lookup(access_logs.value, "bucket", null)
          prefix  = lookup(access_logs.value, "prefix", null)
        }
      }
    
      dynamic "subnet_mapping" {
        for_each = var.subnet_mapping
    
        content {
          subnet_id     = subnet_mapping.value.subnet_id
          allocation_id = lookup(subnet_mapping.value, "allocation_id", null)
        }
      }
    
      tags = merge(
        var.tags,
        var.lb_tags,
        {
          Name = var.name != null ? var.name : var.name_prefix
          "name" =  var.name != null ? var.name : var.name_prefix
        },
      )
    
      timeouts {
        create = var.load_balancer_create_timeout
        update = var.load_balancer_update_timeout
        delete = var.load_balancer_delete_timeout
      }
    }
    
    resource "aws_lb_target_group" "main" {
      count = var.create_lb ? length(var.target_groups) : 0
    
      name        = lookup(var.target_groups[count.index], "name", null)
      name_prefix = lookup(var.target_groups[count.index], "name_prefix", null)
      
      #vpc_id      = var.vpc_id
      vpc_id      = data.aws_vpc.selected.id
      port        = lookup(var.target_groups[count.index], "backend_port", null)
      protocol    = lookup(var.target_groups[count.index], "backend_protocol", null) != null ? upper(lookup(var.target_groups[count.index], "backend_protocol")) : null
      target_type = lookup(var.target_groups[count.index], "target_type", null)
    
      deregistration_delay               = lookup(var.target_groups[count.index], "deregistration_delay", null)
      slow_start                         = lookup(var.target_groups[count.index], "slow_start", null)
      proxy_protocol_v2                  = lookup(var.target_groups[count.index], "proxy_protocol_v2", false)
      lambda_multi_value_headers_enabled = lookup(var.target_groups[count.index], "lambda_multi_value_headers_enabled", false)
      load_balancing_algorithm_type      = lookup(var.target_groups[count.index], "load_balancing_algorithm_type", null)
    
      dynamic "health_check" {
        for_each = length(keys(lookup(var.target_groups[count.index], "health_check", {}))) == 0 ? [] : [lookup(var.target_groups[count.index], "health_check", {})]
    
        content {
          enabled             = lookup(health_check.value, "enabled", null)
          interval            = lookup(health_check.value, "interval", null)
          path                = lookup(health_check.value, "path", null)
          port                = lookup(health_check.value, "port", null)
          healthy_threshold   = lookup(health_check.value, "healthy_threshold", null)
          unhealthy_threshold = lookup(health_check.value, "unhealthy_threshold", null)
          timeout             = lookup(health_check.value, "timeout", null)
          protocol            = lookup(health_check.value, "protocol", null)
          matcher             = lookup(health_check.value, "matcher", null)
        }
      }
    
      dynamic "stickiness" {
        for_each = length(keys(lookup(var.target_groups[count.index], "stickiness", {}))) == 0 ? [] : [lookup(var.target_groups[count.index], "stickiness", {})]
    
        content {
          enabled         = lookup(stickiness.value, "enabled", null)
          cookie_duration = lookup(stickiness.value, "cookie_duration", null)
          type            = lookup(stickiness.value, "type", null)
        }
      }
    
      tags = merge(
        var.tags,
        {"stack-technology"       = "target-group"},
        var.target_group_tags,
        #lookup(var.target_groups[count.index], "tags", {}),
        {
          "Name" = format("%s${var.name}", lookup(var.target_groups[count.index], "name_prefix", ""))
          "name" =  format("%s${var.name}", lookup(var.target_groups[count.index], "name_prefix", "")) 
        },
      )
    
      depends_on = [aws_lb.this]
    
      lifecycle {
        create_before_destroy = true
      }
    }
    
    resource "aws_lb_listener_rule" "https_listener_rule" {
      count = var.create_lb ? length(var.https_listener_rules) : 0
    
      listener_arn = aws_lb_listener.frontend_https[lookup(var.https_listener_rules[count.index], "https_listener_index", count.index)].arn
      priority     = lookup(var.https_listener_rules[count.index], "priority", null)
    
      # authenticate-cognito actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "authenticate-cognito"
        ]
    
        content {
          type = action.value["type"]
          authenticate_cognito {
            authentication_request_extra_params = lookup(action.value, "authentication_request_extra_params", null)
            on_unauthenticated_request          = lookup(action.value, "on_authenticated_request", null)
            scope                               = lookup(action.value, "scope", null)
            session_cookie_name                 = lookup(action.value, "session_cookie_name", null)
            session_timeout                     = lookup(action.value, "session_timeout", null)
            user_pool_arn                       = action.value["user_pool_arn"]
            user_pool_client_id                 = action.value["user_pool_client_id"]
            user_pool_domain                    = action.value["user_pool_domain"]
          }
        }
      }
    
      # authenticate-oidc actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "authenticate-oidc"
        ]
    
        content {
          type = action.value["type"]
          authenticate_oidc {
            # Max 10 extra params
            authentication_request_extra_params = lookup(action.value, "authentication_request_extra_params", null)
            authorization_endpoint              = action.value["authorization_endpoint"]
            client_id                           = action.value["client_id"]
            client_secret                       = action.value["client_secret"]
            issuer                              = action.value["issuer"]
            on_unauthenticated_request          = lookup(action.value, "on_unauthenticated_request", null)
            scope                               = lookup(action.value, "scope", null)
            session_cookie_name                 = lookup(action.value, "session_cookie_name", null)
            session_timeout                     = lookup(action.value, "session_timeout", null)
            token_endpoint                      = action.value["token_endpoint"]
            user_info_endpoint                  = action.value["user_info_endpoint"]
          }
        }
      }
    
      # redirect actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "redirect"
        ]
    
        content {
          type = action.value["type"]
          redirect {
            host        = lookup(action.value, "host", null)
            path        = lookup(action.value, "path", null)
            port        = lookup(action.value, "port", null)
            protocol    = lookup(action.value, "protocol", null)
            query       = lookup(action.value, "query", null)
            status_code = action.value["status_code"]
          }
        }
      }
    
      # fixed-response actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "fixed-response"
        ]
    
        content {
          type = action.value["type"]
          fixed_response {
            message_body = lookup(action.value, "message_body", null)
            status_code  = lookup(action.value, "status_code", null)
            content_type = action.value["content_type"]
          }
        }
      }
    
      # forward actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "forward"
        ]
    
        content {
          type             = action.value["type"]
          target_group_arn = aws_lb_target_group.main[lookup(action.value, "target_group_index", count.index)].id
        }
      }
    
      # Path Pattern condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "path_patterns", [])) > 0
        ]
    
        content {
          path_pattern {
            values = condition.value["path_patterns"]
          }
        }
      }
    
      # Host header condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "host_headers", [])) > 0
        ]
    
        content {
          host_header {
            values = condition.value["host_headers"]
          }
        }
      }
    
      # Http header condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "http_headers", [])) > 0
        ]
    
        content {
          dynamic "http_header" {
            for_each = condition.value["http_headers"]
    
            content {
              http_header_name = http_header.value["http_header_name"]
              values           = http_header.value["values"]
            }
          }
        }
      }
    
      # Http request method condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "http_request_methods", [])) > 0
        ]
    
        content {
          http_request_method {
            values = condition.value["http_request_methods"]
          }
        }
      }
    
      # Query string condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "query_strings", [])) > 0
        ]
    
        content {
          dynamic "query_string" {
            for_each = condition.value["query_strings"]
    
            content {
              key   = lookup(query_string.value, "key", null)
              value = query_string.value["value"]
            }
          }
        }
      }
    
      # Source IP address condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "source_ips", [])) > 0
        ]
    
        content {
          source_ip {
            values = condition.value["source_ips"]
          }
        }
      }
    }
    
    
    resource "aws_lb_listener" "frontend_http_tcp" {
      count = var.create_lb ? length(var.http_tcp_listeners) : 0
    
      load_balancer_arn = aws_lb.this[0].arn
    
      port     = var.http_tcp_listeners[count.index]["port"]
      protocol = var.http_tcp_listeners[count.index]["protocol"]
    
      dynamic "default_action" {
        for_each = length(keys(var.http_tcp_listeners[count.index])) == 0 ? [] : [var.http_tcp_listeners[count.index]]
    
        # Defaults to forward action if action_type not specified
        content {
          type             = lookup(default_action.value, "action_type", "forward")
          target_group_arn = contains([null, "", "forward"], lookup(default_action.value, "action_type", "")) ? aws_lb_target_group.main[lookup(default_action.value, "target_group_index", count.index)].id : null
    
          dynamic "redirect" {
            for_each = length(keys(lookup(default_action.value, "redirect", {}))) == 0 ? [] : [lookup(default_action.value, "redirect", {})]
    
            content {
              path        = lookup(redirect.value, "path", null)
              host        = lookup(redirect.value, "host", null)
              port        = lookup(redirect.value, "port", null)
              protocol    = lookup(redirect.value, "protocol", null)
              query       = lookup(redirect.value, "query", null)
              status_code = redirect.value["status_code"]
            }
          }
    
          dynamic "fixed_response" {
            for_each = length(keys(lookup(default_action.value, "fixed_response", {}))) == 0 ? [] : [lookup(default_action.value, "fixed_response", {})]
    
            content {
              content_type = fixed_response.value["content_type"]
              message_body = lookup(fixed_response.value, "message_body", null)
              status_code  = lookup(fixed_response.value, "status_code", null)
            }
          }
        }
      }
    }
    
    resource "aws_lb_listener" "frontend_https" {
      count = var.create_lb ? length(var.https_listeners) : 0
    
      load_balancer_arn = aws_lb.this[0].arn
    
      port            = var.https_listeners[count.index]["port"]
      protocol        = lookup(var.https_listeners[count.index], "protocol", "HTTPS")
      certificate_arn = var.https_listeners[count.index]["certificate_arn"]
      ssl_policy      = lookup(var.https_listeners[count.index], "ssl_policy", var.listener_ssl_policy_default)
    
      dynamic "default_action" {
        for_each = length(keys(var.https_listeners[count.index])) == 0 ? [] : [var.https_listeners[count.index]]
    
        # Defaults to forward action if action_type not specified
        content {
          type             = lookup(default_action.value, "action_type", "forward")
          target_group_arn = contains([null, "", "forward"], lookup(default_action.value, "action_type", "")) ? aws_lb_target_group.main[lookup(default_action.value, "target_group_index", count.index)].id : null
    
          dynamic "redirect" {
            for_each = length(keys(lookup(default_action.value, "redirect", {}))) == 0 ? [] : [lookup(default_action.value, "redirect", {})]
    
            content {
              path        = lookup(redirect.value, "path", null)
              host        = lookup(redirect.value, "host", null)
              port        = lookup(redirect.value, "port", null)
              protocol    = lookup(redirect.value, "protocol", null)
              query       = lookup(redirect.value, "query", null)
              status_code = redirect.value["status_code"]
            }
          }
    
          dynamic "fixed_response" {
            for_each = length(keys(lookup(default_action.value, "fixed_response", {}))) == 0 ? [] : [lookup(default_action.value, "fixed_response", {})]
    
            content {
              content_type = fixed_response.value["content_type"]
              message_body = lookup(fixed_response.value, "message_body", null)
              status_code  = lookup(fixed_response.value, "status_code", null)
            }
          }
    
          # Authentication actions only available with HTTPS listeners
          dynamic "authenticate_cognito" {
            for_each = length(keys(lookup(default_action.value, "authenticate_cognito", {}))) == 0 ? [] : [lookup(default_action.value, "authenticate_cognito", {})]
    
            content {
              # Max 10 extra params
              authentication_request_extra_params = lookup(authenticate_cognito.value, "authentication_request_extra_params", null)
              on_unauthenticated_request          = lookup(authenticate_cognito.value, "on_authenticated_request", null)
              scope                               = lookup(authenticate_cognito.value, "scope", null)
              session_cookie_name                 = lookup(authenticate_cognito.value, "session_cookie_name", null)
              session_timeout                     = lookup(authenticate_cognito.value, "session_timeout", null)
              user_pool_arn                       = authenticate_cognito.value["user_pool_arn"]
              user_pool_client_id                 = authenticate_cognito.value["user_pool_client_id"]
              user_pool_domain                    = authenticate_cognito.value["user_pool_domain"]
            }
          }
    
          dynamic "authenticate_oidc" {
            for_each = length(keys(lookup(default_action.value, "authenticate_oidc", {}))) == 0 ? [] : [lookup(default_action.value, "authenticate_oidc", {})]
    
            content {
              # Max 10 extra params
              authentication_request_extra_params = lookup(authenticate_oidc.value, "authentication_request_extra_params", null)
              authorization_endpoint              = authenticate_oidc.value["authorization_endpoint"]
              client_id                           = authenticate_oidc.value["client_id"]
              client_secret                       = authenticate_oidc.value["client_secret"]
              issuer                              = authenticate_oidc.value["issuer"]
              on_unauthenticated_request          = lookup(authenticate_oidc.value, "on_unauthenticated_request", null)
              scope                               = lookup(authenticate_oidc.value, "scope", null)
              session_cookie_name                 = lookup(authenticate_oidc.value, "session_cookie_name", null)
              session_timeout                     = lookup(authenticate_oidc.value, "session_timeout", null)
              token_endpoint                      = authenticate_oidc.value["token_endpoint"]
              user_info_endpoint                  = authenticate_oidc.value["user_info_endpoint"]
            }
          }
        }
      }
    
      dynamic "default_action" {
        for_each = contains(["authenticate-oidc", "authenticate-cognito"], lookup(var.https_listeners[count.index], "action_type", {})) ? [var.https_listeners[count.index]] : []
        content {
          type             = "forward"
          target_group_arn = aws_lb_target_group.main[lookup(default_action.value, "target_group_index", count.index)].id
        }
      }
    }
    
    resource "aws_lb_listener_certificate" "https_listener" {
      count = var.create_lb ? length(var.extra_ssl_certs) : 0
    
      listener_arn    = aws_lb_listener.frontend_https[var.extra_ssl_certs[count.index]["https_listener_index"]].arn
      certificate_arn = var.extra_ssl_certs[count.index]["certificate_arn"]
    }
    
    
    resource "aws_lb_target_group_attachment" "tgr_attachment" {
        depends_on = [aws_lb.this]
        for_each = {
            for pair in setproduct(keys(tomap({arn = lookup(aws_lb_target_group.main[0],"arn")})),  var.target_id) :
            "${pair[0]},${pair[1]}" => {
              target_group = aws_lb_target_group.main[0].arn
              target       = length(split(":",pair[1])) > 0 ? split(":",pair[1])[0]: null
              port         = length(split(":",pair[1])) == 2 ? split(":",pair[1])[1] : null
            }
          }
          
        target_group_arn = var.create_lb ? each.value.target_group : null
        target_id        = var.create_lb ? each.value.target : null
        port             = var.create_lb ? each.value.port : null
            
    }
    

    #NLB模块main.tf

      region = lookup(var.lb_common_prop, "region", "us-east-1")
    }
    
    module "ec2_detail" {
      source = "../../../../modules/ec2_new2"
    
      for_each = var.ec2_detail
    
      instance_count = each.value.instance_count
    
      name =  format("%s-${var.ec2_name.suffix}",each.key)
      ami_name      = var.ec2_common_prop.ami_name
      instance_type = var.ec2_common_prop.instance_type
      subnet_id     = ""
      vpc_name      = var.ec2_common_prop.vpc_name
      
      subnet_names  = var.security.subnet_names
      vpc_security_group_names    = var.security.vpc_security_group_names
      
      associate_public_ip_address = var.ec2_common_prop.associate_public_ip_address
      tags                        = var.ec2_tags
      volume_tags                 = var.ec2_volume_tags
      key_name                    = var.ec2_common_prop.key_name
      user_data                   = ""
      iam_instance_profile        = var.ec2_common_prop.iam_instance_profile
      monitoring                  = var.ec2_common_prop.monitoring
      source_dest_check           = var.ec2_common_prop.source_dest_check
      placement_group             = var.ec2_common_prop.placement_group
      ebs_optimized               = var.ec2_common_prop.ebs_optimized
      disable_api_termination     = var.ec2_common_prop.disable_api_termination
      root_block_device = var.hardware.root_block_device
      ebs_block_device  = var.hardware.ebs_block_device
    
    }
    
    
    module "network_load_balancer" {
      depends_on=[module.ec2_detail]
      source = "../../../../modules/nlb_new2"
      
      for_each = var.all_load_balancer
      name = format("%s-${var.ec2_name.suffix}",each.key)
    
      load_balancer_type = each.value.load_balancer_type
    
      vpc_name      = var.ec2_common_prop.vpc_name
      subnet_names  = var.security.subnet_names
      internal      = lookup(merge(var.lb_tags, each.value.lb_tags), "internal", true)
       
      target_id = lookup(each.value.target_groups[0],"target_id",[])==[] ? [for pair in setproduct(module.ec2_detail["memsql-child"].private_ip, [lookup(var.lb_common_prop,"target_port")]) :  "${pair[0]}:${pair[1]}" ] : lookup(each.value.target_groups[0],"target_id",[])
      
      target_groups = each.value.target_groups
      http_tcp_listeners = each.value.http_tcp_listeners
      tags  = merge(var.lb_tags, each.value.lb_tags)
    }
    
    data aws_vpc "selected" {
        filter {
        name   = "tag:Name"
        values = [var.vpc_name] 
      }
    }
    
    data "aws_subnet_ids" "selected" {
      vpc_id=data.aws_vpc.selected.id
      filter {
        name   = "tag:Name"
        values = var.subnet_names
      }
    }
    
    #data "aws_subnet" "selected" {
    #  for_each = data.aws_subnet_ids.selected.ids
    #  id       = each.value
    #}
    
    resource "aws_lb" "this" {
      count = var.create_lb ? 1 : 0
    
      name        = var.name
      name_prefix = var.name_prefix
    
      load_balancer_type = var.load_balancer_type
      internal           = var.internal
      #security_groups    = var.security_groups
      
      #security_groups    = [for i in range(length(var.vpc_security_group_names)) : data.aws_security_group.selected.*.id[i]]
      
      #subnets            = var.subnets
      #subnets = [for s in data.aws_subnet_ids.selected : s.ids]
      subnets = data.aws_subnet_ids.selected.ids
    
      idle_timeout                     = var.idle_timeout
      enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
      enable_deletion_protection       = var.enable_deletion_protection
      enable_http2                     = var.enable_http2
      ip_address_type                  = var.ip_address_type
      drop_invalid_header_fields       = var.drop_invalid_header_fields
    
      # See notes in README (ref: https://github.com/terraform-providers/terraform-provider-aws/issues/7987)
      dynamic "access_logs" {
        for_each = length(keys(var.access_logs)) == 0 ? [] : [var.access_logs]
    
        content {
          enabled = lookup(access_logs.value, "enabled", lookup(access_logs.value, "bucket", null) != null)
          bucket  = lookup(access_logs.value, "bucket", null)
          prefix  = lookup(access_logs.value, "prefix", null)
        }
      }
    
      dynamic "subnet_mapping" {
        for_each = var.subnet_mapping
    
        content {
          subnet_id     = subnet_mapping.value.subnet_id
          allocation_id = lookup(subnet_mapping.value, "allocation_id", null)
        }
      }
    
      tags = merge(
        var.tags,
        var.lb_tags,
        {
          Name = var.name != null ? var.name : var.name_prefix
          "name" =  var.name != null ? var.name : var.name_prefix
        },
      )
    
      timeouts {
        create = var.load_balancer_create_timeout
        update = var.load_balancer_update_timeout
        delete = var.load_balancer_delete_timeout
      }
    }
    
    resource "aws_lb_target_group" "main" {
      count = var.create_lb ? length(var.target_groups) : 0
    
      name        = lookup(var.target_groups[count.index], "name", null)
      name_prefix = lookup(var.target_groups[count.index], "name_prefix", null)
      
      #vpc_id      = var.vpc_id
      vpc_id      = data.aws_vpc.selected.id
      port        = lookup(var.target_groups[count.index], "backend_port", null)
      protocol    = lookup(var.target_groups[count.index], "backend_protocol", null) != null ? upper(lookup(var.target_groups[count.index], "backend_protocol")) : null
      target_type = lookup(var.target_groups[count.index], "target_type", null)
    
      deregistration_delay               = lookup(var.target_groups[count.index], "deregistration_delay", null)
      slow_start                         = lookup(var.target_groups[count.index], "slow_start", null)
      proxy_protocol_v2                  = lookup(var.target_groups[count.index], "proxy_protocol_v2", false)
      lambda_multi_value_headers_enabled = lookup(var.target_groups[count.index], "lambda_multi_value_headers_enabled", false)
      load_balancing_algorithm_type      = lookup(var.target_groups[count.index], "load_balancing_algorithm_type", null)
    
      dynamic "health_check" {
        for_each = length(keys(lookup(var.target_groups[count.index], "health_check", {}))) == 0 ? [] : [lookup(var.target_groups[count.index], "health_check", {})]
    
        content {
          enabled             = lookup(health_check.value, "enabled", null)
          interval            = lookup(health_check.value, "interval", null)
          path                = lookup(health_check.value, "path", null)
          port                = lookup(health_check.value, "port", null)
          healthy_threshold   = lookup(health_check.value, "healthy_threshold", null)
          unhealthy_threshold = lookup(health_check.value, "unhealthy_threshold", null)
          timeout             = lookup(health_check.value, "timeout", null)
          protocol            = lookup(health_check.value, "protocol", null)
          matcher             = lookup(health_check.value, "matcher", null)
        }
      }
    
      dynamic "stickiness" {
        for_each = length(keys(lookup(var.target_groups[count.index], "stickiness", {}))) == 0 ? [] : [lookup(var.target_groups[count.index], "stickiness", {})]
    
        content {
          enabled         = lookup(stickiness.value, "enabled", null)
          cookie_duration = lookup(stickiness.value, "cookie_duration", null)
          type            = lookup(stickiness.value, "type", null)
        }
      }
    
      tags = merge(
        var.tags,
        {"stack-technology"       = "target-group"},
        var.target_group_tags,
        #lookup(var.target_groups[count.index], "tags", {}),
        {
          "Name" = format("%s${var.name}", lookup(var.target_groups[count.index], "name_prefix", ""))
          "name" =  format("%s${var.name}", lookup(var.target_groups[count.index], "name_prefix", "")) 
        },
      )
    
      depends_on = [aws_lb.this]
    
      lifecycle {
        create_before_destroy = true
      }
    }
    
    resource "aws_lb_listener_rule" "https_listener_rule" {
      count = var.create_lb ? length(var.https_listener_rules) : 0
    
      listener_arn = aws_lb_listener.frontend_https[lookup(var.https_listener_rules[count.index], "https_listener_index", count.index)].arn
      priority     = lookup(var.https_listener_rules[count.index], "priority", null)
    
      # authenticate-cognito actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "authenticate-cognito"
        ]
    
        content {
          type = action.value["type"]
          authenticate_cognito {
            authentication_request_extra_params = lookup(action.value, "authentication_request_extra_params", null)
            on_unauthenticated_request          = lookup(action.value, "on_authenticated_request", null)
            scope                               = lookup(action.value, "scope", null)
            session_cookie_name                 = lookup(action.value, "session_cookie_name", null)
            session_timeout                     = lookup(action.value, "session_timeout", null)
            user_pool_arn                       = action.value["user_pool_arn"]
            user_pool_client_id                 = action.value["user_pool_client_id"]
            user_pool_domain                    = action.value["user_pool_domain"]
          }
        }
      }
    
      # authenticate-oidc actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "authenticate-oidc"
        ]
    
        content {
          type = action.value["type"]
          authenticate_oidc {
            # Max 10 extra params
            authentication_request_extra_params = lookup(action.value, "authentication_request_extra_params", null)
            authorization_endpoint              = action.value["authorization_endpoint"]
            client_id                           = action.value["client_id"]
            client_secret                       = action.value["client_secret"]
            issuer                              = action.value["issuer"]
            on_unauthenticated_request          = lookup(action.value, "on_unauthenticated_request", null)
            scope                               = lookup(action.value, "scope", null)
            session_cookie_name                 = lookup(action.value, "session_cookie_name", null)
            session_timeout                     = lookup(action.value, "session_timeout", null)
            token_endpoint                      = action.value["token_endpoint"]
            user_info_endpoint                  = action.value["user_info_endpoint"]
          }
        }
      }
    
      # redirect actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "redirect"
        ]
    
        content {
          type = action.value["type"]
          redirect {
            host        = lookup(action.value, "host", null)
            path        = lookup(action.value, "path", null)
            port        = lookup(action.value, "port", null)
            protocol    = lookup(action.value, "protocol", null)
            query       = lookup(action.value, "query", null)
            status_code = action.value["status_code"]
          }
        }
      }
    
      # fixed-response actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "fixed-response"
        ]
    
        content {
          type = action.value["type"]
          fixed_response {
            message_body = lookup(action.value, "message_body", null)
            status_code  = lookup(action.value, "status_code", null)
            content_type = action.value["content_type"]
          }
        }
      }
    
      # forward actions
      dynamic "action" {
        for_each = [
          for action_rule in var.https_listener_rules[count.index].actions :
          action_rule
          if action_rule.type == "forward"
        ]
    
        content {
          type             = action.value["type"]
          target_group_arn = aws_lb_target_group.main[lookup(action.value, "target_group_index", count.index)].id
        }
      }
    
      # Path Pattern condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "path_patterns", [])) > 0
        ]
    
        content {
          path_pattern {
            values = condition.value["path_patterns"]
          }
        }
      }
    
      # Host header condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "host_headers", [])) > 0
        ]
    
        content {
          host_header {
            values = condition.value["host_headers"]
          }
        }
      }
    
      # Http header condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "http_headers", [])) > 0
        ]
    
        content {
          dynamic "http_header" {
            for_each = condition.value["http_headers"]
    
            content {
              http_header_name = http_header.value["http_header_name"]
              values           = http_header.value["values"]
            }
          }
        }
      }
    
      # Http request method condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "http_request_methods", [])) > 0
        ]
    
        content {
          http_request_method {
            values = condition.value["http_request_methods"]
          }
        }
      }
    
      # Query string condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "query_strings", [])) > 0
        ]
    
        content {
          dynamic "query_string" {
            for_each = condition.value["query_strings"]
    
            content {
              key   = lookup(query_string.value, "key", null)
              value = query_string.value["value"]
            }
          }
        }
      }
    
      # Source IP address condition
      dynamic "condition" {
        for_each = [
          for condition_rule in var.https_listener_rules[count.index].conditions :
          condition_rule
          if length(lookup(condition_rule, "source_ips", [])) > 0
        ]
    
        content {
          source_ip {
            values = condition.value["source_ips"]
          }
        }
      }
    }
    
    
    resource "aws_lb_listener" "frontend_http_tcp" {
      count = var.create_lb ? length(var.http_tcp_listeners) : 0
    
      load_balancer_arn = aws_lb.this[0].arn
    
      port     = var.http_tcp_listeners[count.index]["port"]
      protocol = var.http_tcp_listeners[count.index]["protocol"]
    
      dynamic "default_action" {
        for_each = length(keys(var.http_tcp_listeners[count.index])) == 0 ? [] : [var.http_tcp_listeners[count.index]]
    
        # Defaults to forward action if action_type not specified
        content {
          type             = lookup(default_action.value, "action_type", "forward")
          target_group_arn = contains([null, "", "forward"], lookup(default_action.value, "action_type", "")) ? aws_lb_target_group.main[lookup(default_action.value, "target_group_index", count.index)].id : null
    
          dynamic "redirect" {
            for_each = length(keys(lookup(default_action.value, "redirect", {}))) == 0 ? [] : [lookup(default_action.value, "redirect", {})]
    
            content {
              path        = lookup(redirect.value, "path", null)
              host        = lookup(redirect.value, "host", null)
              port        = lookup(redirect.value, "port", null)
              protocol    = lookup(redirect.value, "protocol", null)
              query       = lookup(redirect.value, "query", null)
              status_code = redirect.value["status_code"]
            }
          }
    
          dynamic "fixed_response" {
            for_each = length(keys(lookup(default_action.value, "fixed_response", {}))) == 0 ? [] : [lookup(default_action.value, "fixed_response", {})]
    
            content {
              content_type = fixed_response.value["content_type"]
              message_body = lookup(fixed_response.value, "message_body", null)
              status_code  = lookup(fixed_response.value, "status_code", null)
            }
          }
        }
      }
    }
    
    resource "aws_lb_listener" "frontend_https" {
      count = var.create_lb ? length(var.https_listeners) : 0
    
      load_balancer_arn = aws_lb.this[0].arn
    
      port            = var.https_listeners[count.index]["port"]
      protocol        = lookup(var.https_listeners[count.index], "protocol", "HTTPS")
      certificate_arn = var.https_listeners[count.index]["certificate_arn"]
      ssl_policy      = lookup(var.https_listeners[count.index], "ssl_policy", var.listener_ssl_policy_default)
    
      dynamic "default_action" {
        for_each = length(keys(var.https_listeners[count.index])) == 0 ? [] : [var.https_listeners[count.index]]
    
        # Defaults to forward action if action_type not specified
        content {
          type             = lookup(default_action.value, "action_type", "forward")
          target_group_arn = contains([null, "", "forward"], lookup(default_action.value, "action_type", "")) ? aws_lb_target_group.main[lookup(default_action.value, "target_group_index", count.index)].id : null
    
          dynamic "redirect" {
            for_each = length(keys(lookup(default_action.value, "redirect", {}))) == 0 ? [] : [lookup(default_action.value, "redirect", {})]
    
            content {
              path        = lookup(redirect.value, "path", null)
              host        = lookup(redirect.value, "host", null)
              port        = lookup(redirect.value, "port", null)
              protocol    = lookup(redirect.value, "protocol", null)
              query       = lookup(redirect.value, "query", null)
              status_code = redirect.value["status_code"]
            }
          }
    
          dynamic "fixed_response" {
            for_each = length(keys(lookup(default_action.value, "fixed_response", {}))) == 0 ? [] : [lookup(default_action.value, "fixed_response", {})]
    
            content {
              content_type = fixed_response.value["content_type"]
              message_body = lookup(fixed_response.value, "message_body", null)
              status_code  = lookup(fixed_response.value, "status_code", null)
            }
          }
    
          # Authentication actions only available with HTTPS listeners
          dynamic "authenticate_cognito" {
            for_each = length(keys(lookup(default_action.value, "authenticate_cognito", {}))) == 0 ? [] : [lookup(default_action.value, "authenticate_cognito", {})]
    
            content {
              # Max 10 extra params
              authentication_request_extra_params = lookup(authenticate_cognito.value, "authentication_request_extra_params", null)
              on_unauthenticated_request          = lookup(authenticate_cognito.value, "on_authenticated_request", null)
              scope                               = lookup(authenticate_cognito.value, "scope", null)
              session_cookie_name                 = lookup(authenticate_cognito.value, "session_cookie_name", null)
              session_timeout                     = lookup(authenticate_cognito.value, "session_timeout", null)
              user_pool_arn                       = authenticate_cognito.value["user_pool_arn"]
              user_pool_client_id                 = authenticate_cognito.value["user_pool_client_id"]
              user_pool_domain                    = authenticate_cognito.value["user_pool_domain"]
            }
          }
    
          dynamic "authenticate_oidc" {
            for_each = length(keys(lookup(default_action.value, "authenticate_oidc", {}))) == 0 ? [] : [lookup(default_action.value, "authenticate_oidc", {})]
    
            content {
              # Max 10 extra params
              authentication_request_extra_params = lookup(authenticate_oidc.value, "authentication_request_extra_params", null)
              authorization_endpoint              = authenticate_oidc.value["authorization_endpoint"]
              client_id                           = authenticate_oidc.value["client_id"]
              client_secret                       = authenticate_oidc.value["client_secret"]
              issuer                              = authenticate_oidc.value["issuer"]
              on_unauthenticated_request          = lookup(authenticate_oidc.value, "on_unauthenticated_request", null)
              scope                               = lookup(authenticate_oidc.value, "scope", null)
              session_cookie_name                 = lookup(authenticate_oidc.value, "session_cookie_name", null)
              session_timeout                     = lookup(authenticate_oidc.value, "session_timeout", null)
              token_endpoint                      = authenticate_oidc.value["token_endpoint"]
              user_info_endpoint                  = authenticate_oidc.value["user_info_endpoint"]
            }
          }
        }
      }
    
      dynamic "default_action" {
        for_each = contains(["authenticate-oidc", "authenticate-cognito"], lookup(var.https_listeners[count.index], "action_type", {})) ? [var.https_listeners[count.index]] : []
        content {
          type             = "forward"
          target_group_arn = aws_lb_target_group.main[lookup(default_action.value, "target_group_index", count.index)].id
        }
      }
    }
    
    resource "aws_lb_listener_certificate" "https_listener" {
      count = var.create_lb ? length(var.extra_ssl_certs) : 0
    
      listener_arn    = aws_lb_listener.frontend_https[var.extra_ssl_certs[count.index]["https_listener_index"]].arn
      certificate_arn = var.extra_ssl_certs[count.index]["certificate_arn"]
    }
    
    
    resource "aws_lb_target_group_attachment" "tgr_attachment" {
        depends_on = [aws_lb.this]
        for_each = {
            for pair in setproduct(keys(tomap({arn = lookup(aws_lb_target_group.main[0],"arn")})),  var.target_id) :
            "${pair[0]},${pair[1]}" => {
              target_group = aws_lb_target_group.main[0].arn
              target       = length(split(":",pair[1])) > 0 ? split(":",pair[1])[0]: null
              port         = length(split(":",pair[1])) == 2 ? split(":",pair[1])[1] : null
            }
          }
          
        target_group_arn = var.create_lb ? each.value.target_group : null
        target_id        = var.create_lb ? each.value.target : null
        port             = var.create_lb ? each.value.port : null
            
    }
    

    您的错误消息和代码示例似乎不完整,但尽管如此,我认为我可以看出问题的原因:您试图将目标组ARN用作
    aws\u lb\u target\u group\u attachment.tgr\u attachment
    的实例键的一部分,但ARN不适合用于实例密钥,因为提供者在创建每个对象之前不知道ARN值,因此在规划期间无法预测值

    相反,我建议将您的
    var.target\u组
    更改为对象的映射,而不是对象的列表,然后在
    aws\u lb\u target\u组.main中使用
    for\u each=var.target\u组
    。因此,模块的调用方可以为每个目标组指定一个有意义的名称,您可以将其用作
    aws\u lb\u target\u group\u attachment.tgr\u attachment
    的实例键的一部分:

    resource "aws_lb_target_group_attachment" "tgr_attachment" {
      for_each = {
        for pair in setproduct(keys(aws_lb_target_group.main), var.target_id) :
        "${pair[0]},${pair[1]}" => {
          target_group_arn = aws_lb_target_group.main[pair[0]].arn
          target           = length(split(":",pair[1])) > 0 ? split(":",pair[1])[0]: null
          port             = length(split(":",pair[1])) == 2 ? split(":",pair[1])[1] : null
        }
      }
    
      # ...
    }
    
    通过让模块的调用者为每个目标组指定一个键,可以让调用者控制对目标组集合的更改是否应理解为就地更新现有目标组、创建新目标组或删除现有目标组

    作为一个很好的副作用,您还可以为每个实例使用一个静态和稳定的标识符,这对于查看
    地形平面图
    输出的人来说是有意义的,并且即使将来的更改导致某个目标组被替换,也会保持一致