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
相关产品推荐
相关产品推荐

