Use checks to validate infrastructure
Terraform checks let you define assertions to validate as part of your infrastructure management workflow. Unlike variable validation or custom conditions, check blocks are decoupled from the lifecycle of a specific resource or data source. Checks let you take advantage of Terraform's abstraction of the differences between different provider APIs. Because Terraform standardizes how you interact with all provider APIs, you can use the familiar Terraform language features and syntax to define conditions to validate in your Terraform runs. Checks also let you verify your assumptions about your infrastructure on an ongoing basis instead of just at the time of provisioning.
In this tutorial, you will define and use checks to check the response code for a service and validate that your TLS certificate is still valid. You will define conditions that reference existing resources and integrate data sources to query your systems. If you complete this tutorial using HCP Terraform, you will also enable health assessments and use continuous validation to verify the results of your checks.
Prerequisites
You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects. It includes features like remote state and execution, structured plan output, workspace resource summaries, and more.
Select the HCP Terraform tab to complete this tutorial using HCP Terraform.
This tutorial assumes that you are familiar with the Terraform and HCP Terraform workflows. If you are new to Terraform, complete the Get Started tutorials first. If you are new to HCP Terraform, complete the HCP Terraform Get Started tutorials first.
In order to complete this tutorial, you will need the following:
- Terraform v1.5+ installed locally.
- An AWS account.
- An HCP Terraform account with HCP Terraform locally authenticated.
- An HCP Terraform organization with the Standard edition.
- An HCP Terraform variable set configured with your AWS credentials.
Clone example configuration
Clone the example repository for this tutorial. It contains Terraform configuration for a load balancer, self-signed TLS certificate, target group, security group, and an autoscaling group that runs Teramino, a Terraform-skinned Tetris application.
$ git clone https://github.com/hashicorp-education/learn-terraform-checks
Change to the repository directory.
$ cd learn-terraform-checks
Define a check
Checks can validate any condition that you can define with Terraform configuration. A check can validate an attribute of your infrastructure, or the functionality of the resource itself. Rather than writing custom scripts to test assertions about your infrastructure, you can use Terraform language features to validate your infrastructure health.
Open your main.tf file and add a check block that verifies the status of your TLS certificate to the file. Save the file.
main.tf
check "certificate" {
assert {
condition = aws_acm_certificate.cert.status == "ERRORED"
error_message = "Certificate status is ${aws_acm_certificate.cert.status}"
}
}
A check block consists of one or more assert statements. The assertions contain the condition to verify and the error message to display if the assertion fails. This check verifies the TLS certificate's status. To demonstrate how Terraform handles a failed check, the condition asserts that the status is ERRORED, which will fail.
Create infrastructure and validate checks
Open your terraform.tf file and uncomment the cloud block. Replace the
organization name with your own HCP Terraform organization.
terraform.tf
terraform {
cloud {
organization = "organization-name"
workspaces {
name = "learn-terraform-checks"
}
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.4.0"
}
}
required_version = ">= 1.5"
}
Initialize your configuration. Terraform will automatically create the learn-terraform-checks workspace in your HCP Terraform organization.
$ terraform init
Initializing HCP Terraform...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Installing hashicorp/aws v4.4.0...
- Installed hashicorp/aws v4.4.0 (signed by HashiCorp)
HCP Terraform has been successfully initialized!
You may now begin working with HCP Terraform. Try running "terraform plan" to
see any changes that are required for your infrastructure.
If you ever set or change modules or Terraform Settings, run "terraform init"
again to reinitialize your working directory.
Note: This tutorial assumes that you are using a tutorial-specific HCP Terraform organization with a global variable set of your AWS credentials. Review the Create a Credential Variable Set for detailed guidance. If you are using a scoped variable set, assign it to your new workspace now.
Now, create your infrastructure. Terraform will evaluate any checks included in your configuration as the last step of the operation, and the configuration will fail the check because your certificate status is actually ISSUED.
$ terraform apply
data.aws_ami.amazon_linux: Reading...
data.aws_availability_zones.available: Reading...
data.aws_ami.amazon_linux: Read complete after 0s [id=ami-01974536802026e4f]
data.aws_availability_zones.available: Read complete after 1s [id=us-east-2]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
##...
Plan: 21 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ application_endpoint = (known after apply)
+ asg_name = "terramino"
+ lb_endpoint = (known after apply)
╷
│ Warning: Check block assertion known after apply
│
│ on main.tf line 169, in check "certificate":
│ 169: condition = aws_acm_certificate.cert.status == "ERRORED"
│ ├────────────────
│ │ aws_acm_certificate.cert.status is a string
│
│ The condition could not be evaluated at this time, a result will be known when this plan is applied.
╵
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
##...
╷
│ Warning: Check block assertion failed
│
│ on main.tf line 169, in check "certificate":
│ 169: condition = aws_acm_certificate.cert.status == "ERRORED"
│ ├────────────────
│ │ aws_acm_certificate.cert.status is "ISSUED"
│
│ Certificate status is ISSUED
╵
Apply complete! Resources: 21 added, 0 changed, 0 destroyed.
Outputs:
application_endpoint = "https://terramino-1659500809.us-east-2.elb.amazonaws.com/index.php"
lb_endpoint = "https://terramino-1659500809.us-east-2.elb.amazonaws.com"
Notice that after Terraform generated the execution plan for the run, it displayed the check, but noted that the result would only be known after the apply. At the end of the apply, Terraform determined the certificate status and showed that the check failed.
Open main.tf again. Find the aws_launch_configuration.terramino resource and update the instance_type to t2.small. This time, Terraform will know at the time of the plan that your configuration's check fails, but will still let you proceed with the instance resize.
main.tf
resource "aws_launch_configuration" "terramino" {
name_prefix = "terramino-"
image_id = data.aws_ami.amazon_linux.id
instance_type = "t2.small"
user_data = file("user-data.sh")
security_groups = [aws_security_group.terramino_instance.id]
lifecycle {
create_before_destroy = true
}
}
Run terraform apply. This time, Terraform evaluates the check and notifies that it failed, but still lets you change your infrastructure.
$ terraform apply
##...
Plan: 1 to add, 1 to change, 1 to destroy.
╷
│ Warning: Check block assertion failed
│
│ on main.tf line 169, in check "certificate":
│ 169: condition = aws_acm_certificate.cert.status == "ERRORED"
│ ├────────────────
│ │ aws_acm_certificate.cert.status is "ISSUED"
│
│ Certificate status is ISSUED
╵
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
Terraform evaluates checks after generating the plan. Unlike custom conditions or variable validation errors, failed checks do not block applies. Terraform will notify if there are any failures or issues to address, letting you decide whether to proceed with the operation.
Unlike other configuration validation mechanisms, checks are decoupled from other components and resources in your configuration. These differ from variable validation, which lets you ensure the inputs to your configuration satisfy your requirements, and custom conditions, which let you define conditions as part of your resource definitions. These conditions are tied to the specific resource lifecycle, rather than your configuration as a whole.
Enable health assessments
HCP Terraform health assessments run daily to verify the status of your infrastructure. These assessments include drift detection, which verifies that your infrastructure settings still match your intended configuration, and continuous validation, which verifies that any checks defined in your configuration still pass.
You can enable assessments on a specific workspace, or on all workspaces within your organization. Enable assessments on the workspace for this tutorial. First, navigate to your learn-terraform-checks workspace. In the Health section, select Settings. Then, select Enable and click Save settings.