- OpenTofu 语言
- 元参数
- 生命周期元参数
lifecycle
元参数
在 资源行为 页面中描述了资源的一般生命周期。可以使用资源块体内的特殊嵌套 lifecycle
块来自定义该行为的某些细节。
resource "azurerm_resource_group" "example" {
# ...
lifecycle {
create_before_destroy = true
}
}
语法和参数
lifecycle
是一个嵌套块,可以出现在资源块内。lifecycle
块及其内容是元参数,可用于所有 resource
块,无论类型如何。
lifecycle
块中可用的参数是 create_before_destroy
、prevent_destroy
、ignore_changes
和 replace_triggered_by
。
-
create_before_destroy
(bool) - 默认情况下,当 OpenTofu 必须更改由于远程 API 限制而无法就地更新的资源参数时,OpenTofu 将改为销毁现有对象,然后使用新的配置参数创建一个新的替换对象。create_before_destroy
元参数会更改此行为,以便首先创建新的替换对象,然后在创建替换对象后销毁先前对象。这是一种选择加入的行为,因为许多远程对象类型具有唯一的名称要求或其他约束,必须同时为新对象和旧对象提供这些约束才能同时存在。例如,一些资源类型提供特殊选项在每个对象名称后附加随机后缀以避免冲突。OpenTofu CLI 无法自动激活此类功能,因此您必须在使用
create_before_destroy
之前了解每个资源类型的约束条件。请注意,OpenTofu 将
create_before_destroy
元属性行为传播并应用于所有资源依赖关系。例如,如果在资源 A 上启用了create_before_destroy
,但在资源 B 上没有启用,但资源 A 依赖于资源 B,则 OpenTofu 默认情况下会隐式地为资源 B 启用create_before_destroy
,并将其存储到状态文件中。您不能将资源 B 上的create_before_destroy
覆盖为false
,因为这将意味着图中存在依赖循环。如果将
create_before_destroy
设置为true
,则不会运行此资源的销毁预置程序。此 GitHub 问题 包含更多详细信息。 -
prevent_destroy
(bool) - 当此元参数设置为true
时,OpenTofu 将拒绝任何会销毁与资源关联的基础设施对象的计划,只要该参数在配置中存在,就会拒绝该计划。这可以用作防止意外替换可能难以复制的对象(例如数据库实例)的安全措施。但是,它会使某些配置更改无法应用,并会阻止在创建此类对象后使用
tofu destroy
命令,因此应谨慎使用此选项。由于此参数必须存在于配置中才能使保护生效,请注意,此设置不会阻止在从配置中完全删除
resource
块时销毁远程对象:在这种情况下,prevent_destroy
设置将与之一起删除,因此 OpenTofu 将允许销毁操作成功执行。 -
ignore_changes
(属性名称列表) - 默认情况下,OpenTofu 会检测真实基础设施对象当前设置的任何差异,并计划更新远程对象以匹配配置。ignore_changes
功能旨在用于使用对未来可能更改的数据的引用的情况下创建资源,但创建后不应影响该资源。在某些罕见情况下,远程对象的设置会由 OpenTofu 之外的进程修改,OpenTofu 随后将尝试在下次运行时“修复”这些设置。为了让 OpenTofu 与单独的进程共享单个对象的管理职责,ignore_changes
元参数指定了 OpenTofu 在规划更新关联的远程对象时应忽略的资源属性。规划 创建 操作时会考虑与给定属性名称相对应的参数,但在规划 更新 操作时会忽略这些参数。这些参数是资源中属性的相对地址。可以使用索引表示法来引用映射和列表元素,例如
tags["Name"]
和list[0]
。代码块 resource "aws_instance" "example" {
# ...
lifecycle {
ignore_changes = [
# Ignore changes to tags, e.g. because a management agent
# updates these based on some ruleset managed elsewhere.
tags,
]
}
}除了列表之外,还可以使用特殊关键字
all
指示 OpenTofu 忽略 所有 属性,这意味着 OpenTofu 可以创建和销毁远程对象,但永远不会提议对其进行更新。只能忽略由资源类型定义的属性。
ignore_changes
不能应用于自身或任何其他元参数。 -
replace_triggered_by
(资源或属性引用的列表) - 当任何引用的项目发生变化时,替换资源。提供引用受管资源、实例或实例属性的表达式列表。当在使用count
或for_each
的资源中使用时,可以在表达式中使用count.index
或each.key
来引用使用相同计数或集合配置的其他资源的特定实例。在以下条件下,引用会触发替换
- 如果引用指向具有多个实例的资源,则计划更新或替换任何实例都会触发替换。
- 如果引用的是单个资源实例,则更新或替换该实例的计划将触发替换。
- 如果引用的是资源实例的单个属性,则对属性值的任何更改都将触发替换。
您只能在
replace_triggered_by
表达式中引用托管资源。这样,您就可以修改这些表达式,而不会强制进行替换。代码块 resource "aws_appautoscaling_target" "ecs_target" {
# ...
lifecycle {
replace_triggered_by = [
# Replace `aws_appautoscaling_target` each time this instance of
# the `aws_ecs_service` is replaced.
aws_ecs_service.svc.id
]
}
}replace_triggered_by
仅允许资源地址,因为决策基于对所有给定资源的计划操作。诸如本地值或输入变量之类的纯值本身没有计划的操作,但是您可以使用它们与terraform_data
资源类型 一起使用,以将其视为类似资源的生命周期。
自定义条件检查
您可以在 lifecycle
块中添加 precondition
和 postcondition
块,以指定有关资源和数据源操作方式的假设和保证。以下示例创建了一个先决条件,该先决条件检查 AMI 是否已正确配置。
resource "aws_instance" "example" {
instance_type = "t2.micro"
ami = "ami-abc123"
lifecycle {
# The AMI ID must refer to an AMI that contains an operating system
# for the `x86_64` architecture.
precondition {
condition = data.aws_ami.example.architecture == "x86_64"
error_message = "The selected AMI must be for the x86_64 architecture."
}
}
}
自定义条件有助于捕获假设,帮助未来的维护者了解配置设计和意图。它们还以更早的时间和上下文返回有关错误的有用信息,帮助使用者更容易地诊断其配置中的问题。
有关更多详细信息,请参阅 自定义条件。
仅文字值
lifecycle
设置都会影响 OpenTofu 如何构建和遍历依赖关系图。因此,只能使用文字值,因为处理发生得太早,无法进行任意表达式评估。