1.7.19.1. taint
terrform taint
命令可以手动标记某个Terraform管理的资源有"污点",强迫在下一次执行apply时删除并重建之。
该命令并不会修改基础设施,而是在状态文件中的某个资源对象上标记污点。当一个资源对象被标记了污点,在下一次 plan
操作时会计划将之删除并且重建,apply
操作会执行这个变更。
强迫重建某个资源可以使你能够触发某种副作用。举例来说,你想重新执行某个预置器操作,或是某些人绕过 Terraform 修改了虚拟机状态,而你想将虚拟机重置。
注意为某个资源标记污点并重建之会影响到所有依赖该资源的对象。举例来说,一条 DNS 记录使用了服务器的 IP 地址,我们在服务器上标记污点会导致 IP 发生变化从而影响到 DNS 记录。这种情况下可以使用 plan
命令查看变更计划。
警告:此命令已被弃用。从 Terraform v0.15.2 开始,我们建议使用 -replace
选项和 terraform apply
代替(详细信息如下)。
1.7.19.1.1. 推荐的替代方法
从 Terraform v0.15.2 开始,我们建议使用 terraform apply
的 -replace
选项来强制 Terraform 替换对象,即使没有发生需要变更的配置更改。
terraform apply -replace="aws_instance.example[0]"
我们推荐使用 -replace
参数,因为这可以在 Terraform 计划中显示将要发生的变更,让我们在采取任何会影响系统的操作之前了解计划将如何影响我们的基础设施。当我们使用 terraform taint
时,其他用户有可能可以在我们审查变更之前针对标记的对象创建新的变更计划。
1.7.19.1.2. 用法
terraform taint [options] <address>
address
参数是要标记污点的资源地址。该地址格式遵循资源地址语法,例如:
aws_instance.foo
aws_instance.bar[1]
aws_instance.baz[\"key\"]
(资源地址中的引号必须在命令行中转义,这样它们就不会被 shell 解释)module.foo.module.bar.aws_instance.qux
该命令可以使用如下可选参数:
-allow-missing
:如果声明该参数,那么即使资源不存在,命令也会返回成功(状态码0)。对于其他异常情况,该命令可能仍会返回错误,例如读取或写入状态时出现问题。-lock=false
:执行时是否先锁定状态文件。如果其他人可能同时对同一工作区运行命令,则这是危险的。-lock-timeout=DURATION
:除非使用-lock=false
禁用锁定,否则命令 Terraform 为上锁操作设置一个超时时长。持续时间语法是一个数字后跟一个时间单位字母,例如“3s”表示三秒。
以下是使用 local
Backend 时可用的遗留参数:
-backup=FILENAME
:指定源状态文件的备份地址,默认为源状态文件加上".backup"后缀-bakcup-out=FILENAME
:指定目标状态文件的备份地址,默认为目标状态文件加上".backup"后缀-state=FILENAME
:源状态文件地址,默认为当前 Backend 或是"terraform.tfstate"-state-out=FILENAME
:目标状态文件地址。如果不指定则使用源状态文件。可以是一个已经存在的文件或新建一个文件
1.7.19.1.3. 标记单个资源
$ terraform taint aws_security_group.allow_all
The resource aws_security_group.allow_all in the module root has been marked as tainted.
1.7.19.1.4. 标记使用for_each创建的资源的特定实例
$ terraform taint "module.route_tables.azurerm_route_table.rt[\"DefaultSubnet\"]"
The resource module.route_tables.azurerm_route_table.rt["DefaultSubnet"] in the module root has been marked as tainted.
1.7.19.1.5. 标记模块中的资源
$ terraform taint "module.couchbase.aws_instance.cb_node[9]"
Resource instance module.couchbase.aws_instance.cb_node[9] has been marked as tainted.
虽然我们推荐模块深度不要超过1,但是我们仍然可以标记多层模块中的资源:
$ terraform taint "module.child.module.grandchild.aws_instance.example[2]"
Resource instance module.child.module.grandchild.aws_instance.example[2] has been marked as tainted.