[超意译] 从Terraform v0.6系升级到v0.7的指南

我翘首以待的Terraform v0.7已经发布了!!

Hashicorp社的博客中也发布了版本信息。
https://www.hashicorp.com/blog/terraform-0-7.html

由于本次更新包含了许多重要的功能添加或修改,因此提供了升级指南。
https://www.terraform.io/upgrade-guides/0-7.html

关于升级问题,下面是我留下的意译备忘录。(请参考上方的升级指南以获取更详细的信息!)

插件二进制文件

在0.6版本之前,二进制文件按如下方式分割。

terraform               # core binary
terraform-provider-*    # provider plugins
terraform-provisioner-* # provisioner plugins

这些二进制文件应该被放置在$PATH环境变量已设置的位置,或者放置在~/.terraform.d目录下。

在0.7版本中,这些二进制文件已被整合,成为了单一的terraform二进制文件。

请在升级时替换terraform二进制文件,然后删除terraform-provider-*和terraform-provisioner-*二进制文件。

我自己的解釋

关于不包括在Terraform内建提供程序/预设的外部插件,仍然采用二进制分割的方式。

    • Terraform for さくらのクラウド(terraform-provider-sakuracloudバイナリ)

 

    Terraform for Arukas(terraform-provider-arukasバイナリ)

以下是一种选项的中文表述方式:
这些是一如既往的方法,只要将$PATH设置为正确位置或者将其放在~/.terraform.d目录下即可。

展示计划中的地图

以前,数组的元素数量是用#表示的。
从现在开始,列表将用#表示,而映射将用%表示。

somelist.#:  "0" => "1"
somelist.0:  "" => "someitem"
somemap.%:   "0" => "1"
somemap.foo: "" => "bar"

字符串连接

在0.7系列中,concat()函数只能用于数组合并,不再支持字符串合并。如果尝试在字符串上使用,将会报错。

"${concat(var.foo, "-suffix")}"     # => Error! No longer supported.

对于字符列的情况,可以按照以下方式处理。

"${var.foo}-suffix"

嵌套引号和转义

以前我们可以为了保证后向兼容性而进行以下的写法,但是从现在开始将会发生错误。

"${lookup(var.somemap, \"somekey\")}"  # => Syntax Error!

只要按照以下的方式写就可以了,在${}的内部会成为一个新的引用上下文。

"${lookup(var.somemap, "somekey")}"

如果您想在字符串内部使用双引号,请进行转义。

"${upper("\"quoted\"")}"    # => "QUOTED"

在这里,您指定了一个包含双引号”quoted”的字符作为upper()函数的参数。在这种情况下需要进行转义处理。

更安全的地球改造计划行为

在0.6版本之前,执行terraform plan时可能会导致状态文件被更新。
terraform plan会刷新资源状态(通过API等方式重新获取信息),
但在此时可能会导致状态文件被覆写。

在0.7版本中,这个方面有所改进,plan可以在没有副作用的情况下(即无需更新state文件)执行。执行apply或refresh会更新state文件。

迁移到数据源

在0.7版本中,新增了数据源功能。它类似于只读资源。

因此,一些资源已被标记为不推荐使用。(仍可使用,但会出现警告)

以下资源已被弃用。

    • atlas_artifact

 

    • template_file

 

    • template_cloudinit_config

 

    tls_cert_request

只需将以下资源关键字部分更改为”data”即可将这些资源与数据源对应起来。

改變前:

resource "template_file" "example" {
  template = "someconfig"
}
resource "aws_instance" "example" {
  user_data = "${template_file.example.rendered}" 
  # ...
}

修改后:

data "template_file" "example" {
  template = "someconfig"
}
resource "aws_instance" "example" {
  user_data = "${template_file.example.rendered}" 
  # ...
}

迁移到本地的列表和地图

在0.7版本中,List和Map被视为一等公民对象。
以前通过join()和split()等方式来模拟数组的表示现在变得直观、简洁地表达出来了。

0.6版本中的写作方式

例如,关于模块的输出,由于以前只能返回一个值,所以我们通过使用join()将其伪装成逗号分隔的字符串等来模拟数组处理。

output "private_subnets" {
  value = "${join(",", aws_subnet.private.*.id)}"
}

使用这个值的一方,将其通过split()函数从以逗号分隔的字符串拆分,并将其转换为数组后再使用。

subnet_id = "${element(split(",", var.private_subnets), count.index)}"

注:element([列表],索引)是一个返回指定数组中索引位置的元素的函数。

0.7版本的写法是什么?

在0.7版本中,现在可以直接返回数组。

output "private_subnets" {
  value = ["${aws_subnet.private.*.id}"]
}

由于该值的使用方也可以使用[]语法,因此编写起来更加直观。

subnet_id = "${var.private_subnets[count.index]}"

这些不仅可以应用于模块,还可以应用于变量等。

赠品

可以继续使用element函数。与[]相比,它允许指定超过数组元素数量的值。
例如,如果指定如下:

subnet_id = "${element(var.private_subnets, count.index)}"

如果指定的索引大于或等于private_subnets的长度,会对其进行取模操作。例如,当索引为3时,取的是private_subnets[0];当索引为4时,取的是private_subnets[1],以此类推。

地图值覆盖

过去,我们在覆盖map变量时使用逗号分隔的方式进行名称指定。

以以下变量定义为例,

variable "amis" {
  type = "map"
  default = {
    us-east-1 = "ami-123456"
    us-west-2 = "ami-456789"
    eu-west-1 = "ami-789123"
  }
}

使用命令行选项以”-var” “amis.us-west-2=overriden_value”的格式进行覆盖设定。(环境变量和tfvar文件也是一样的设置方式)

在0.7版本中,这将被修改为以下形式。

-var 'amis = { us-west-2 = "overriden_value" }'

map类型的变量将合并默认值和通过命令行等指定的值。
先前的变量定义将变为以下的值。

{
  us-east-1 = "ami-123456"  
  us-west-2 = "overriden_value"
  eu-west-1 = "ami-789123"
}

注意が必要です。これまでの書き方である「var “amis.us-west-2=overriden_value”」を使用してもエラーが発生しないかもしれませんが、変数の上書きはできないようです。terraform planを実行するだけでは気付くことができない可能性もありますので、この部分には注意が必要です。

terraform.tfvarsファイルでの指定

-var-fileフラグで指定しているファイル
環境変数TF_VAR_[name]など

请问可能是哪几个呢?

请参考官方文档:variables,了解有关变量定义和覆盖方法的详细信息。

其他注意事项(作者补充说明)

错误示例1:

在升级时可能会出现以下类似的错误。

Error configuring: 1 error(s) occurred:

* Unrecognized remote plugin message: 2|unix|/var/folders/wh/5gklk3s17hn9c60827qnkgk99999gn/T/tf-plugin9999999

This usually means that the plugin is either invalid or simply
needs to be recompiled to support the latest protocol.

如果这些插件(terraform-provider-*二进制文件或terraform-provisioner-*二进制文件)的版本过旧,将会显示这个。

我们需要确认一下0.6系列的插件的二进制文件是否还存在。(有可能插件本身不支持0.7系列的情况,如果是这样的话,我们可以向对应插件开发者提交问题)

错误示例2:

Error configuring: 1 error(s) occurred:

* Incompatible API version with plugin. Plugin version: 1, Ours: 2

只要使用的Terraform版本过旧,即使插件是0.7版本,也会出现这个问题。请运行terraform version命令,确认Terraform本体确实是0.7系列。

结束

在Terraform v0.7中,各种功能变得更易用。

特別是在import方面,具有强大的功能。
参考文章:Terraform v0.7引领着“基础设施即代码”的世界。

此外,由于List/Map的使用范围已扩大,使得更容易进行模块化。在这个新版本的基础上,请务必尝试使用Terraform进行基础设施即代码化!

我也请多关照!当然支持Terraform v0.7。

    • Terraform for さくらのクラウド

 

    Terraform for Arukas

以上就是。

广告
将在 10 秒后关闭
bannerAds