【问题标题】:Terraform 0.11 list attribute compatible with terraform 0.12Terraform 0.11 列表属性与 terraform 0.12 兼容
【发布时间】:2019-11-28 17:27:21
【问题描述】:

我有一些共享的 terraform 模块,目前被许多基于 terraform 0.11 的项目使用。我想逐步将项目迁移到 0.12 并尝试保留模块与 0.11 和 0.12 的兼容性。 我在使用列表属性时遇到了问题,这些属性已经从括号语法中改变了。

在 terraform 0.11 中,需要在单个表达式周围加上方括号,以便向语言解释器提示需要列表解释:

# Example for older versions of Terraform; not valid for v0.12
example = ["${var.any_list}"]

在 terraform 0.12 中,像上面这样的表达式现在将生成列表列表,因此对于任何期望其他类型列表的参数都会产生类型检查错误。

# Example for Terraform v0.12
example = var.any_list

是否可以同时兼容 0.11 和 0.12 的方式设置 list 属性?

【问题讨论】:

  • 抱歉,这几乎是不可能的。不仅列表,而且几乎 hcl 语法已更改。如果您将 git 用于模块,我认为您最好将模块修改为 0.12 并制作新版本标签。比如 v1.x 支持 terraform 0.11 和 v2.x 支持 terraform 0.12。
  • @RyanKim 我正在使用 S3 来托管模块,因此必须在存储桶中单独创建 terraform 0.12 兼容版本。这是迄今为止我发现的唯一不兼容 hcl1 的东西。

标签: terraform


【解决方案1】:

原则上,不用多余的括号编写它应该在 Terraform 0.11 和 0.12 中都可以工作,如下所示:

example = "${var.any_list}"

不幸的是,由于 Terraform 0.11 的限制,如果 var.any_list 包含任何在计划时未知的值,这将失败,因为 Terraform 0.11 不会将未知值视为有效列表。多余的额外括号是该限制的常见解决方法,但不是有意的功能:除了该错误之外,自 Terraform 0.7 以来就不再需要冗余列表括号,并且仅支持与 Terraform 0.6 及更早版本的向后兼容性。

话虽如此,如果您的列表确实包含未知值,那么不幸的是,没有办法编写与这两个版本兼容的内容。最接近的方法是使用像上面这样的形式,使用插值语法但没有括号,然后在第一次应用时使用 -target 强制 Terraform 创建 var.any_list 依赖的任何资源 first em>,然后在随后的应用中,该列表中应该没有未知值,因此它应该能够成功完成。这与 count 中出现未知值时的原理相同,即使在 Terraform 0.12 中也是不允许的。

【讨论】:

    【解决方案2】:

    这种棘手的方法适用于 0.11 和 0.12,

    example = "${flatten(var.any_list)}"
    

    我在 aws_security_group 中针对 terraform v0.11.14 和 v0.12.4 使用 cidr_blocks 进行了测试

    variable  "test" {
      default = ["10.10.0.0/16", "10.20.0.0/16"]
    }
    
    resource "aws_security_group" "test" {
      ingress {
        from_port   = 443
        to_port     = 443
        protocol    = "TCP"
    
        cidr_blocks = "${flatten(var.test)}"
      }
    }
    

    【讨论】:

    • 这适用于 terrafom 0.12,但不适用于 terraform 0.11,它会生成一个字符串值列表,但仍需要括号告诉解释器它是一个列表。
    • @Glen,我测试了 terraform 0.11.14 和 0.12.4,并在 aws_security_group 中测试了 cidr_blocks,`locals{ test = ["10.10.0.0/16", "10.20.0.0/16"] } 资源 "aws_security_group" "test" { ingress { from_port = 443 to_port = 443 协议 = "TCP" cidr_blocks = "${flatten(local.test)}" } } ` 你在哪里使用它?
    • 我用 0.11.13 试过了,但没用。我遇到了意外的属性类型错误。
    猜你喜欢
    • 2019-11-24
    • 2020-06-30
    • 1970-01-01
    • 2020-07-21
    • 2019-11-05
    • 2019-10-22
    • 2020-12-28
    • 1970-01-01
    • 2020-01-16
    相关资源
    最近更新 更多