Terraform ";对于“每个人”;值取决于无法确定的资源属性(地形)

Terraform ";对于“每个人”;值取决于无法确定的资源属性(地形),terraform,Terraform,我有一个地形配置,需要: 创建一个lambda 调用lambda 迭代lambda的json结果,该结果返回一个数组,并为数组中的每个条目创建一个CloudWatch事件规则 相关代码如下所示: Create lambda code... data "aws_lambda_invocation" "run_lambda" { function_name = "${aws_lambda_function.deployed_lambda.fun

我有一个地形配置,需要:

  • 创建一个lambda
  • 调用lambda
  • 迭代lambda的json结果,该结果返回一个数组,并为数组中的每个条目创建一个CloudWatch事件规则
  • 相关代码如下所示:

    Create lambda code...
    
    data "aws_lambda_invocation" "run_lambda" {
      function_name = "${aws_lambda_function.deployed_lambda.function_name}"
    
      input = <<JSON
      {}
      JSON
      depends_on = [aws_lambda_function.deployed_lambda]
    }
    
    resource "aws_cloudwatch_event_rule" "aws_my_cloudwatch_rule" {
      for_each = {for record in jsondecode(data.aws_lambda_invocation.run_lambda.result).entities : record.entityName => record} 
        name = "${each.value.entityName}-event"
        description = "Cloudwatch rule for ${each.value.entityName}"
        schedule_expression = "cron(${each.value.cronExpression})"
    }
    
    我读了很多关于这个问题的帖子,但找不到解决办法。
    问题是Terraform需要在创建lambda之前,在规划阶段知道lambda返回的数组的大小。
    解决此类任务的最佳方法是什么?

    由于它是作为CI/CD管道的一部分运行的,我更喜欢不包含“-target”标志的解决方案。

    如果您想在纯地形中解决这个问题,目前的解决方法是将部署拆分为多个堆栈/阶段(例如,首先使用lambda部署堆栈,然后使用lambda作为数据源的第二个堆栈)或者如您已经发现的,使用
    -target
    部分部署堆栈,然后部署整个堆栈。(在这种情况下,请确保删除
    取决于
    ,因为它会一直将数据源的读取延迟到应用阶段。)

    另一种选择是使用这样的工具来解决部分应用问题,如果定义了这些模块之间的所有依赖项,那么可以按正确的顺序部署一组terraform模块。使用
    terragrunt
    可以在一次运行中部署所有内容,例如
    terragrunt apply all
    。缺点是您仍然无法获得一个好的p审查CI中的更改,以供同行审查


    我建议将其分为两个阶段,因为在应用最终更改之前,您可能真的希望对这两个阶段进行检查。否则,您可能会遇到一个设置,即损坏的lambda会导致在您或您的团队未注意到的情况下销毁所有现有的cloudwatch规则。

    一种可能性是重新考虑每个规则的ong>并在适当的情况下使用计数对于每个都有一些主要的限制。我遇到了类似的情况(对我来说似乎是一个主要的错误,但他们说这是一个功能) 考虑我正在部署三个VM,并希望将它们绑定到负载均衡器:

    resource "aws_instance" "xxx-IIS-004" {
    
      ami               = var.ami["Windows Server 2019"]
      instance_type     = var.depoy_lowcost ? var.default_instance_type : "m5.2xlarge"
      count             = "3"
      ...
    
    当我尝试使用for_each时,我得到的“for_each”值取决于无法确定的资源属性…或元组错误

    失败:

    resource "aws_elb_attachment" "attachments_004" {
      depends_on = [ aws_instance.xxx-IIS-004 ]
      elb        = data.aws_elb.loadBalancer.id
      for_each   = aws_instance.xxx-IIS-004[*]
      instance   = each.value.id
    }
    
    有效*

    locals {
      att_004 = join("_", aws_instance.xxx-IIS-004[*].id )
    }
    
    resource "aws_elb_attachment" "attachments_004" {
      depends_on = [ aws_instance.xxx-IIS-004 ]
      elb        = data.aws_elb.loadBalancer.id
      count      = length( aws_instance.xxx-IIS-004 )
      instance   = split("_", local.att_004)[count.index]
    }
    

    作为一个注释,请确保aws提供程序>3。我在2.x上遇到了这个错误,我升级了提供程序并修复了它。同样值得一提的是,如果你这样做,这是一个重大升级,所以请小心操作。
    locals {
      att_004 = join("_", aws_instance.xxx-IIS-004[*].id )
    }
    
    resource "aws_elb_attachment" "attachments_004" {
      depends_on = [ aws_instance.xxx-IIS-004 ]
      elb        = data.aws_elb.loadBalancer.id
      count      = length( aws_instance.xxx-IIS-004 )
      instance   = split("_", local.att_004)[count.index]
    }