【问题标题】:For loop in terraform地形中的for循环
【发布时间】:2022-01-19 07:13:13
【问题描述】:

我正在尝试从 local.tf 获取函数名称的值,但我无法获取它。我有 terraform,tfvars,我在其中给出了函数名称,然后将其传递给 variable.tf。从 varibale.tf 我将其传递给 local.tf,然后传递给 main.tf。我无法在 main.tf 中获取函数名称。任何帮助,将不胜感激。 terraform.tfvars

config = {
  s3= {
//s3 configurations
}
  s3_notifications = {
      function_name         = "test-lambda-mary"
    }
}

变量.tf

variable "config" {
  type        = any
  description = "S3 configuration block"
}

local.tf

  function_name = {
    for k, v in var.config :
    k => lookup(v, "function_name", "")
  }
module "all_notifications" {
  source   = "terraform-aws-modules/s3-bucket/aws//modules/notification"
  for_each = var.config
  bucket   = module.s3_bucket[each.key].this_s3_bucket_id

  lambda_notifications = {
    lambda = {
      function_name = local.function_name[each.key]
      function_arn  = "arn:aws:lambda:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:function:${local.function_name[each.key]}"
      events        = ["s3:ObjectCreated:*"]

    }
  }
}

错误

"function_name" doesn't comply with restrictions ("^(arn:[\\w-]+:lambda:)?([a-z]{2}-(?:[a-z]+-){1,2}\\d{1}:)?(\\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\\$LATEST|[a-zA-Z0-9-_]+))?$"): ""
│ 
│   with module.all_notifications["s3"].aws_lambda_permission.allow["lambda"],
│   on .terraform/modules/all_notifications/modules/notification/main.tf line 63, in resource "aws_lambda_permission" "allow":
│   63:   function_name       = each.value.function_name

【问题讨论】:

  • 好的,但是有什么问题?有什么错误吗?
  • @Marcin 我在问题中添加了错误
  • 如果我把 function_name 放在 s3 大括号中,它工作得很好,但我需要在 s3_notification 中有函数名称
  • 很遗憾你的问题不清楚。 each.keymodule.s3_bucket 是什么?您能否为您使用的所有变量提供值?
  • 它创建多个 s3 存储桶并向其添加通知

标签: amazon-web-services amazon-s3 aws-lambda terraform


【解决方案1】:

如果我将 function_name 放在 s3 大括号中,它绝对可以正常工作,但我需要在 s3_notification 中包含函数名称

这看起来是一个很好的提示。您正在迭代 var.config,它有 2 个键,其中只有 1 个定义了 function_name。因此,当使用 s3 作为键请求模块时,该键的 function_value 将为空字符串,AWS 将按预期失败请求。

您可以过滤for_each = var.config 以排除这种情况,例如:

for_each = { for k, v in var.config: k => v if local.function_name[each.key] != ""}

一点点挑剔:似乎模块的源代码可能写错了。而不是terraform-aws-modules/s3-bucket/aws//modules/notification 可能应该是terraform-aws-modules/terraform-aws-s3-bucket//modules/notification。见https://github.com/terraform-aws-modules/terraform-aws-s3-bucket

【讨论】:

  • 是的,你没看错,var.config 有两个变量,你能帮我看看你提供的解决方案是正确的格式,但我需要用我的格式。我正在循环访问 local.tf 中的变量,如下所示`function_name = { for k, v in var.config : k => lookup(v, "function_name", "") }` 如何调整两者之间的 if 条件?
  • 您可以通过添加if lookup(v, "function_name", "") != "" 来调整条件,以便local.function_name 中只有1 个元素。但是,您需要在模块上调整 for_each,因为它将被调用 2 次,而 local 只有 1 个项目。如果您为 module.s3_bucket 添加缺少的代码,尤其是它为其 for_loop 使用的变量,那将是一个更明确的问题。
  • 当我添加这个function_name = { for k, v in var.config : k => if lookup(v, "function_name", "") != "" }它给我这个错误Error: Invalid 'for' expression │ │ on locals.tf line 17, in locals: │ 15: function_name = { │ 16: for k, v in var.config : │ 17: k => if lookup(v, "function_name", "") != "" │ │ Extra characters after the end of the 'for' expression.
【解决方案2】:

因为我以前没有使用过那个模块,所以在黑暗中刺伤。

但是通过查看您的错误消息:

"function_name" doesn't comply with restrictions ("^(arn:[\\w-]+:lambda:)?

对于function_name,您应该传递 Lambda 的 ARN,而不是名称(与变量名称所说的相反)。

顺便说一句,function_arn 是这里的参数吗?

【讨论】:

    【解决方案3】:

    出现此错误是因为 terraform 模块需要一个有效且强制的函数名称来使用 terraform-aws-modules/s3-bucket/aws//modules/notification 模块创建 [aws_lambda_permission][1] 资源。

    在您的情况下,您在 var.config 上循环模块,该模块由 s3 和 s3_notifications 部分组成,并且在第一次迭代时,它的函数名称为 null,因此它抛出此错误。

    "function_name" doesn't comply with restrictions ("^(arn:[\\w-]+:lambda:)?([a-z]{2}-(?:[a-z]+-){1,2}\\d{1}:)?(\\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\\$LATEST|[a-zA-Z0-9-_]+))?$"): ""
    

    最好将特定于 s3_notification 的变量拆分为列表,并使用 count 迭代模块,如下所示。

    variable "s3_config" {
      type = any
      default = {
        s3 = {
    
        }
      }
    }
    
    variable "s3_notify_lambda_func" {
      type = list
      default = ["test-lambda-mary","test"]. #N Numbers of functions
    }
    
    data "aws_region" "current" {}
    data "aws_caller_identity" "current" {}
    
    module "all_notifications" {
      source   = "terraform-aws-modules/s3-bucket/aws//modules/notification"
      count = length(var.s3_notify_lambda_func) > 0 ? length(var.s3_notify_lambda_func) : 0
      bucket   = module.s3_bucket[count.index].this_s3_bucket_id
    
      lambda_notifications = {
        lambda = {
          function_name = var.s3_notify_lambda_func[count.index]
          function_arn  = "arn:aws:lambda:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:function:${var.s3_notify_lambda_func[count.index]}"
          events        = ["s3:ObjectCreated:*"]
    
        }
      }
    }
     
    

    【讨论】:

      猜你喜欢
      • 2020-02-06
      • 1970-01-01
      • 2020-05-25
      • 2011-10-18
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 2012-11-11
      相关资源
      最近更新 更多