Bird
Raised Fist0
Terraformcloud~15 mins

Check blocks for assertions in Terraform - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Check blocks for assertions
What is it?
Check blocks in Terraform are special sections that let you test conditions about your infrastructure before applying changes. They help ensure your setup meets certain rules or expectations. If a check fails, Terraform stops and shows an error, preventing unwanted changes. This helps keep your cloud resources safe and predictable.
Why it matters
Without check blocks, mistakes in configuration could cause costly or insecure infrastructure changes. For example, accidentally deleting a database or opening a firewall too wide. Check blocks act like safety guards, catching problems early and saving time, money, and headaches. They make infrastructure changes more reliable and trustworthy.
Where it fits
Before learning check blocks, you should understand basic Terraform configuration and how resources are defined. After mastering check blocks, you can explore advanced validation techniques, custom policies, and automated testing in infrastructure as code.
Mental Model
Core Idea
Check blocks are like safety checkpoints that verify your infrastructure rules before making changes.
Think of it like...
Imagine driving a car with a dashboard warning light that checks your brakes before you start. If the brakes aren’t working, the car won’t move. Check blocks do the same for your cloud setup, stopping bad changes before they happen.
┌───────────────┐
│ Terraform Run │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Check Blocks  │───If all pass──▶ Continue Apply
└──────┬────────┘
       │
       ▼
  Fail: Stop and Show Error
Build-Up - 6 Steps
1
FoundationWhat are Terraform Check Blocks
🤔
Concept: Introduces the basic idea of check blocks as a way to validate conditions before applying changes.
Terraform check blocks are defined inside resource or module blocks. They contain assertions—simple true or false tests about your configuration or resource attributes. If any assertion fails, Terraform stops applying changes and shows an error message.
Result
You learn that check blocks act as pre-apply tests to catch mistakes early.
Understanding that Terraform can test conditions before making changes helps prevent errors and builds safer infrastructure.
2
FoundationBasic Syntax of Check Blocks
🤔
Concept: Shows how to write a simple check block with an assertion in Terraform.
Inside a resource, you add a check block with an assertion using the 'assert' keyword and a condition. For example: resource "aws_instance" "example" { # ... resource config ... check { assert = var.instance_type != "t2.micro" error_message = "Instance type t2.micro is not allowed." } } This stops the apply if the instance type is t2.micro.
Result
You can write simple checks that stop bad configurations.
Knowing the syntax lets you start enforcing rules directly in your Terraform code.
3
IntermediateUsing Multiple Assertions in Check Blocks
🤔Before reading on: do you think you can have more than one assertion inside a single check block? Commit to your answer.
Concept: Explains how to use multiple check blocks or multiple assertions to enforce several rules.
Each check block contains one assertion. To check multiple conditions, add multiple check blocks: resource "aws_s3_bucket" "example" { # ... check { assert = length(self.bucket) >= 3 error_message = "Bucket name must be at least 3 characters." } check { assert = !contains(self.bucket, " ") error_message = "Bucket name cannot contain spaces." } } Terraform runs all checks and stops if any fail.
Result
You can enforce multiple rules on a resource.
Understanding that each check block is a separate test helps organize validations clearly.
4
IntermediateCheck Blocks with Variables and Expressions
🤔Before reading on: do you think check blocks can use variables and complex expressions? Commit to your answer.
Concept: Shows that check blocks can use variables, resource attributes, and expressions for flexible assertions.
Check blocks can reference variables and resource attributes to make dynamic checks. For example: variable "allowed_regions" { type = list(string) default = ["us-east-1", "us-west-2"] } resource "aws_instance" "example" { # ... check { assert = contains(var.allowed_regions, var.region) error_message = "Region is not allowed." } } This ensures instances are only created in allowed regions.
Result
You can write flexible, context-aware checks.
Knowing that checks can use variables lets you create reusable and environment-specific validations.
5
AdvancedCheck Blocks in Modules and Reusability
🤔Before reading on: do you think check blocks inside modules affect only that module or the whole Terraform run? Commit to your answer.
Concept: Explains how check blocks inside modules validate module inputs and outputs, improving module safety.
Modules can include check blocks to validate inputs or outputs. For example, a module might check that a subnet CIDR block is valid: check { assert = can(cidrhost(var.subnet_cidr, 1)) error_message = "Invalid subnet CIDR block." } When you use the module, Terraform runs these checks before applying. This prevents invalid inputs from causing errors later.
Result
Modules become safer and more reliable with built-in checks.
Understanding module-level checks helps build reusable, self-validating components.
6
ExpertLimitations and Best Practices of Check Blocks
🤔Before reading on: do you think check blocks can replace all validation needs in Terraform? Commit to your answer.
Concept: Discusses what check blocks cannot do and how to complement them with other tools and practices.
Check blocks only run during Terraform plan and apply. They cannot enforce runtime policies or external compliance. For complex policies, use tools like Sentinel or Open Policy Agent. Also, avoid overly complex assertions that slow down plans. Keep checks simple and clear. Example limitation: check blocks cannot prevent manual changes outside Terraform.
Result
You know when to use check blocks and when to use other validation tools.
Knowing the limits of check blocks prevents overreliance and encourages a layered validation approach.
Under the Hood
Terraform evaluates check blocks during the plan phase after resource attributes are computed but before applying changes. Each assertion is a boolean expression evaluated in Terraform's expression language. If any assertion returns false, Terraform halts the apply and reports the error message. This mechanism ensures that invalid configurations are caught early, avoiding partial or harmful changes.
Why designed this way?
Check blocks were introduced to provide a native, simple way to validate infrastructure code without external tools. They balance expressiveness and simplicity, allowing users to write inline assertions close to resources. Alternatives like external policy engines are more complex and separate from Terraform code. Check blocks keep validation integrated and immediate.
Terraform Run
┌───────────────────────────────┐
│ 1. Parse Configuration         │
├───────────────────────────────┤
│ 2. Compute Resource Attributes │
├───────────────────────────────┤
│ 3. Evaluate Check Blocks       │───If all true──▶ Apply Changes
│    ┌───────────────────────┐  │
│    │ Evaluate Assertions   │  │
│    └───────────────────────┘  │
│    └── If any false ───────┘  │
│          Stop and Error       │
└───────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do check blocks run after resources are created or before? Commit to before or after.
Common Belief:Check blocks run after resources are created to verify their state.
Tap to reveal reality
Reality:Check blocks run during the plan phase before any resources are created or changed.
Why it matters:Believing checks run after creation leads to false confidence; errors caught too late can cause costly rollbacks or partial failures.
Quick: Can check blocks modify resources or fix errors automatically? Commit yes or no.
Common Belief:Check blocks can fix problems automatically if assertions fail.
Tap to reveal reality
Reality:Check blocks only stop the apply with an error; they do not change or fix resources.
Why it matters:Expecting automatic fixes can cause confusion and delays; manual correction is always needed.
Quick: Are check blocks a replacement for external policy tools like Sentinel? Commit yes or no.
Common Belief:Check blocks replace the need for external policy enforcement tools.
Tap to reveal reality
Reality:Check blocks provide simple inline checks but cannot replace full policy engines that enforce complex rules across teams and environments.
Why it matters:Relying only on check blocks can miss important compliance or governance requirements.
Quick: Can check blocks access external data sources or APIs? Commit yes or no.
Common Belief:Check blocks can query external APIs or data sources for validation.
Tap to reveal reality
Reality:Check blocks can only use Terraform expressions and data available in the configuration; they cannot call external APIs.
Why it matters:Expecting external data access leads to failed validations and unmet requirements.
Expert Zone
1
Check blocks evaluate in the context of the current plan, so they can validate computed attributes but not runtime states or external changes.
2
Assertions in check blocks must be side-effect free and deterministic to avoid inconsistent plan results.
3
Error messages in check blocks should be clear and actionable because they are the only feedback users get when a check fails.
When NOT to use
Avoid using check blocks for complex policy enforcement or cross-resource validations that require global context. Instead, use dedicated policy-as-code tools like Sentinel or Open Policy Agent integrated with Terraform Cloud or CI pipelines.
Production Patterns
In production, teams embed check blocks in reusable modules to enforce module-specific rules. They combine check blocks with external policy tools for layered validation. Check blocks are also used to enforce naming conventions, region restrictions, and resource sizing limits directly in Terraform code.
Connections
Unit Testing in Software Development
Both check blocks and unit tests verify correctness before deployment or release.
Understanding check blocks as tests for infrastructure helps apply software testing principles to cloud setups, improving reliability.
Quality Control in Manufacturing
Check blocks act like quality control checkpoints that prevent defective products from moving forward.
Seeing infrastructure validation as quality control emphasizes the importance of early error detection to avoid costly fixes later.
Pre-flight Safety Checks in Aviation
Check blocks are similar to pre-flight checks that ensure all systems are safe before takeoff.
Recognizing this connection highlights the critical role of validation in preventing disasters and ensuring smooth operations.
Common Pitfalls
#1Writing overly complex assertions that slow down Terraform plans.
Wrong approach:check { assert = length(join("", [for r in aws_instance.example : r.id])) > 0 && some_complex_function() error_message = "Complex check failed." }
Correct approach:check { assert = length(aws_instance.example) > 0 error_message = "At least one instance must exist." }
Root cause:Misunderstanding that check blocks should be simple and fast to evaluate.
#2Expecting check blocks to fix errors automatically.
Wrong approach:check { assert = var.instance_type != "t2.micro" error_message = "Automatically changing instance type to t3.micro." # No code to change instance type }
Correct approach:check { assert = var.instance_type != "t2.micro" error_message = "Instance type t2.micro is not allowed. Please change it manually." }
Root cause:Confusing validation with remediation.
#3Using check blocks to enforce policies that require external data or runtime state.
Wrong approach:check { assert = external_api_call(var.resource_id) == "approved" error_message = "Resource not approved." }
Correct approach:# Use external policy tools or manual checks instead; check blocks cannot call APIs.
Root cause:Assuming check blocks can access external systems.
Key Takeaways
Check blocks in Terraform are inline tests that validate your infrastructure configuration before applying changes.
They help catch mistakes early, preventing costly or insecure resource changes.
Each check block contains a simple assertion that must be true for Terraform to proceed.
Check blocks are best for simple, fast validations and should be combined with external policy tools for complex rules.
Understanding their limits and proper use improves infrastructure safety and reliability.

Practice

(1/5)
1. What is the main purpose of a check block in Terraform?
easy
A. To define variables for resource configuration
B. To verify conditions before resource creation and prevent errors
C. To output resource attributes after deployment
D. To create loops for multiple resource instances

Solution

  1. Step 1: Understand the role of check blocks

    Check blocks are used to verify conditions before Terraform creates resources to avoid invalid configurations.
  2. Step 2: Differentiate from other blocks

    Variables define inputs, outputs show results, and loops create multiple resources; none verify conditions before creation.
  3. Final Answer:

    To verify conditions before resource creation and prevent errors -> Option B
  4. Quick Check:

    Check blocks = pre-creation validation [OK]
Hint: Check blocks catch errors before deployment [OK]
Common Mistakes:
  • Confusing check blocks with variable declarations
  • Thinking check blocks output values
  • Assuming check blocks create resources
2. Which of the following is the correct syntax for a check block in Terraform?
easy
A. check "valid_region" { condition var.region == "us-east-1" error_message "Region must be us-east-1" }
B. check "valid_region" { assert = var.region == "us-east-1" message = "Region must be us-east-1" }
C. check "valid_region" { condition = var.region = "us-east-1" error = "Region must be us-east-1" }
D. check "valid_region" { condition = var.region == "us-east-1" error_message = "Region must be us-east-1" }

Solution

  1. Step 1: Identify correct attribute names

    The correct syntax uses condition for the boolean check and error_message for the error text.
  2. Step 2: Check syntax correctness

    check "valid_region" { condition = var.region == "us-east-1" error_message = "Region must be us-east-1" } correctly uses condition = and error_message = with proper equality ==. Others use wrong attribute names or syntax errors.
  3. Final Answer:

    check "valid_region" { condition = var.region == "us-east-1" error_message = "Region must be us-east-1" } -> Option D
  4. Quick Check:

    Use condition and error_message with equals signs [OK]
Hint: Use 'condition =' and 'error_message =' inside check blocks [OK]
Common Mistakes:
  • Using single equals (=) instead of double equals (==) for condition
  • Using wrong attribute names like assert or error
  • Missing equals signs between keys and values
3. Given this Terraform snippet:
variable "count" { type = number default = 3 }
check "positive_count" { condition = var.count > 0 error_message = "Count must be positive" }

What happens if you set count = 0 and run terraform apply?
medium
A. Terraform fails with error: Count must be positive
B. Terraform applies resources with count 0, creating none
C. Terraform ignores the check block and applies resources
D. Terraform applies resources but warns about count

Solution

  1. Step 1: Understand the check block condition

    The check block requires var.count > 0. Setting count = 0 violates this condition.
  2. Step 2: Predict Terraform behavior on violation

    Terraform stops and shows the error message from the check block instead of applying resources.
  3. Final Answer:

    Terraform fails with error: Count must be positive -> Option A
  4. Quick Check:

    Check blocks stop apply if condition false [OK]
Hint: Check blocks block apply if condition is false [OK]
Common Mistakes:
  • Thinking Terraform ignores check blocks
  • Assuming resources apply with warnings
  • Confusing default variable values with overrides
4. This Terraform check block causes an error during plan:
check "valid_name" { condition = var.name != "" error_message = "Name cannot be empty" }

What is the likely cause if var.name is not set?
medium
A. Terraform errors because var.name is null and comparison fails
B. Terraform ignores the check block if variable is unset
C. Terraform treats unset variable as empty string and passes check
D. Terraform applies default empty string and shows warning only

Solution

  1. Step 1: Analyze variable unset behavior

    If var.name is not set and has no default, it is null, not an empty string.
  2. Step 2: Understand condition evaluation

    Comparing null to empty string with != causes an error because null is not a string.
  3. Final Answer:

    Terraform errors because var.name is null and comparison fails -> Option A
  4. Quick Check:

    Null variables cause check block errors if compared to strings [OK]
Hint: Unset variables are null, not empty strings [OK]
Common Mistakes:
  • Assuming unset variables default to empty strings
  • Expecting check blocks to ignore null values
  • Thinking Terraform only warns on check failures
5. You want to enforce that a variable region is either "us-east-1" or "us-west-2" using a check block. Which is the correct check block to enforce this?
hard
A. check "valid_region" { condition = var.region == "us-east-1" || var.region == "us-west-2" error_message = "Region must be us-east-1 or us-west-2" }
B. check "valid_region" { condition = var.region == ["us-east-1", "us-west-2"] error_message = "Region must be us-east-1 or us-west-2" }
C. check "valid_region" { condition = contains(["us-east-1", "us-west-2"], var.region) error_message = "Region must be us-east-1 or us-west-2" }
D. check "valid_region" { condition = var.region in ("us-east-1", "us-west-2") error_message = "Region must be us-east-1 or us-west-2" }

Solution

  1. Step 1: Understand how to check membership in a list

    Terraform uses the contains(list, value) function to check if a value is in a list.
  2. Step 2: Evaluate each option

    check "valid_region" { condition = var.region == "us-east-1" || var.region == "us-west-2" error_message = "Region must be us-east-1 or us-west-2" } uses logical OR correctly but is verbose; check "valid_region" { condition = var.region == ["us-east-1", "us-west-2"] error_message = "Region must be us-east-1 or us-west-2" } compares a string to a list incorrectly; check "valid_region" { condition = contains(["us-east-1", "us-west-2"], var.region) error_message = "Region must be us-east-1 or us-west-2" } uses contains properly; check "valid_region" { condition = var.region in ("us-east-1", "us-west-2") error_message = "Region must be us-east-1 or us-west-2" } uses invalid syntax in.
  3. Final Answer:

    check "valid_region" { condition = contains(["us-east-1", "us-west-2"], var.region) error_message = "Region must be us-east-1 or us-west-2" } -> Option C
  4. Quick Check:

    Use contains(list, value) to check membership [OK]
Hint: Use contains() to check if value is in list [OK]
Common Mistakes:
  • Using 'in' keyword which Terraform does not support
  • Comparing string directly to list
  • Using verbose OR instead of contains()