预置器是由Terraform所提供的另一组插件,每种预置器可以在资源对象创建后执行不同类型的操作。
使用预置器需要节制,因为他们采取的操作并非Terraform声明式的风格,所以Terraform无法对他们执行的变更进行建模和保存。
预置器也可以声明为资源销毁前执行,但会有一些限制。
作为元参数,provisioner和connection可以声明在任意类型的resource块内。
举一个例子:
resource "aws_instance" "web" {
# ...
provisioner "file" {
source = "conf/myapp.conf"
destination = "/etc/myapp.conf"
connection {
type = "ssh"
user = "root"
password = var.root_password
host = self.public_ip
}
}
}
我们在aws_instance中定义了类型为file的预置器,该预置器可以本机文件或文件夹拷贝到目标机器的指定路径下。我们在预置器内部定义了connection块,类型是ssh。我们对connection的host赋值self.public_ip,在这里self代表预置器所在的母块,也就是aws_instance.web,所以self.public_ip代表着aws_instance.web.public_ip,也就是创建出来的主机的公网ip。
file类型预置器支持ssh和winrm两种类型的connection。
预置器根据运行的时机分为两种类型,创建时预置器以及销毁时预置器。
创建时预置器
默认情况下,资源对象被创建时会运行预置器,在对象更新、销毁时则不会运行。预置器的默认行为时为了引导一个系统。
如果创建时预置器失败了,那么资源对象会被标记污点(我们将在介绍terraform taint命令时详细介绍)。一个被标记污点的资源在下次执行terraform apply命令时会被销毁并重建。Terrform的这种设计是因为当预置器运行失败时标志着资源处于半就绪的状态。由于Terraform无法衡量预置器的行为,所以唯一能够完全确保资源被正确初始化的方式就是删除重建。
我们可以通过设置on_failure参数来改变这种行为。
销毁时预置器
如果我们设置预置器的when参数为destroy,那么预置器会在资源被销毁时执行:
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
when = destroy
command = "echo 'Destroy-time provisioner'"
}
}
销毁时预置器在资源被实际销毁前运行。如果运行失败,Terraform会报错,并在下次运行terraform apply操作时重新执行预置器。在这种情况下,需要仔细关注销毁时预置器以使之能够安全地反复执行。
销毁时预置器只有在存在于代码中的情况下才会在销毁时被执行。如果一个resource块连带内部的销毁时预置器块一起被从代码中删除,那么被删除的预置器在资源被销毁时不会被执行。要解决这个问题,我们需要使用多个步骤来绕过这个限制:
修改资源声明代码,添加count = 0参数
执行terraform apply,运行删除时预置器,然后删除资源实例
删除resource块
重新执行terraform apply,此时应该不会有任何变更需要执行
该限制在未来将会得到解决,但目前来说我们必须节制使用销毁时预置器。
预置器失败行为
默认情况下,预置器运行失败会导致terraform apply执行失败。可以通过设置on_failure参数来改变这一行为。可以设置的值为:
continue:忽视错误,继续执行创建或是销毁
fail:报错并终止执行变更(这是默认行为)。如果这是一个创建时预置器,则在对应资源对象上标记污点
样例:
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
on_failure = continue
}
}
本地资源
虽然大部分资源类型都对应的是通过远程基础设施API控制的一个资源对象,但也有一些资源对象他们只存在于Terraform进程自身内部,用来计算生成某些结果,并将这些结果保存在状态中以备日后使用。
比如说,我们可以用tls_private_key生成公私钥,用tls_self_signed_cert生成自签名证书,或者是用random_id生成随机id。虽不像其他“真实”基础设施对象那般重要,但这些本地资源也可以成为连接其他资源有用的黏合剂。
本地资源的行为与其他类型资源是一致的,但是他们的结果数据仅存在于Terraform状态文件中。“销毁”这种资源只是将结果数据从状态中删除。
操作超时设置
有些资源类型提供了特殊的timeouts内嵌块参数,它允许我们配置我们允许操作持续多长时间,超时将被认定为失败。比如说,aws_db_instance资源允许我们分别为create,update,delete操作设置超时时间。
超时完全由资源对应的Provider来处理,但支持超时设置的Provider一般都遵循相同的传统,那就是由一个名为timeouts的嵌入块参数定义超时设置,timeouts块内可以分别设置不同操作的超时时间。超时时间由string描述,比如"60m"代表60分钟,"10s"代表10秒,"2h"代表2小时。
esource "aws_db_instance" "example" {
# ...
timeouts {
create = "60m"
delete = "2h"
}
}
可配置超时的操作类别由每种支持超时设定的资源类型自行决定。大部分资源类型不支持设置超时。使用超时前请先查阅相关文档。