You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform中如何仅对locals特定块应用for_each生成资源

解决方案:创建单个API Gateway + 多个Lambda函数

核心思路

将API Gateway与Lambda的创建逻辑拆分:

  • 单独实例化一次API Gateway模块,确保仅创建1个网关
  • 用for_each循环创建Lambda模块,生成2个独立的Lambda函数
  • 把Lambda的ARN传递给API Gateway,配置对应的集成路径实现关联

调整后的代码实现

1. 保留原有Locals配置

原locals中的lambda_apigateway和api_gateway_variables可直接复用:

locals {
  lambda_apigateway = {
    "digitalts-devtest-${var.environment}-auth" = {
      service_name          = "${var.environment}-auth"
      function_handler      = "auth.handler"
      lambda_key            = "customizedlayer.zip"
      function_name         = "${var.account}-${var.environment}"
      source_dir            = "../built/lambdahandlers/auth/"
      output_path           = "../auth.zip"
      layer_name            = var.layer_name
      create_lambda_layer   = var.create_lambda_layer
      layer_count           = var.layer_count
      filename              = var.filename
      environment_variables = {
        "MATRIS_CREDENTIALS" = "MATRIS_CLIENT"
      }
    },

    "digitalts-devtest-${var.environment}-healthz" = {
      service_name          = "${var.environment}-healthz"
      function_handler      = "healthz.handler"
      lambda_key            = "customizedlayer.zip"
      function_name         = "${var.account}-${var.environment}"
      source_dir            = "../built/lambdahandlers/healthz/"
      output_path           = "../healthz.zip"
      layer_name            = var.layer_name
      create_lambda_layer   = var.create_lambda_layer
      layer_count           = var.layer_count
      filename              = var.filename
      environment_variables = {
        "MATRIS_CREDENTIALS" = "MATRIS_CLIENT"
      }
    }
  }
    
  api_gateway_variables = {
    create_apigw_rest               = var.create_apigw_rest
    create_apigw                    = var.create_apigw
    api_gateway_name                = var.api_gateway_name
    endpoint_configuration          = var.endpoint_configuration
    parent_path                     = var.parent_path
    first_sub_path                  = var.first_sub_path
    http_methods                    = var.http_methods
    authorizations                  = var.authorizations
    request_parameters              = var.request_parameters
    request_models                  = var.request_models
    integration_http_methods        = var.integration_http_methods
    integration_types               = var.integration_types
    connection_types                = var.connection_types
  }
}

2. 单独创建API Gateway模块

调用模块时关闭Lambda相关创建开关,仅生成API Gateway资源:

module "api_gateway_dts" {
  source                  = "gitlab.***"
  version                 = "0.0.49"

  # 启用API Gateway创建逻辑
  create_apigw_rest               = local.api_gateway_variables.create_apigw_rest
  create_apigw                    = local.api_gateway_variables.create_apigw
  api_gateway_name                = local.api_gateway_variables.api_gateway_name
  endpoint_configuration          = local.api_gateway_variables.endpoint_configuration
  parent_path                     = local.api_gateway_variables.parent_path
  first_sub_path                  = local.api_gateway_variables.first_sub_path
  http_methods                    = local.api_gateway_variables.http_methods
  authorizations                  = local.api_gateway_variables.authorizations
  request_parameters              = local.api_gateway_variables.request_parameters
  request_models                  = local.api_gateway_variables.request_models
  integration_http_methods        = local.api_gateway_variables.integration_http_methods
  integration_types               = local.api_gateway_variables.integration_types
  connection_types                = local.api_gateway_variables.connection_types

  # 关闭Lambda相关创建开关
  create_lambda = false
}

3. 用for_each批量创建Lambda函数

基于local.lambda_apigateway循环生成2个Lambda,同时关闭API Gateway创建开关:

module "lambda_dts" {
  source                  = "gitlab.***"
  version                 = "0.0.49"

  for_each                = local.lambda_apigateway

  # 启用Lambda创建逻辑
  create_lambda                     = true
  create_lambda_permission          = true
  # 关闭API Gateway创建开关
  create_apigw_rest                 = false
  create_apigw                      = false

  # Lambda专属参数,从each.value中获取差异化配置
  service_name            = each.value.service_name
  lambda_key              = each.value.lambda_key
  function_name           = each.value.function_name
  source_dir              = each.value.source_dir
  output_path             = each.value.output_path
  runtime                 = var.runtime
  function_handler        = each.value.function_handler
  timeout                 = var.timeout
  memory_size             = var.memory_size
  environment_variables   = each.value.environment_variables
  subnet_ids              = var.subnet_ids
  VPCId                   = var.vpc_id
  env                     = var.env
  filename                = each.value.filename
  lambda_layer_bucket     = var.lambda_layer_bucket
  s3_key_lambda_layer     = var.s3_key_lambda_layer
  layer_count             = each.value.layer_count
}

4. 关联Lambda与API Gateway

通过原生Terraform资源手动配置API Gateway集成,将两个Lambda绑定到网关的对应路径:

# 绑定auth Lambda到API Gateway
resource "aws_api_gateway_integration" "auth" {
  rest_api_id             = module.api_gateway_dts.rest_api_id
  resource_id             = module.api_gateway_dts.resource_id
  http_method             = "POST"
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = module.lambda_dts["digitalts-devtest-${var.environment}-auth"].lambda_arn
}

# 绑定healthz Lambda到API Gateway
resource "aws_api_gateway_integration" "healthz" {
  rest_api_id             = module.api_gateway_dts.rest_api_id
  resource_id             = module.api_gateway_dts.resource_id
  http_method             = "GET"
  integration_http_method = "GET"
  type                    = "AWS_PROXY"
  uri                     = module.lambda_dts["digitalts-devtest-${var.environment}-healthz"].lambda_arn
}

关键注意事项

  • 模块开关控制:必须通过create_lambda、create_apigw等参数,确保API Gateway和Lambda模块各自只创建对应资源
  • 差异化变量:Lambda的function_handler要从each.value获取,两个Lambda的处理函数不同,不能复用全局变量
  • 集成配置:如果原有模块不支持单独添加集成,必须用原生aws_api_gateway_integration资源手动关联

内容的提问来源于stack exchange,提问作者Shafeeq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:47:03