是否可以在 Terraform SDK v2 中将 DiffSuppressFunc 用于 TypeMap?

Is it possible to use DiffSuppressFunc for a TypeMap in Terraform SDK v2?

当我创建新属性时:

"foo": {
    Type: schema.TypeMap,
    Elem: &schema.Schema{
        Type: schema.TypeString,
    },
    Sensitive:   true,
    Required:    true,
    ForceNew:    false,
},

一切正常。但是,当我向其添加新的 属性 时:

DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
  return true
},

忽略状态和 main.tf 之间的每个变化(foo 属性 仅在 CREATE 上使用) d.Get("foo") 开始返回一个空映射,它超级混乱。一旦我删除 DiffSuppressFunc d.Get("foo") 就不再是空地图(如预期的那样)。

https://github.com/hashicorp/terraform-plugin-sdk/issues/477好像有关系

更新:问题似乎是 DiffSuppressFunc 被调用

"foo.%" "0" "2"

甚至在 d.Get().

之前

此 SDKv2 基于最初为非常旧版本的 Terraform(v0.11 及更早版本)编写的 SDK,因此它使用了一些不再适用的约定,其中包括您在其中资源类型的所有嵌套属性和复杂类型都被扁平化为从字符串到字符串的单个映射,特别是名为 foo 的映射属性,其值如 { a = 1, b = 2 } 最终被存储在 SDK 抽象中采用以下特殊方式:

"foo.%" = "2"
"foo.a" = "1"
"foo.b" = "2"

foo.% 元素既用于记录这是一个地图(与 foo.# 相对,后者表示列表),也用于记录地图中元素的数量,这会变成out 对地图不是很有用,但它是 SDK 如何处理列表的重要部分,因此它可以知道期望找到哪些索引。

不幸的是,这个实现细节在 DiffSuppressFunc 中显示出来,因为当 schema.ResourceData 对象已经被压平成上面的形状时,该特定功能在过程中处理得很晚,所以您在该函数中收到的是展平后的原始键和值。

因此,将 DiffSuppressFunc 与地图或列表属性一起使用并不实际或可靠。由于这个要求与 Terraform v0.11 的期望保持兼容,它可能永远不会。 HashiCorp 的一个团队一直在研究名为 Terraform Plugin Framework 的 SDKv2 的替代品,它从一开始就围绕类型系统和现代 Terraform 的假设而设计,因此它能够更好地以合理的方式支持复杂类型.

不幸的是,自 its design is still under consideration, but it is possible in principle to achieve a similar effect via plan modification 以来,新框架目前没有直接等同于 DiffSuppressFunc,尽管有更多的样板文件。在幕后,DiffSuppressFunc 所做的只是覆盖计划值以匹配先前状态而不是配置,Terraform 然后将其理解为配置和先前状态值是写下相同信息的两种不同方式。