Sling Academy
Home/DevOps/Working with postcondition checks in Terraform

Working with postcondition checks in Terraform

Last updated: February 03, 2024

Overview

Terraform is a powerful tool for building, changing, and versioning infrastructure safely and efficiently. However, even with careful planning and execution, infrastructure deployments can sometimes result in configurations that don’t align with expectations or policy requirements. This is where postcondition checks come into play, offering a method to ensure that your Terraform-managed resources comply with predefined conditions after deployment.

In this tutorial, we’ll explore how to implement and leverage postcondition checks in Terraform. We’ll start with basic concepts and gradually move to more advanced techniques, providing code examples and outputs along the way.

What are Postcondition Checks?

Postcondition checks are assertions made after a Terraform apply operation, ensuring that the state of the infrastructure matches certain criteria. These checks can be used to verify compliance with security policies, operational best practices, or cost controls, among other things.

Implementing Basic Postcondition Checks

Let’s begin with a simple postcondition check. Imagine you have deployed an AWS S3 bucket using Terraform and you want to verify that it’s been encrypted.

resource "aws_s3_bucket" "example" {
  bucket = "my-tf-test-bucket"
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

Now for the postcondition check, we could use the Terraform `external` data source to call a script that checks the encryption status of the bucket:

data "external" "check_encryption" {
  program = ["python", "./check_encryption.py", "my-tf-test-bucket"]
}

The `check_encryption.py` script would use the AWS SDK to verify the encryption status and output the result in a format Terraform can understand.

Intermediate Postcondition Checks

As a next step, let’s consider a scenario where you need to verify that a deployed instance is not exposed to the public internet. For instance, you may want to ensure that no security groups allow traffic from 0.0.0.0/0 to sensitive ports.

resource "aws_security_group" "example" {
  // Configuration omitted for brevity
}

data "external" "check_security_group" {
  program = ["python", "./check_security_group.py", "${aws_security_group.example.id}"]
}

The `check_security_group.py` script would inspect the security group rules and output whether the instance is exposed or not.

Advanced Postcondition Checks

For more complex environments, you may want to implement checks that span multiple resources or even cross-cloud checks. In such cases, a comprehensive audit script or tool can be invoked to assess the environment against a broader set of criteria.

Terraform Compliance Frameworks

Apart from scripting postcondition checks, it’s worthwhile to consider frameworks designed for carrying out compliance checks against Terraform plans, states, or live environments. Tools like “tfsec” and “checkov” scan your Terraform code for common security and compliance issues, offering an added layer of validation.

Conclusion

Implementing postcondition checks in Terraform goes a long way towards ensuring that your infrastructure not only deploys successfully but also adheres to essential compliance and security standards. While the early examples showcased basic checks, evolving your practice to include comprehensive reviews either through scripting or leveraging existing frameworks will further bolster your infrastructure’s integrity and resilience.

Next Article: Using maps in Terraform: A complete guide

Previous Article: Understanding precondition checks in Terraform

Series: Terraform Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide