英文:
I want for_each to be applied only to a block of code in locals and not to everything
问题
我正在使用Terraform创建AWS API Gateway和2个Lambda函数。
我想知道在使用模块时是否有一种方法可以仅对locals
中的特定块应用for_each
。对于模块中的其余变量,我希望它们要么从variables.tf
中获取,要么从locals
中获取:
以下是我的代码:
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
uri = var.uri
}
}
我尝试了以下代码,但它将for_each
应用于locals
中的所有内容:
module "lambda_API_dts" {
source = "gitlab.***"
version = "0.0.49"
for_each = local.lambda_apigateway
service_name = each.key
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 = var.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 = var.filename
lambda_layer_bucket = var.lambda_layer_bucket
s3_key_lambda_layer = var.s3_key_lambda_layer
layer_count = each.value.layer_count
# API Gateway variables
create_apigw_rest = local.create_apigw_rest
create_apigw = local.create_apigw
api_gateway_name = local.api_gateway_name
endpoint_configuration = local.endpoint_configuration
parent_path = local.parent_path
first_sub_path = local.first_sub_path
http_methods = local.http_methods
authorizations = local.authorizations
request_parameters = local.request_parameters
request_models = local.request_models
integration_http_methods = local.integration_http_methods
integration_types = local.integration_types
connection_types = local.connection_types
uri = local.uri
}
我希望只创建1个API Gateway和2个Lambda函数。
英文:
I'm using Terraform to create an AWS API Gateway and 2 Lambda functions.
I would like to know if there is a way to apply for_each
to only a particular block from locals
while using the modules. For the remaining variables in modules, I want it to either pick up from variables.tf
or from locals:
Below is my code:
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
#layers = var.layers
layer_count = var.layer_count
filename = var.filename
#create_lambda_permission = var.create_lambda_permission
#create_lambda = var.create_lambda
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
#layers = var.layers
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
uri = var.uri
}
}
I tried the following code but it is applying the for_each
to all of the locals:
module "lambda_API_dts" {
source = "gitlab.***"
version = "0.0.49"
for_each = local.lambda_apigateway
service_name = each.key
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 = var.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 = var.filename
lambda_layer_bucket = var.lambda_layer_bucket
s3_key_lambda_layer = var.s3_key_lambda_layer
layer_count = each.value.layer_count
#api gateway variables
create_apigw_rest = local.create_apigw_rest
create_apigw = local.create_apigw
api_gateway_name = local.api_gateway_name
endpoint_configuration = local.endpoint_configuration
parent_path = local.parent_path
first_sub_path = local.first_sub_path
http_methods = local.http_methods
authorizations = local.authorizations
request_parameters = local.request_parameters
request_models = local.request_models
integration_http_methods = local.integration_http_methods
integration_types = local.integration_types
connection_types = local.connection_types
uri = local.uri
}
I want only 1 API gateway to be created & 2 Lambdas to be created.
答案1
得分: 2
@Shlomi,dynamic
块在这里不起作用,在一个模块中,正如文档中所述:
> 您可以使用一种特殊的动态块类型,在resource
、data
、provider
和provisioner
块内支持动态构建可重复嵌套块[...]。
方法1:将for_each
移至资源定义
如果出于特定原因要保持根模块不变,您可以在子模块中使用for_each
来循环所需的资源。下面是根模块和子模块的示例:
./main.tf
:
module "lambda_API_dts" {
source = "gitlab.***"
version = "0.0.49"
# 传递对象映射到模块 #############
lambda_apigateway = local.lambda_apigateway
runtime = var.runtime
function_handler = var.function_handler
timeout = var.timeout
memory_size = var.memory_size
subnet_ids = var.subnet_ids
VPCId = var.vpc_id
env = var.env
filename = var.filename
lambda_layer_bucket = var.lambda_layer_bucket
s3_key_lambda_layer = var.s3_key_lambda_layer
#api gateway 变量
[...]
}
./modules/lambda_API_dts/main.tf
:
[...]
resource "aws_lambda_function" "test_lambda" {
for_each = var.lambda_apigateway
[...aws_lambda_function 属性...]
}
[...]
方法2:按目的拆分您的模块
在这里,您的lambda_API_dts
模块似乎用于创建 AWS API 网关和 AWS Lambda 函数。
如果您确实需要在调用模块中使用for_each
块,您可以保留在那里,但也可以将for_each
放在资源级别,在resource
块中,使用我在方法1中的示例。
.
├── api-gw
│ ─── main.tf
├── lambda-functions
│ ─── main.tf
└── main.tf
这样,您将:
- 拥有两个各自具有其自己变量和行为的模块
- 能够在这里放置所有的 Lambda 函数,而不仅仅是您的"API 网关"函数
希望这有所帮助!
英文:
@Shlomi, dynamic
blocks won't work here, in a module, as said in the documentation :
> You can dynamically construct repeatable nested blocks [...] using a special dynamic block type, which is supported inside resource
, data
, provider
, and provisioner
blocks
Method 1 : Deport the for_each
to the resource definition
If you want to keep the root module as is for a particular reason, you can use for_each
in the child module to loop on the desired resource. Below, you'll find the root module & the child module :
./main.tf
:
module "lambda_API_dts" {
source = "gitlab.***"
version = "0.0.49"
# Pass you map of objects to your module #############
lambda_apigateway = local.lambda_apigateway
runtime = var.runtime
function_handler = var.function_handler
timeout = var.timeout
memory_size = var.memory_size
subnet_ids = var.subnet_ids
VPCId = var.vpc_id
env = var.env
filename = var.filename
lambda_layer_bucket = var.lambda_layer_bucket
s3_key_lambda_layer = var.s3_key_lambda_layer
#api gateway variables
[...]
}
./modules/lambda_API_dts/main.tf
:
[...]
resource "aws_lambda_function" "test_lambda" {
for_each = var.lambda_apigateway
[...aws_lambda_function properties...]
}
[...]
Method 2 : Split your modules by purpose
Here, your lambda_API_dts
module seems to have the purpose of creating a AWS API gateway AND AWS lambda functions.
If you really need to have your for_each
block in the calling module, you can keep it there but you can also put the for_each
at the resource level, in the resource
block, using my example in Method 1.
.
├── api-gw
│   └── main.tf
├── lambda-functions
│   └── main.tf
└── main.tf
This way, you will :
- have your 2 modules that will have their own variables & behavior
- be able to put all your lambda functions here, not only your "API gateway" ones
Hope this helps !
答案2
得分: 0
{
"Try using dynamic as follows": "尝试如下使用 dynamic:",
"module "lambda_API_dts" {": "模块 "lambda_API_dts" {",
"source = "gitlab.***"": "source = "gitlab.***"",
"version = "0.0.49"": "version = "0.0.49"",
"# digitalts-devtest auth, healthz": "# digitalts-devtest 认证、healthz",
"dynamic "lambda_apigateway" {": "dynamic "lambda_apigateway" {",
"for_each = local.lambda_apigateway": "for_each = local.lambda_apigateway",
"service_name = lambda_apigateway.key": "service_name = lambda_apigateway.key",
"lambda_key = lambda_apigateway.value.lambda_key": "lambda_key = lambda_apigateway.value.lambda_key",
"function_name = lambda_apigateway.value.function_name": "function_name = lambda_apigateway.value.function_name",
"source_dir = lambda_apigateway.value.source_dir": "source_dir = lambda_apigateway.value.source_dir",
"output_path = lambda_apigateway.value.output_path": "output_path = lambda_apigateway.value.output_path",
"runtime = var.runtime": "runtime = var.runtime",
"function_handler = var.function_handler": "function_handler = var.function_handler",
"timeout = var.timeout": "timeout = var.timeout",
"memory_size = var.memory_size": "memory_size = var.memory_size",
"environment_variables = lambda_apigateway.value.environment_variables": "environment_variables = lambda_apigateway.value.environment_variables",
"subnet_ids = var.subnet_ids": "subnet_ids = var.subnet_ids",
"VPCId = var.vpc_id": "VPCId = var.vpc_id",
"env = var.env": "env = var.env",
"filename = var.filename": "filename = var.filename",
"lambda_layer_bucket = var.lambda_layer_bucket": "lambda_layer_bucket = var.lambda_layer_bucket",
"s3_key_lambda_layer = var.s3_key_lambda_layer": "s3_key_lambda_layer = var.s3_key_lambda_layer",
"layer_count = lambda_apigateway.value.layer_count": "layer_count = lambda_apigateway.value.layer_count",
"#api gateway variables": "#API 网关变量",
"create_apigw_rest = local.create_apigw_rest": "create_apigw_rest = local.create_apigw_rest",
"create_apigw = local.create_apigw": "create_apigw = local.create_apigw",
"api_gateway_name = local.api_gateway_name": "api_gateway_name = local.api_gateway_name",
"endpoint_configuration = local.endpoint_configuration": "endpoint_configuration = local.endpoint_configuration",
"parent_path = local.parent_path": "parent_path = local.parent_path",
"first_sub_path = local.first_sub_path": "first_sub_path = local.first_sub_path",
"http_methods = local.http_methods": "http_methods = local.http_methods",
"authorizations = local.authorizations": "authorizations = local.authorizations",
"request_parameters = local.request_parameters": "request_parameters = local.request_parameters",
"request_models = local.request_models": "request_models = local.request_models",
"integration_http_methods = local.integration_http_methods": "integration_http_methods = local.integration_http_methods",
"integration_types = local.integration_types": "integration_types = local.integration_types",
"connection_types = local.connection_types": "connection_types = local.connection_types",
"uri = local.uri": "uri = local.uri"
}
英文:
<br />
Try using dynamic as follows:
module "lambda_API_dts" {
source = "gitlab.***"
version = "0.0.49"
# digitalts-devtest auth, healthz
dynamic "lambda_apigateway" {
for_each = local.lambda_apigateway
content {
service_name = lambda_apigateway.key
lambda_key = lambda_apigateway.value.lambda_key
function_name = lambda_apigateway.value.function_name
source_dir = lambda_apigateway.value.source_dir
output_path = lambda_apigateway.value.output_path
runtime = var.runtime
function_handler = var.function_handler
timeout = var.timeout
memory_size = var.memory_size
environment_variables = lambda_apigateway.value.environment_variables
subnet_ids = var.subnet_ids
VPCId = var.vpc_id
env = var.env
filename = var.filename
lambda_layer_bucket = var.lambda_layer_bucket
s3_key_lambda_layer = var.s3_key_lambda_layer
layer_count = lambda_apigateway.value.layer_count
}
}
#api gateway variables
create_apigw_rest = local.create_apigw_rest
create_apigw = local.create_apigw
api_gateway_name = local.api_gateway_name
endpoint_configuration = local.endpoint_configuration
parent_path = local.parent_path
first_sub_path = local.first_sub_path
http_methods = local.http_methods
authorizations = local.authorizations
request_parameters = local.request_parameters
request_models = local.request_models
integration_http_methods = local.integration_http_methods
integration_types = local.integration_types
connection_types = local.connection_types
uri = local.uri
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论