Terraform Preconditions & Postconditions

Terraform preconditions are mechanisms used to assert certain states or conditions before executing Terraform operations, thereby enforcing the desired state and ensuring the integrity of the infrastructure-as-code deployment.

Preconditions in Terraform refer to the checks and validations that are run before an operation is executed. For instance, suppose you’re creating an AWS S3 bucket. A precondition could be a check to confirm that the name you’re about to use for the bucket does not already exist in your AWS environment. This is crucial because S3 bucket names must be unique across AWS, not just within your account.

In another example, let’s consider a scenario where you’re deploying a virtual machine (VM) on Azure. Here, a precondition could involve ensuring that the selected VM size is available in the specific Azure region you’re targeting. Without this precondition, your deployment might fail if the VM size isn’t available in that region.

To enforce a precondition and validation check for ensuring an AWS EC2 instance is part of the AWS free tier, you would have to ensure that the instance_type you choose falls under AWS’s free tier.

For a validation check in Terraform, you can define it like so:

variable "instance_type" {
  description = "AWS EC2 instance type"

  validation {
    condition     = contains(["t2.micro", "t3.micro", "t4g.micro"], var.instance_type)
    error_message = "The instance type must be part of the AWS free tier: t2.micro, t3.micro, or t4g.micro."
  }
}

This validation block will ensure that the instance type is one of the free tier eligible options before executing the configuration.

To do this same task but without having to hardcode the instance types that are part of the free tier you can instead dynamically check which instances types are part of the free tier when the code is executed using a precondition.

data "aws_ec2_instance_type" "instance" {
    instance_type = var.instance_type
}

resource "aws_instance" "example" {
    instance_type = var.instance_type

    lifecycle {
        precondition {
            condition = data.aws.ec2_instance_type.instance.free_tier_eligible
            error_message = "${var.instance_type} is not part of the AWS Free Tier!"
        }
    }
}
Last modified July 21, 2024: update (e2ae86c)