一般来说Terraform会加载模块内所有的.tf
和.tf.json
文件,并要求文件内定义了一组无重复的对象。如果两个文件尝试定义同一个对象,那么Terraform会报错。
在某些少见场景中,能够用单独的文件重载已有对象配置的特定部分将会十分有用。比如说,由工程师编写的配置文件能够在运行时被程序生成的JSON文件部分重载。
为支持这些少见场景,Terrform会对后缀名为override.tf
和override.tf.json
的代码文件进行特殊处理,对于名为override.tf
和override.tf.json
的代码文件也会进行相同的特殊处理。
Terraform一开始加载代码文件时会跳过这些重载文件,然后才会按照字典序一个一个处理重载文件。对重载文件中定义的所有顶级块(resource
、data
等),Terraform会尝试找到对应的已有对象并且将重载内容合并进已有对象。
重载文件只应使用于特殊场景,过度使用会使得读者在阅读原始代码文件时被迫还要阅读所有的重载文件才能理解对象配置,从而降低了代码的可读性。使用重载文件时,请在原始文件被重载的部分添加相应注释,提醒未来的读者哪些部分会被重载文件修改。
示例
如果有一个名为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"
}
合并行为
不同的块类型有着些微不同的合并行为,某些特定块内的特殊构造会以特殊形式被合并。
- 重载文件内的顶级块会和普通文件内同类型同名的顶级块合并
- 重载文件内的顶级块配置参数会覆盖普通文件内对应块内的同名参数
- 重载块内的内嵌块会取代普通文件内对应块内的所有同类型内嵌块,所有重载块内没有定义的内嵌块在普通文件内保持不变
- 内嵌块的内容不会进行合并
- 合并后的块仍然需要符合对应块类型的所有验证规则
如果有多个重载文件定义了同一个顶级块,那么重载效果是叠加的,后加载的重载块会在先前加载的重载块生效的基础上合并,重载操作首先按照文件名的字典序其次是在重载文件中的位置决定执行顺序。
有一些针对特定顶级块类型的特殊合并行为规则,将重载文件中定义的块称为重载块,重载块在普通文件中对应的块称为源块。
合并resource块以及合并data块
在resource
块内,所有lifecycle
块的内容会按照参数逐条合并。
比如说,一个重载块只定义了create_before_destroy
参数而源块定义了ignore_changes
,那么create_before_destroy
被合并的同时igonore_changes
将会被保留。
如果重载的resource
块包含了一个或多个provisioner
,那么源块内所有的provisioner
会被忽略。
如果重载的resource
块内包含了一个connection
块,那么它将会完全覆盖所有源块内定义的connection
块。
不允许在重载块内定义depends_on
参数,那将会引发一个错误。
合并variable块
variable
块内参数的合并遵循上述的标准流程,但对于type
和default
参数的处理会有一些特殊的考虑。
如果源块定义了default
值而重载块修改了变量的type
,Terraform会尝试将default值转换成新类型,如果转换失败则会报错。
如果源块定义了type
参数而重载块修改了default
值,那么新的default值必须能够被转换成原先的类型。
合并output块
不允许在重载块内定义depends_on
参数,这会引发一个错误。
合并locals块
所有的locals
块都定义了一个或多个命名值,针对locals
的合并是按照命名值的名字逐条执行的,不论命名值是在哪个locals块内被定义的。
合并terraform块
如果重载块定义了required_providers
参数,那么它的值会被逐条合并,这就允许重载块在不影响其他Provider的情况下调整单个Provider的版本约束。
重载块内的required_version
和required_providers
里的配置完全覆盖源块内的相应配置,如果源块和重载块都定义了required_version
,那么源块的配置会被完全忽略。
【参考】
Override Files
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,在下面评论区告诉我^_^^_^