我想让 for_each 仅应用于 locals 中的一块代码,而不是全部内容。

huangapple go评论57阅读模式
英文:

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 块在这里不起作用,在一个模块中正如文档中所述

> 您可以使用一种特殊的动态块类型,在resourcedataproviderprovisioner块内支持动态构建可重复嵌套块[...]。

方法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 &quot;lambda_API_dts&quot; {
source = &quot;gitlab.***&quot;
version = &quot;0.0.49&quot;
# digitalts-devtest auth, healthz
dynamic &quot;lambda_apigateway&quot; {
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
}

huangapple
  • 本文由 发表于 2023年3月31日 22:13:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定