Terraform 创造怪异 for_each

Terraform create weird for_each

我想创建一个 for_each 循环,它只在数组中具有特定键值对的对象上循环。

我的输入变量是:

inputs = {
  names = ["first", "second"]
  lifecycle_rules = [
    {
      name = first
      condition = {
        age = "1"
      }
      action = {
        type = "Delete"
      }
    },{
      condition = {
        age = "2"
      }
      action = {
        type = "Delete"
      }
    },
    {
      name = second
      condition = {
        age = "3"
      }
      action = {
        type = "Delete"
      }
    },{
      condition = {
        age = "4"
      }
      action = {
        type = "Delete"
      }
    }
  ]

并且在我的 main.tf 中(顺便说一句,用于部署 gcp 存储桶以供参考),我想将每个存储桶的生命周期分开,并且只想应用其中包含存储桶名称的规则。

因此,如果有人知道如何修改下面的 for_each 代码以使其正常工作,我将不胜感激。我相信只有 for_each 需要更改才能遍历正确的元素(比方说只有该列表中名称 = 第一的对象)。来自var.lifecycle_rules

  resource "google_storage_bucket" "buckets" {
    count         = length(var.names)
    name          = "${lower(element(var.names, count.index))}"
...
    dynamic "lifecycle_rule" {
     #for_each = length(lookup(lifecycle_rules[lookup(element(var.names, count.index))])
     for_each = lifecycle_rules
     content {
       action {
         type          = lifecycle_rule.value.action.type
         storage_class = lookup(lifecycle_rule.value.action, "storage_class", null)
       }
       condition {
         #age = lifecycle_rule.value.name == element(var.names, count.index) ? lookup(lifecycle_rule.value.condition, "age", null) : null
         age = lookup(lifecycle_rule.value.condition, "age", null) : null
...

我认为这种“奇怪”的外观可以分两个阶段获得。

  1. 根据names
  2. lifecycle_rules重组为地图
variable "input" {

  default = {
  names = ["first", "second"],
  
  lifecycle_rules = [
    {
      name = "first",
      condition = {
        age = "1"
      },
      action = {
        type = "Delete"
      }
    },
    {
      condition = {
        age = "2"
      },
      action = {
        type = "Delete"
      }
    },
    {
      name = "second",
      condition = {
        age = "3"
      },
      action = {
        type = "Delete"
      }
    },
    {
      condition = {
        age = "4"
      },
      action = {
        type = "Delete"
      }
    }
  ]
  }

}



locals {

  new = {
    for name in var.input.names:  
       name => [for rule in var.input.lifecycle_rules: 
        contains(keys(rule), "name" ) ? 
          rule.name == name ? rule: null : 
          null ] 
  }    
}


这将以以下形式给出 local.new

{                                                        
  "first" = [            
    {                 
      "action" = {       
        "type" = "Delete"
      }              
      "condition" = { 
        "age" = "1"
      }                  
      "name" = "first"
    },                   
    null,          
    null,                
    null,                
  ]                  
  "second" = [           
    null,          
    null,                
    {                  
      "action" = {       
        "type" = "Delete"
      }              
      "condition" = {  
        "age" = "3"
      }                
      "name" = "second"
    },   
    null,
  ]
}  

  1. 执行for_each
  resource "google_storage_bucket" "buckets" {

    for_each = toset(var.input.names)  

    name          = each.key

    dynamic "lifecycle_rule" {

      # iterate for each name skipping null values
      for_each = [for v in local.new[each.key]: v if v != null]
  
      content {
        action {
           type          = lifecycle_rule.value["action"].type
           storage_class = lookup(lifecycle_rule.value["action"], "storage_class", null)
         }

        condition {
            age = lookup( tag.value["condition"], "age", null) 
         }
      }
   }
}

我只能验证第一步和部分第二步(使用 aws_autoscaling_group 及其多个 tag 组件)。我无法访问 google 云来全面测试代码。