check
block. This allows us to assert things about our provisioned resources. Unlike the precondition
and postcondition
however a check
is non-blocking, this means that it will not prevent your Terraform code from running it will simply warn the engineer that the assertion has failed.First off lets look at a very basic example.
resource "scratch_string" "this" {
in = "meow"
}
resource "scratch_string" "that" {
in = "woof"
}
check "this" {
data "http" "this" {
url = "https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat"
}
assert {
condition = scratch_string.this.in == data.http.this.response_body
error_message = "Err: the data source doesn't match the resource."
}
}
check "that" {
data "http" "that" {
url = "https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat"
}
assert {
condition = scratch_string.that.in == data.http.that.response_body
error_message = "Err: the data source doesn't match the resource."
}
}
scratch_string.this
and scratch_string.that
will run a check against a remote key-value store to ensure that they both match what is in the KV store with check
. As part of the check
block we are able to define a data
block and one or more assert
blocks. The assert
block takes the same form that we are used to in precondition
and postcondition
checks with the condition
attribute that requires to return a boolean and the error_message
attribute that is shown when the check fails.error_message
more useful by using string interprolation, this allows us to bring in information from either the data
block or other parts of the code so that our errors are more contextual and meaningful. Below is an example using a fake resource.assert {
condition = ...
error_message = format("Err: User (%s) no it group.", some_resource.user.name)
}
Our result looks like:
data.http.that: Reading...
data.http.this: Reading...
data.http.this: Read complete after 0s [id=https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat]
data.http.that: Read complete after 0s [id=https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
<= read (data resources)
Terraform will perform the following actions:
# data.http.that will be read during apply
# (config will be reloaded to verify a check block)
<= data "http" "that" {
+ body = "meow"
+ id = "https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat"
+ response_body = "meow"
+ response_headers = {
...
}
+ status_code = 200
+ url = "https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat"
}
# data.http.this will be read during apply
# (config will be reloaded to verify a check block)
<= data "http" "this" {
+ body = "meow"
+ id = "https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat"
+ response_body = "meow"
+ response_headers = {
...
}
+ status_code = 200
+ url = "https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat"
}
# scratch_string.that will be created
+ resource "scratch_string" "that" {
+ id = (known after apply)
+ in = "woof"
}
# scratch_string.this will be created
+ resource "scratch_string" "this" {
+ id = (known after apply)
+ in = "meow"
}
Plan: 2 to add, 0 to change, 0 to destroy.
scratch_string.this: Creating...
scratch_string.that: Creating...
scratch_string.this: Creation complete after 0s [id=7d2182f0-0f0d-11ee-b7ef-aacb117da4fc]
data.http.that: Reading...
data.http.this: Reading...
scratch_string.that: Creation complete after 0s [id=7d21889a-0f0d-11ee-b7ef-aacb117da4fc]
data.http.that: Read complete after 0s [id=https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat]
data.http.this: Read complete after 0s [id=https://kvdb.io/QmQfhGhDgNTVEANY6vXfFk/sounds/cat]
╷
│ Warning: Check block assertion failed
│
│ on main.tf line 35, in check "that":
│ 35: condition = scratch_string.that.in == data.http.that.response_body
│ ├────────────────
│ │ data.http.that.response_body is "meow"
│ │ scratch_string.that.in is "woof"
│
│ Err: the data source doesn't match the resource.
╵
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
scratch_string.this
resource is all hunky-dory as there are no warnings shown in our apply output, with the second one however we were not so lucky. You can see we have a Warning: Check block assertion failed we expected our in
attribute to have the value of meow
like the KV store however it actually has the value of woof
. This check
would also yield the same result on the Plan phase as well.data
block in your check, there might be scenarios where it makes sense to have multiple items to check against however this is not currently possible.check
block works however it isn't what I would call real-world , below are a few examples of where the check
block would be useful.
check
block that came out with Terraform v1.5 this opens up a whole new world of possibilities when it comes to testing our infrastructure and ensuring that it exists in the state we expect it to. This means that using technologies such as Terratest for validating our resultant infrastructure (think Unit Tests) becomes less likely to be required. I still think however it is a fantastic option for powerful Integration Testing.Try out the Check feature using Scalr today!