地形中的for循环

Posted

技术标签:

【中文标题】地形中的for循环【英文标题】:For loop in terraform 【发布时间】: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\\d1:)?(\\d12:)?(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 存储桶并向其添加通知 【参考方案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\\d1:)?(\\d12:)?(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:*"]

    
  

 

【讨论】:

以上是关于地形中的for循环的主要内容,如果未能解决你的问题,请参考以下文章

JS中如何解决for循环中的延迟执行问题

Java中的增强for循环怎么用?for()中的参数是啥意思

C语言中的for循环

python 双层for循环,在第二层的for循环中的else中的continue,会退出到第一层for循环继续执行

python中的for循环相当于scratch中的啥循环?

for循环求和中的for循环正在覆盖数据值python