7命令部分-状态管理
terraform用state文件记录配置中有地址的!重点!配置中有地址的!外部对象得数据。
文章目录
资源寻址
默认地址
资源地址是一个字符串,用于标识整个配置中的零个或多个资源实例。
两部分
[module path][resource spec]
在某些情况下,Terraform 可能允许不完整的资源地址,该地址仅引用整个模块,或者省略多实例资源的索引。在这些情况下,含义取决于上下文,因此您需要参考您正在使用的用于解析资源地址的特定功能的文档。
模块寻址 module path
模块路径寻址模块树中的模块。它采用以下形式:
module.module_name[module index]
[module index]
- (可选)索引,用于从具有多个实例的模块调用中选择一个实例,并用方括号字符 ( [
和 ]
) 括起来。
模块索引仅适用于 Terraform v0.13 或更高版本中的模块。在早期版本的 Terraform 中,一个模块不能有多个实例。
资源规格 resource spec
默认语法
resource_type.resource_name[instance index]
所以!! 其实我们常见的直接寻找的方案都是省略了module path 的使用跟模块的资源, 通过资源类型来寻址。
在 Terraform v0.12 及更高版本中,没有模块路径前缀的资源规范仅匹配根模块中的资源。在早期版本中,没有模块路径前缀的资源规范将与任何后代模块中具有相同类型和名称的资源匹配。
索引值部分
这里如果用count, 就是用序号来做
比如
resource "aws_instance" "web" {
# ...
count = 4
}
aws_instance.web[3]
这里3 是最后一个实例
如果希望引用全部,可以写
aws_instance.web
这里如果是用for_each来做,就直接写名称
比如
resource "aws_instance" "web" {
# ...
for_each = tomap({
"terraform": "value1",
"resource": "value2",
"indexing": "value3",
"example": "value4",
})
}
寻址就是
aws_instance.web["example"]
state 命令
state文件可以放在远程,使用上除了多了网络的往返外跟本地没有区别
state 的备份
state命令有很多子命令会修改state文件,这些修改都写入 备份文件, 而且这个备份文件是的创建,是不可以被禁用的,,,
但是可以通过-backup 参数来指定位置
state 命令的不修改状态的子命令 比如list 啥的, 这是不会写备份文件的, 因为这些命令不对备份做修改
检查状态
state 命令的list 跟show ,就看之前的 命令部分第五篇
refresh
警告:此命令已弃用,因为如果您为任何提供程序配置了错误的凭据,则其默认行为是不安全的。有关详细信息和推荐的替代方法,请参阅下文。
通常不需要使用此命令,因为 Terraform 会在 terraform plan
和 terraform apply
命令中自动执行与创建计划相同的刷新操作。此命令主要用于向后兼容,但我们不建议使用它,因为它没有机会在更新状态之前查看操作的效果。
这个命令是下边这个命令的alias
terraform apply -refresh-only -auto-approve
auto-approve 是个危险参数 不建议直接加
所以建议的命令是
terraform apply -refresh-only
强制重建资源
在执行terraform plan期间,默认情况下,Terraform 会检索每个现有对象的最新状态,并将其与当前配置进行比较,仅针对当前状态与配置不匹配的对象规划操作。
但是,在某些情况下,远程对象可能会以 Terraform 无法自动检测到的方式损坏或降级。例如,如果在虚拟机中运行的软件崩溃,但虚拟机本身仍在运行,则 Terraform 通常无法检测和响应问题,因为 Terraform 仅直接管理整个计算机。
如果您知道某个对象已损坏,或者出于任何其他原因想要强制 Terraform 替换它,则可以在运行以下 terraform apply
任一 terraform plan
选项时使用 -replace=...
规划选项覆盖 Terraform 的默认行为:
示例:
terraform apply -replace="aws_instance.example"
# ...
# aws_instance.example will be replaced, as requested
-/+ resource "aws_instance" "example" {
# ...
}
taint
tf 如果检测到某个资源不合理,可能会标记为tainted状态, 提示为
# aws_instance.example is tainted, so must be replaced
-/+ resource "aws_instance" "example" {
# ...
}
这个时候可以用untanit,,后边说,
还可以强制 Terraform 使用该 terraform taint
命令将特定对象标记为受污染,但该方法已被弃用,取而代之的是该 -replace=...
选项,这样就无需使用受污染的对象创建临时状态快照。
用法
terraform taint [options] <address>
untaint
使用方式就是直接untait 对象就行
如果写脚本可以加
-allow-missing
- 如果指定,即使缺少资源,该命令也会成功(退出代码 0)。对于其他情况,该命令可能仍会返回错误,例如读取或写入状态时出现问题。
移动资源
Terraform 的状态将每个真实世界的对象与特定资源地址的已配置资源相关联。这在更改资源属性时是无缝的,但如果更改资源的名称、将其移动到其他模块或更改其提供程序,Terraform 将失去对资源的跟踪。
state mv
可以在不太常见的情况下使用 terraform state mv
,例如希望保留现有远程对象,但在 Terraform 中将其跟踪为不同的资源实例地址,例如,如果重命名了资源块或已将其移动到配置中的其他模块中。
最常见的用途 terraform state mv
是重命名配置中的资源块或将资源块移动到子模块中,在这两种情况下,都是为了保留现有对象,但以新名称跟踪它。默认情况下,Terraform 会将移动或重命名资源配置理解为删除旧对象并在新地址创建新对象的请求,因此 terraform state mv
允许您通过抢占将现有对象附加到 Terraform 中的新地址来覆盖该解释。
示例
terraform state mv packet_device.worker packet_device.helper
如果最初在根模块中编写了资源,但现在希望将其重构为子模块,则可以将 resource
该块移动到子模块配置中,删除根模块中的原始模块,然后运行以下命令以告诉 Terraform 将其视为移动:
terraform state mv packet_device.worker module.worker.packet_device.worker
在上面的示例中,新资源具有相同的名称,但模块地址不同。如果新的模块组织建议使用不同的命名方案,也可以同时更改资源名称:
terraform state mv packet_device.worker module.worker.packet_device.main
state rm
您可以在不太常见的情况下使用 terraform state rm
,即您希望在不首先销毁现有远程对象的情况下删除与现有远程对象的绑定,这将有效地使 Terraform 在对象继续存在于远程系统中时“忘记”该对象。
terraform state rm 'packet_device.worker'
state replace-provider
该 terraform state replace-provider
命令用于替换处于 Terraform 状态的资源的提供程序。
下面的示例将 hashicorp/aws
提供程序替换为 fork by acme
,托管在私有注册表中 registry.acme.corp
:
$ terraform state replace-provider hashicorp/aws registry.acme.corp/acme/aws
Recovering from State Disasters
如果出现严重错误(可能是由于执行其他状态操作时发生的事故),则可能需要对状态数据采取激烈的措施。
该 terraform force-unlock
命令可以覆盖 Terraform 用于防止两个进程同时修改状态的保护措施。如果 Terraform 进程(如正常应用)意外终止(如完全销毁它所在的 VM),然后才能释放其在状态后端的锁定,则可能需要此功能。在您完全确定导致锁卡住的过程发生了什么之前,不要运行此操作。
该 terraform state pull
命令和 terraform state push
命令可以直接从配置的后端读取和写入整个状态文件。您可能需要此功能来获取或还原状态备份。
state pull
该 terraform state pull
命令用于从远程状态手动下载和输出状态。此命令也适用于本地状态。
state push
该 terraform state push
命令用于手动将本地状态文件上传到远程状态。此命令也适用于本地状态。
force-unlock
手动解锁已定义配置的状态。
这不会修改您的基础结构。此命令删除当前配置状态上的锁定。此锁的行为取决于所使用的后端。本地状态文件无法由其他进程解锁。