- OpenTofu 语言
- 文件和目录
- 覆盖文件
覆盖文件
OpenTofu 通常加载目录中所有 .tf
、.tofu
、.tf.json
和 .tofu.json
文件,并期望每个文件定义一组不同的配置对象。如果两个文件尝试定义相同的对象,OpenTofu 将返回错误。
在某些罕见情况下,能够在单独的文件中覆盖现有配置对象的特定部分非常方便。例如,可以使用以 JSON 语法编写的程序生成的配置部分覆盖 OpenTofu 语言原生语法中的人工编辑的配置文件。
对于这些罕见情况,OpenTofu 对任何名称以 _override.tf
、_override.tofu
、_override.tf.json
或 _override.tofu.json
结尾的配置文件进行特殊处理。此特殊处理也适用于字面名为 override.tf
、override.tofu
、override.tf.json
或 override.tofu.json
的文件。
扩展优先级 在处理覆盖文件时非常重要。如果 foo_override.tf
和 foo_override.tofu
都存在于同一目录中,OpenTofu 将只加载 foo_override.tofu
并忽略 foo_override.tf
。相同的规则适用于基于 JSON 的文件 - 如果 foo_override.tofu.json
和 foo_override.tf.json
都存在于同一目录中,OpenTofu 将只加载 foo_override.tofu.json
并忽略 foo_override.tf.json
。
OpenTofu 最初在加载配置时会跳过这些覆盖文件,然后依次处理每个文件(按字典顺序)。对于在覆盖文件中定义的每个顶级块,OpenTofu 尝试查找与该块对应的已定义对象,然后将覆盖块的内容合并到现有对象中。
仅在特殊情况下使用覆盖文件。过度使用覆盖文件会降低可读性,因为仅查看原始文件的读者无法轻松地看出这些文件的某些部分已被覆盖,而无需查阅所有存在的覆盖文件。在使用覆盖文件时,请在原始文件中使用注释以警告将来的读者哪些覆盖文件会对每个块进行更改。
示例
如果您有一个 OpenTofu 配置 example.tf
,其内容如下所示
resource "aws_instance" "web" {
instance_type = "t2.micro"
ami = "ami-408c7f28"
}
...并且您创建了一个包含以下内容的文件 override.tf
resource "aws_instance" "web" {
ami = "foo"
}
OpenTofu 将后者合并到前者中,其行为就像原始配置如下所示
resource "aws_instance" "web" {
instance_type = "t2.micro"
ami = "foo"
}
合并行为
每种块类型的合并行为略有不同,某些块中的某些特殊构造以特殊方式合并。
适用于大多数情况的一般规则是
-
覆盖文件中的顶级块与普通配置文件中具有相同块头的块合并。块头是块类型以及跟随其后的任何带引号的标签。
-
在顶级块内,覆盖块中的属性参数将替换原始块中任何同名参数。
-
在顶级块内,覆盖块中的任何嵌套块将替换原始块中所有相同类型的块。覆盖块中未出现的任何块类型将保留自原始块。
-
嵌套配置块的内容不会合并。
-
生成的合并块必须仍然符合适用于给定块类型的任何验证规则。
如果多个覆盖文件定义了相同的顶级块,则覆盖效果将叠加,后面的块优先于前面的块。覆盖按文件名(按字典顺序)然后按每个文件中的位置顺序处理。
以下部分描述了适用于某些顶级块类型内特定参数的特殊合并行为。
合并 resource
和 data
块
在 resource
块内,任何 lifecycle
嵌套块的内容将按参数逐个基础进行合并。例如,如果覆盖块仅设置 create_before_destroy
参数,则原始块中的任何 ignore_changes
参数将被保留。
如果覆盖 resource
块包含一个或多个 provisioner
块,则原始块中的任何 provisioner
块将被忽略。
如果覆盖 resource
块包含 connection
块,则它将完全覆盖原始块中存在的任何 connection
块。
depends_on
元参数不能在覆盖块中使用,否则将产生错误。
合并 variable
块
variable
块内的参数以上面描述的标准方式合并,但由于 type
和 default
参数之间的交互,会有一些特殊考虑因素。
如果原始块定义了 default
值,并且覆盖块更改了变量的 type
,则 OpenTofu 将尝试将默认值转换为覆盖的类型,如果此转换不可行,则会产生错误。
相反,如果原始块定义了 type
,并且覆盖块更改了 default
,则覆盖的默认值必须与原始类型规范兼容。
合并 output
块
depends_on
元参数不能在覆盖块中使用,否则将产生错误。
合并 locals
块
每个 locals
块定义了一些命名值。覆盖是基于逐值应用的,忽略它们是在哪个 locals
块中定义的。
合并 terraform
块
合并时,terraform
块中的设置会被单独考虑。
如果设置了 required_providers
参数,则其值将基于逐元素进行合并,这允许覆盖块调整单个提供程序的约束,而不会影响其他提供程序的约束。
在 required_version
和 required_providers
设置中,每个覆盖约束都会完全替换原始块中相同组件的约束。如果基础块和覆盖块都设置了 required_version
,则完全忽略基础块中的约束。
覆盖文件中定义后端块(cloud
或 backend
)的存在始终优先于原始配置中定义的后端块。也就是说,如果原始配置中设置了 cloud
块,而在覆盖文件中设置了 backend
块,则 OpenTofu 在合并时将使用覆盖文件中指定的 backend
块。类似地,如果原始配置中设置了 backend
块,而在覆盖文件中设置了 cloud
块,则 OpenTofu 在合并时将使用覆盖文件中指定的 cloud
块。