输出中每个参考索引的Terraform

发布于 2025-02-07 21:08:36 字数 2861 浏览 3 评论 0原文

我有一个模块,在该模块中,我可以使用for_each生成几个lambdas。

resource "aws_lambda_function" "profile" {
  for_each = local.lambdas

  function_name = each.value.lambda_name
  role          = var.lambda_assume_role_arn
  image_uri     = each.value.ecr_repository_uri
  package_type  = "Image"

  vpc_config {
    security_group_ids = [var.rds_security_group_id]
    subnet_ids         = var.subnet_ids
  }
}

我需要在输出中导出

output "aws_lambda_function_pre_sign_up_arn" {
  value       = aws_lambda_function.profile[9].arn
}

output "aws_lambda_function_post_confirmation_arn" {
  value       = aws_lambda_function.profile[0].arn
}

╷
│ Error: Invalid index
│ 
│   on ../modules/services/profile/ouptput.tf line 2, in output "aws_lambda_function_pre_sign_up_arn":
│    2:   value       = aws_lambda_function.profile[9]
│     ├────────────────
│     │ aws_lambda_function.profile is object with 10 attributes
│ 
│ The given key does not identify an element in this collection value. An object only supports looking up attributes by name, not by numeric index.
╵
╷
│ Error: Invalid index
│ 
│   on ../modules/services/profile/ouptput.tf line 7, in output "aws_lambda_function_post_confirmation_arn":
│    7:   value       = aws_lambda_function.profile[0]
│     ├────────────────
│     │ aws_lambda_function.profile is object with 10 attributes
│ 
│ The given key does not identify an element in this collection value. An object only supports looking up attributes by name, not by numeric index.
╵

这些生成的lambdas中的两个 总共有10个。

locals {
  service = "profile"
  lambdas = {
    assign_default_group = {
      lambda_name                  = "${lower(var.company)}-${local.service}-${var.environment}-assign_default_group",
      ecr_repository_name          = "${lower(var.company)}/${local.service}/${var.environment}/lambda/assign_default_group",
      ecr_repository_uri           = "xxx.dkr.ecr.${var.region}.amazonaws.com/${lower(var.company)}/${local.service}/${var.environment}/lambda/assign_default_group:latest"
      lambda_environment_variables = {
        RDS_STORAGE_URL      = var.storage_url
        COGNITO_USER_POOL_ID = jsondecode(data.aws_secretsmanager_secret_version.profile.secret_string)["cognito_user_pool_id"]
      }
    },
    create_account = {
      lambda_name                  = "${lower(var.company)}-${local.service}-${var.environment}-create_account",
      ecr_repository_name          = "${lower(var.company)}/${local.service}/${var.environment}/lambda/create_account",
      ecr_repository_uri           = "xxx.dkr.ecr.${var.region}.amazonaws.com/${lower(var.company)}/${local.service}/${var.environment}/lambda/create_account:latest"
      lambda_environment_variables = {
        RDS_STORAGE_URL = var.storage_url
      }
    },
...

I have a module where I am generating several lambdas programmatically using for_each.

resource "aws_lambda_function" "profile" {
  for_each = local.lambdas

  function_name = each.value.lambda_name
  role          = var.lambda_assume_role_arn
  image_uri     = each.value.ecr_repository_uri
  package_type  = "Image"

  vpc_config {
    security_group_ids = [var.rds_security_group_id]
    subnet_ids         = var.subnet_ids
  }
}

Two of these generated lambdas I need to to export in output.tf

output "aws_lambda_function_pre_sign_up_arn" {
  value       = aws_lambda_function.profile[9].arn
}

output "aws_lambda_function_post_confirmation_arn" {
  value       = aws_lambda_function.profile[0].arn
}

When I apply I get an error:

╷
│ Error: Invalid index
│ 
│   on ../modules/services/profile/ouptput.tf line 2, in output "aws_lambda_function_pre_sign_up_arn":
│    2:   value       = aws_lambda_function.profile[9]
│     ├────────────────
│     │ aws_lambda_function.profile is object with 10 attributes
│ 
│ The given key does not identify an element in this collection value. An object only supports looking up attributes by name, not by numeric index.
╵
╷
│ Error: Invalid index
│ 
│   on ../modules/services/profile/ouptput.tf line 7, in output "aws_lambda_function_post_confirmation_arn":
│    7:   value       = aws_lambda_function.profile[0]
│     ├────────────────
│     │ aws_lambda_function.profile is object with 10 attributes
│ 
│ The given key does not identify an element in this collection value. An object only supports looking up attributes by name, not by numeric index.
╵

Here is a snippet of what the locals look like. There are 10 entires in all.

locals {
  service = "profile"
  lambdas = {
    assign_default_group = {
      lambda_name                  = "${lower(var.company)}-${local.service}-${var.environment}-assign_default_group",
      ecr_repository_name          = "${lower(var.company)}/${local.service}/${var.environment}/lambda/assign_default_group",
      ecr_repository_uri           = "xxx.dkr.ecr.${var.region}.amazonaws.com/${lower(var.company)}/${local.service}/${var.environment}/lambda/assign_default_group:latest"
      lambda_environment_variables = {
        RDS_STORAGE_URL      = var.storage_url
        COGNITO_USER_POOL_ID = jsondecode(data.aws_secretsmanager_secret_version.profile.secret_string)["cognito_user_pool_id"]
      }
    },
    create_account = {
      lambda_name                  = "${lower(var.company)}-${local.service}-${var.environment}-create_account",
      ecr_repository_name          = "${lower(var.company)}/${local.service}/${var.environment}/lambda/create_account",
      ecr_repository_uri           = "xxx.dkr.ecr.${var.region}.amazonaws.com/${lower(var.company)}/${local.service}/${var.environment}/lambda/create_account:latest"
      lambda_environment_variables = {
        RDS_STORAGE_URL = var.storage_url
      }
    },
...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九厘米的零° 2025-02-14 21:08:36

如评论中所述,不可能使用for_each meta-argument创建的资源使用索引[1]。如果需要使用索引,则应使用计数 Meta-argument [2]。如果您决定继续使用for_each,则可以以以下方式获取所需的输出:

output "aws_lambda_function_pre_sign_up_arn" {
  value       = aws_lambda_function.profile["first_key"].arn
}

output "aws_lambda_function_post_confirmation_arn" {
  value       = aws_lambda_function.profile["last_key"].arn
}

因为我不知道哪个键是第一个键(我猜nistion_default_group)这是最后一个(为了举例来说,让我们使用create_account),以上变为:

output "aws_lambda_function_pre_sign_up_arn" {
  value       = aws_lambda_function.profile["assign_default_group"].arn
}

output "aws_lambda_function_post_confirmation_arn" {
  value       = aws_lambda_function.profile["create_account"].arn
}

但是基于输出名称,可能有一个键nasy post_confirmation和一个名为pre_sign_up的键,因此您可以将其用作钥匙值。

如果您需要获取许多lambda函数(无论是ARN还是其他)的特定属性,则可以执行以下操作:

output "lambda_arns" {
  value = {
    for k, v in aws_lambda_function.profile : k => v.arn
  }
}

这将返回键/值对的地图,其中键将再次成为键本地变量lambdas,该值将是lambda函数。

另外,您可以将value内置函数[3]与splat表达式[4]一起派生,而返回结果将为列表(在其中您可以通过索引值引用元素):

output "lambda_arns" {
  value = values(aws_lambda_function.profile)[*].arn
}

获取值的方法可能有更多不同的方法,但取决于您想要获得的输出类型。


[1] https://wwww.terraform.io/language /meta-arguments/for_each#referring to-instances

[2] https://www.terraform.io/language/meta-arguments/count#referring-to-instances

[3]语言/函数/值“ rel =” nofollow noreferrer”> https://www.terraform.io/language/functions/vunctions/values

[4] https://www.terraform.io/language/language/expressions/splat

As mentioned in the comments, using indexes with resources created with for_each meta-argument is not possible [1]. If using indexes is required then count meta-argument should be used [2]. If you decide to proceed with using for_each, you could fetch the desired outputs in the following way:

output "aws_lambda_function_pre_sign_up_arn" {
  value       = aws_lambda_function.profile["first_key"].arn
}

output "aws_lambda_function_post_confirmation_arn" {
  value       = aws_lambda_function.profile["last_key"].arn
}

Since I do not know which key is first (I'm guessing assign_default_group) and which is the last (for the sake of example, let's go with create_account), the above becomes:

output "aws_lambda_function_pre_sign_up_arn" {
  value       = aws_lambda_function.profile["assign_default_group"].arn
}

output "aws_lambda_function_post_confirmation_arn" {
  value       = aws_lambda_function.profile["create_account"].arn
}

But based on the output name, there is probably a key named post_confirmation and a key named pre_sign_up, so you can use that as the key values.

If you need to fetch a certain attribute for a number of Lambda functions (whether it is ARN or something else), you could do the following:

output "lambda_arns" {
  value = {
    for k, v in aws_lambda_function.profile : k => v.arn
  }
}

This will return a map of key/value pairs, where key will again be a key from the local variable lambdas and the value will be the Lambda function ARN.

Alternatively, you could use the values built-in function [3] with the splat expression [4] to derive only values and the return result will be a list (where you could reference elements by index value):

output "lambda_arns" {
  value = values(aws_lambda_function.profile)[*].arn
}

There could be more different ways to get the values but it depends on the type of output you would like to get.


[1] https://www.terraform.io/language/meta-arguments/for_each#referring-to-instances

[2] https://www.terraform.io/language/meta-arguments/count#referring-to-instances

[3] https://www.terraform.io/language/functions/values

[4] https://www.terraform.io/language/expressions/splat

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文