[超意译] 从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
以上就是。