1.5.1.1. 重载(Override) 文件
Terraform 通常会加载目录中的所有 .tf
和 .tf.json
文件,并假设每个文件中配置的对象是不同的。如果两个文件尝试定义同一对象,Terraform 将返回错误。
在某些极少数情况下,能够很方便地重载某一文件中声明配置的对象的指定部分。例如,可以使用 JSON 语法以编程方式生成的文件部分重载那些使用 HCL 语法人工编辑的 Terraform 配置文件。
对于这些不常见的场景,Terraform 对名称以 _override.tf
或 _override.tf.json
结尾的配置文件进行特殊处理。这种特殊处理也适用于字面名称为 override.tf
或 override.tf.json
的文件。
Terraform 最初在加载配置时跳过这些重载文件,然后依次处理每个文件(按字典顺序)。对于重载文件中定义的每个顶级块,Terraform 尝试查找与该块对应的已定义对象,然后将重载块的内容合并到现有对象中。
请确保仅在特殊情况下使用重载文件。过度使用重载文件会损害可读性,因为仅查看原始文件的读者无法在不查阅所有重载文件的情况下轻松地认识到这些文件的某些部分已被重载。使用重载文件时,请在原文件中对重载文件修改的每一个块添加注释警告。
1.5.1.1.1. 示例
假设我们有一个名为 example.tf
的文件中包含如下内容:
resource "aws_instance" "web" {
instance_type = "t2.micro"
ami = "ami-408c7f28"
}
同时,创建名为 override.tf
的文件:
resource "aws_instance" "web" {
ami = "foo"
}
Terraform 会将后者合并到前者中,其行为就好比我们一开始就写成这样:
resource "aws_instance" "web" {
instance_type = "t2.micro"
ami = "foo"
}
1.5.1.1.2. 合并规则
不同的块类型所对应的合并行为略有不同,某些块内的一些特殊结构以特殊方式合并。
适用于大多数情况的一般规则是:
- 重载文件中的顶级块与具有相同块头的普通配置文件中的块合并。块头是块类型及其后面的所有标签。
- 顶级块中的属性值将被替换为重载块中的同名属性值。
- 顶级块中的内嵌块全部都会被重载块中相同类型的块替换。任何未出现在重载块中的块类型仍保留在原始块中。
- 内嵌块的内容不会合并。
- 合并后的块仍必须符合所有适用于该类型块的验证规则。
如果多个重载文件定义相同的顶级块,则重载效果会叠加,后面的块优先于前面的块。重载首先按文件名(按字典顺序)然后按每个文件中的位置进行处理。
以下部分描述了适用于某些顶级块类型中的特定参数的特殊合并行为。
1.5.1.1.2.1. 合并 resource 和 data 块
在 resource
块内,所有 lifecycle
块的内容都会按参数进行合并。例如,如果重载块仅设置了 create_before_destroy
参数,则原始块中 ignore_changes
参数会被保留。
如果重载 resource
块包含一个或多个 provisioner
块,则原始块中的所有 provisioner
块都将被忽略。
如果重载 resource
块包含 connection
块,则它完全取代原始块中存在的所有 connection
块。
不允许在重载块中声明 depends_on
元参数,那将会返回错误。
1.5.1.1.2.2. 合并 variable 块
variable
块内的参数按照上述的标准方式合并,但由于 type
和 default
参数之间存在相互作用,有一些特殊规则。
如果原始块定义了 default
值并且重载块更改了变量的 type
,Terraform 会尝试将默认值转换为重载的类型,如果无法进行这样的转换,则会产生错误。
相反,如果原始块定义 type
并且重载块更改 default
值,则重载的默认值必须与原始块定义的类型兼容。
1.5.1.1.2.3. 合并 output 块
不允许在重载块中声明 depends_on
元参数,那将会返回错误。
1.5.1.1.2.4. 合并 locals 块
每个 locals
块定义了键值对。重载是在逐个值进行的,不论它们定义在哪个 locals
块中。
1.5.1.1.2.5. 合并 terraform 块
terraform
块内的配置在合并时会有不同的规则。
如果设置了 required_providers
参数,则其值将以 Provider 的尺度进行合并,这允许重载块调整单个 Provider 的约束,而不影响其他 Provider 的约束。
在 required_version
和 required_providers
设置中,所有重载的约束都会彻底替换原始块中同一组件的约束。如果原始块和重载块都设置了 required_version
,则原始块中的约束将被彻底忽略。
重载文件中定义 Backend(cloud
或 backend
)的块始终优先于原始配置中定义 Backend 的块。也就是说,如果在原始配置中设置了 cloud
块,并在重载文件中设置了 backend
块,则 Terraform 将在合并时使用重载文件中指定的 backend
块。同样,如果在原始配置中设置了 backend
块,并且在重载文件中设置了 cloud
块,则 Terraform 将在合并时使用重载文件中指定的 cloud
块。