check
块是Terraform 1.5开始引入的新功能。
过去可以在resource
块里的lifecycle
块中验证基础设施的状态,check块填补了在apply
后验证基础设施状态这一功能的空白。check
块允许定义在每次plan
以及apply
操作后执行的自定义的验证。check块定义的验证逻辑是作为plan
和apply
操作的最后一步执行的。
语法
可以定义一个包含本地名称的check
块,其中可以定义一个有限作用范围的data
块,以及至少一个的断言。
如下示例演示了加载Terraform官网并验证HTTP返回状态码为200。
check "health_check" {
data "http" "terraform_io" {
url = "https://www.terraform.io"
}
assert {
condition = data.http.terraform_io.status_code == 200
error_message = "${data.http.terraform_io.url} returned an unhealthy status code"
}
}
有限作用范围的数据源
可以在check
块使用任意Provider提供的任意数据源作为一个有限作用范围的数据源。
一个check
块可以配一个可选的内嵌(也叫有限作用范围)数据源,该data
块和普通的data
块行为类似,但不能在定义它的check
块以外引用它。
另外,如果一个有限作用范围的数据源运行时触发了任意错误,这些错误将被标记为警告,不会阻止Terraform继续执行操作。
可以使用有限作用范围的数据源在resource
的lifecycle
外验证相关基础设施片段的状态。
在上述例子里,如果terraform_io
数据源在加载时发生错误,那么将会收到一个警告而不是中断执行的错误。
元参数
有限作用域的数据源支持depends_on
和provider
元参数,但不支持count
或for_each
元参数。depends_on
元参数配合有限作用域数据源可以提供非常强大的能力。
假设上述例子中的Terraform网站是即将用同一目录下的Terraform代码部署的,在第一次创建Plan时因为网站还没有被创建,所以验证会失败,Terraform总是会在一开始显示一条让人分心的警告信息。可以给该内嵌数据源添加depends_on
来确保该数据源依赖于某项组成基础设施的必要资源,例如负载均衡器。这样对该数据源的检查结果将保持known after apply
直到依赖项创建完成。该策略避免了在配置阶段产生无意义的警告信息,直到在plan
和apply
操作的合适阶段执行检查。
该策略的一个问题是如果有限作用域数据源所依赖的资源发生了变化,那么check
块将返回known after apply
直到Terraform完成了对被依赖资源的更新。在某些情况下,这种行为将会引发一些问题。
推荐只有在内嵌数据源依赖于某项资源,但又没有显式的引用其数据时使用depends_on
元参数。
断言
在check
块中使用assert
块定义断言条件,每个check
块必须声明至少一个或更多的assert块,每个assert块都包含了一个condition属性和一个error_message属性。
与其他自定义检查(输入变量中的validation
以及lifecycle中的precondition
和postcondition
)不同,check块中的assert断言不会影响Terraform执行操作,失败的断言将以警告信息的形式输出而不会中断后续的操作。这与其他诸如postcondition
这样的自定义检查形成了对比,因为它们的检查失败会立即终止后续的plan
以及apply
操作,返回错误信息。
assert
块中的断言条件表达式可以引用同一check
块里的内嵌数据源数据,以及同一模块中的任意输入参数、资源、数据源、模块的输出值。
元参数
check
块目前不支持元参数。
是使用check块还是其他自定义条件检查
check
块提供了Terraform中最灵活的验证功能,可以在其中引用输出值、输入参数、资源以及数据源的值。的确可以使用check
块取代所有其他的自定义条件检查,但这并不意味着应该要这么做。check
与其他检查最大的区别在于check
块不会中断Terraform的执行,需要将这种非阻塞性的行为特点计入考量来决定采取何种检查。
输出值与输入参数
输出值的precondition
以及输入变量的validation
都可以对输入输出值进行断言,这些检查是用来阻止Terraform在数据有问题时继续执行的。
举例来说,如果输入参数的值是无效的那么任由Terraform执行整个配置文件并没有什么意义,这种情况下,check
块只会输出有关无效输入参数的警告,不会打断Terraform的执行,而 validation
块则会警告输入参数值非法,并终止Terraform执行plan
或apply
操作。
resource块的precondition与postcondition
check
块与resource
块的precondition和postcondition的区别更加微妙。precondition
是自定义条件检查中最特殊的,因为它们是在资源的变更被计算或应用之前执行的检查。决定使用precondition
还是postcondition
的考量也适用于选择是使用 precondition
还是check
块。
可以在postcondition
与check
块之间互换来验证资源和数据源。例如,可以把上述例子中的check
块改写成postcondition
,以下的postcondition
块将会验证对Terraform网站的请求是否返回了状态码200:
data "http" "terraform_io" {
url = "https://www.terraform.io"
lifecycle {
postcondition {
condition = self.status_code == 200
error_message = "${self.url} returned an unhealthy status code"
}
}
}
check
和postcondition
块都在plan
或apply
操作中验证了Terraform网站是否返回200状态码,它们的区别是发生错误时的行为。
如果是postcondition
失败,那么将无法继续执行,Terraform会阻止任意后续的plan
或apply
操作。
推荐使用check
块来验证基础设施的整体状态,仅在希望确保单一资源状态符合预期时使用postcondition
。
【参考】
Checks
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,在下面评论区告诉我^_^^_^