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 == 200error_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 == 200error_message = "${self.url} returned an unhealthy status code"}}
}
check和postcondition块都在plan或apply操作中验证了Terraform网站是否返回200状态码,它们的区别是发生错误时的行为。
如果是postcondition失败,那么将无法继续执行,Terraform会阻止任意后续的plan或apply操作。
推荐使用check块来验证基础设施的整体状态,仅在希望确保单一资源状态符合预期时使用postcondition。