Welcome to this article! If you are working with Terraform to manage cloud infrastructure such as AWS, writing integration tests is an important step to verify that your code works correctly with the real provider (for example, creating actual resources on the cloud). In this blog, I will guide you through creating integration tests (real-world application to check actual resources) for a simple Terraform source code: provisioning an EC2 instance via a module. We will use the Terraform Test feature (available from Terraform 1.6 onwards) to apply real code, validate outputs, and automatically destroy resources afterwards.
Project Structure
The source code we are working with follows a basic structure:
- main.tf: The main file that calls the module and sets up the provider.
- modules/ec2_instance/: The module that provisions the EC2 instance.
- tests/integration.tftest.hcl: The integration test file.
1. Set Up Basic Terraform Source Code
First, create the project folder structure and files.
1.1 Create main.tf
This file configures the AWS provider and calls the EC2 module.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
module "web_server" {
source = "./modules/ec2_instance" # Adjust path if needed
env_name = "dev"
instance_type = "t3.micro"
ami_id = "ami-0fa3fe0fa7920f68e" # Replace with a valid AMI ID for your region
}
output "server_ip" {
value = module.web_server.public_ip
}
1.2 Create the ec2_instance Module
Inside modules/ec2_instance, add the following files:
main.tf
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = "web-server-${var.env_name}"
}
}
output "public_ip" {
value = aws_instance.web.public_ip
}
output "instance_type" {
value = aws_instance.web.instance_type
}
output "ami" {
value = aws_instance.web.ami
}
output "instance_state" {
value = aws_instance.web.instance_state
}
variables.tf
variable "env_name" {
description = "Environment name"
type = string
}
variable "instance_type" {
description = "EC2 instance type"
type = string
}
variable "ami_id" {
description = "AMI ID for the EC2 instance"
type = string
}
Note: We add outputs such as instance_type, ami, and instance_state to make it easier to validate in integration tests (since internal resources are not directly exposed, and state is a computed value from AWS).
2. Introduction to Terraform Test
Terraform Test is an integrated framework for writing tests for Terraform code. For integration tests, it allows:
- Real apply: Create actual resources on the cloud and validate them, with automatic destroy after the test finishes.
- Run blocks: Execute commands such as
applyorplanin a test environment. - Assertions: Validate conditions on outputs or resources.
To run tests, you need Terraform >= 1.6. Run terraform test from the project root. Tests will automatically run all .tftest.hcl files inside the tests/ folder.
3. Write Integration Test (Real Apply)
Integration tests apply real code to AWS, create actual resources, validate them, and destroy them afterwards. This helps verify that the code works correctly with the real provider.
Important notes:
- You need valid AWS credentials (e.g., via environment variables such as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY).
- This test will create (and destroy) real resources, so it may incur small costs (EC2 free tier may be free).
Create a tests folder and add integration.tftest.hcl.
run "integration_test_web_server" {
command = apply
assert {
condition = module.web_server.public_ip != null && module.web_server.public_ip != ""
error_message = "Public IP should not be null or empty after apply."
}
assert {
condition = module.web_server.instance_type == "t3.micro"
error_message = "Instance type does not match expected value."
}
assert {
condition = module.web_server.ami == "ami-0fa3fe0fa7920f68e"
error_message = "AMI ID does not match expected value."
}
assert {
condition = module.web_server.instance_state == "running"
error_message = "EC2 instance should be in running state."
}
}
Explanation of the Integration Test File
runblock: Executesapplywith the real provider (no mock). Terraform will create an actual EC2 instance.- Assertions: Validate outputs (e.g.,
public_ipis not null, since now it’s a real value from AWS). Assertion oninstance_stateverifies the instance is running (a computed value from AWS). - Automatic cleanup: After the test finishes (pass or fail), Terraform will destroy the resource to avoid leftovers.
To run the integration test:
terraform test -filter=integration.tftest.hcl
Or run all tests:
terraform test
4. Run Integration Test
Run the command from the project root:
taipham@Tais terraform2 % terraform test
tests/intergration.tftest.hcl... in progress
run "integration_test_web_server"... pass
tests/intergration.tftest.hcl... tearing down
tests/intergration.tftest.hcl... pass
tests/unit.tftest.hcl... in progress
run "test_web_server_intance_type"... pass
run "test_web_server_module_ami"... pass
run "test_web_server_module_ami_ip"... pass
tests/unit.tftest.hcl... tearing down
tests/unit.tftest.hcl... pass
Success! 4 passed, 0 failed.
5. Best Practices for Integration Tests in Terraform
- Limit usage: Use integration tests to verify real behavior, but limit them to avoid high costs (run in CI/CD with a dev account).
- Meaningful assertions: Validate inputs, outputs, tags, and resource states (such as "
running"). - Integrate with CI/CD: Run
terraform testin pipelines (e.g., GitHub Actions) for automation. - Advanced usage: Use
expect_failuresfor negative tests or test multiple scenarios via variables. - Combine with unit tests: Add unit tests with mocks for faster checks; here we focus on integration.
Conclusion
With integration tests, you can verify that your Terraform code works correctly in real environments without leaving leftover resources. In this example, we tested an EC2 instance with minimal cost.
Whether you need scalable software solutions, expert IT outsourcing, or a long-term development partner, ISB Vietnam is here to deliver. Let’s build something great together—reach out to us today. Or click here to explore more ISB Vietnam's case studies.
[References]
https://developer.hashicorp.com/terraform
https://www.sudeepa.com/?p=382 [Image link]


