Terraform 具有动态列表的地形将在索引更改时重新创建资源

Terraform 具有动态列表的地形将在索引更改时重新创建资源,terraform,Terraform,使用动态列表时,如果添加或删除条目,则更改索引后的每个条目都将更新。 如何让terraform仅插入新条目 例子 我有一张单子 十, 二十 三十 (地形适用) 现在将我的列表更改为添加15 十, 十五 二十 三十 (地形适用) Terraform将替换20->15,30->20并创建30 简单解 一种解决方案是单独声明每个元素(不使用列表) 复杂的解决方法 在应用之前,我可以直接更改状态文件以更改索引。 这似乎很危险 更多上下文 我有一个包含数百个dns条目的json数据文件。 我使用d

使用动态列表时,如果添加或删除条目,则更改索引后的每个条目都将更新。
如何让terraform仅插入新条目

例子 我有一张单子

  • 十,
  • 二十
  • 三十
(地形适用)

现在将我的列表更改为添加15

  • 十,
  • 十五
  • 二十
  • 三十
(地形适用) Terraform将替换20->15,30->20并创建30

简单解 一种解决方案是单独声明每个元素(不使用列表)

复杂的解决方法 在应用之前,我可以直接更改状态文件以更改索引。 这似乎很危险

更多上下文 我有一个包含数百个dns条目的json数据文件。 我使用data.external将其加载到列表中

data "external" "read_dns_entries" {
   program = [ "${path.module}/terraform_script_dns_entries_from_file" ]
}

locals {
  file_dns_records_without_aliases = jsondecode(data.external.read_dns_entries.result.EntriesWithoutAlias)
}

resource "aws_route53_record" "record" {
  count = length(local.file_dns_records_without_aliases)

  zone_id         = local.file_dns_records_without_aliases[count.index].ZoneID
  name            = local.file_dns_records_without_aliases[count.index].Name
  type            = local.file_dns_records_without_aliases[count.index].Type
  allow_overwrite = true
  ttl             = local.file_dns_records_without_aliases[count.index].TTL
  records         = local.file_dns_records_without_aliases[count.index].Records

  lifecycle {
    create_before_destroy = true
  }
}
我使用的是
terraformv0.12.18

工具书类 这个封闭的话题正在谈论它。

这是希望Terraform 0.12能够为每个_

P>如果你可以使用TyRaFr.x,x或更新,考虑选择< /P>

  • 而不是
    计数
  • 用地图代替输入数据表示的列表(因为每个都在地图上运行)
  • 可以使用
    {for item in list:key=>value}
    表达式(请参阅)从列表中组成映射。与按位置跟踪资源的
    count
    相反,
    for\u each
    按id(映射键)跟踪资源状态的表示。由于随着新资源的插入或移除,职位会不断变化/转移,因此这是一个相当脆弱的结构。这就是为什么在资源列表中进行洗牌、插入或删除之后,人们会注意到许多销毁/创建计划的操作;)

    作为记录,这里有一个关于cleaner设置的片段:

    data "external" "read_dns_entries" {
      program = ["${path.module}/terraform_script_dns_entries_from_file"]
    }
    
    locals {
      #file_dns_records_without_aliases = jsondecode(data.external.read_dns_entries.result.EntriesWithoutAlias)
      file_dns_records_without_aliases = {
        for entry in jsondecode(data.external.read_dns_entries.result.EntriesWithoutAlias) :
        entry.Name => entry
      }
    }
    
    resource "aws_route53_record" "record" {
      # count = length(local.file_dns_records_without_aliases)
      for_each = local.file_dns_records_without_aliases
    
      zone_id         = each.value.ZoneID
      name            = each.value.Name
      type            = each.value.Type
      allow_overwrite = true
      ttl             = each.value.TTL
      records         = each.value.Records
    
      lifecycle {
        create_before_destroy = true
      }
    }
    

    注:这里似乎不太习惯使用data.external,可以使用
    文件(${path.module}/terraform\u script\u dns\u entries\u from\u file”)
    更清楚,因为其目的仅仅是读取文件的内容。

    另一种解决方案,我也可以获得现有的条目,并相应地列出我的列表。如果我有新的东西:在末尾加上。但是如果我需要删除第一个条目,我仍然会遇到同样的问题=>所有内容都会被重新创建。这是解决我问题的完美方法。事实上,我会为每个人使用
    。非常感谢。