1. 概要
terraform testコマンドとは(Terraform 1.6+).tftest.hclファイルの書き方assertブロックによる検証- モジュールのテスト
- 実際のインフラを使ったテストとモック
Terraform 1.6で導入されたterraform testコマンドを使うと、TerraformコードをHCLのテストファイルで検証できます。モジュールの正確性を自動テストで保証し、リグレッションを防ぎます。
2. 基本的な使い方
# テストを実行(カレントディレクトリ内の*.tftest.hclを自動検出)
$ terraform test
# 特定のテストファイルのみ実行
$ terraform test -filter=tests/network.tftest.hcl
# 詳細出力
$ terraform test -verbose
テストファイルはtests/ディレクトリに.tftest.hcl拡張子で置きます。
3. テストファイルの基本構造
# tests/main.tftest.hcl
# テストで使う変数
variables {
environment = "test"
instance_type = "t3.micro"
}
# run ブロック: 1つのテストケース
run "ec2_instance_created" {
# commandはplan(デフォルト)またはapply
command = plan
# planの結果を検証
assert {
condition = aws_instance.web.instance_type == "t3.micro"
error_message = "インスタンスタイプがt3.microではありません"
}
assert {
condition = aws_instance.web.tags["Environment"] == "test"
error_message = "Environmentタグが正しく設定されていません"
}
}
4. テスト対象のモジュール例と完全なテスト
# modules/compute/main.tf(テスト対象)
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
variable "environment" {
description = "環境名"
type = string
}
variable "instance_type" {
description = "EC2インスタンスタイプ"
type = string
default = "t3.micro"
}
variable "vpc_id" {
description = "VPC ID"
type = string
}
variable "subnet_id" {
description = "サブネットID"
type = string
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = var.instance_type
subnet_id = var.subnet_id
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
output "instance_id" {
value = aws_instance.web.id
}
output "private_ip" {
value = aws_instance.web.private_ip
}
# modules/compute/tests/compute.tftest.hcl
provider "aws" {
region = "ap-northeast-1"
}
# モックプロバイダー(実際のAWS APIを呼ばない)
mock_provider "aws" {
mock_resource "aws_instance" {
defaults = {
id = "i-mock1234567890"
private_ip = "10.0.1.100"
}
}
mock_data "aws_ami" {
defaults = {
id = "ami-mock1234567890"
}
}
}
variables {
environment = "test"
instance_type = "t3.micro"
vpc_id = "vpc-test1234"
subnet_id = "subnet-test1234"
}
run "correct_instance_type" {
command = plan
assert {
condition = aws_instance.web.instance_type == var.instance_type
error_message = "インスタンスタイプが変数と一致しません: ${aws_instance.web.instance_type}"
}
}
run "correct_tags" {
command = plan
assert {
condition = aws_instance.web.tags["Environment"] == var.environment
error_message = "Environmentタグが正しくありません"
}
assert {
condition = aws_instance.web.tags["ManagedBy"] == "terraform"
error_message = "ManagedByタグが設定されていません"
}
assert {
condition = aws_instance.web.tags["Name"] == "${var.environment}-web"
error_message = "Nameタグが正しくありません"
}
}
run "ebs_encrypted" {
command = plan
assert {
condition = aws_instance.web.root_block_device[0].encrypted == true
error_message = "EBSボリュームが暗号化されていません"
}
}
5. テスト実行結果
$ terraform test
compute.tftest.hcl... in progress
run "correct_instance_type"... pass
run "correct_tags"... pass
run "ebs_encrypted"... pass
compute.tftest.hcl... tearing down
compute.tftest.hcl... pass
Success! 3 passed, 0 failed.
6. mock_provider vs 実際のapply
| 方法 | 速度 | コスト | 何をテストするか |
|---|---|---|---|
command = plan | 高速 | 無料 | 設定値・タグ・型チェック |
mock_provider | 高速 | 無料 | planに近い検証(APIなし) |
command = apply | 低速 | AWSコスト発生 | 実際のリソース作成・属性 |
通常のCI/CDではplan + mock_providerでテストし、結合テストのみapplyを使います。
7. 関連記事
- CI/CDパイプラインとTerraform — GitHub Actionsでterraform testを実行
- check ブロック — 実行後の条件検証 — デプロイ後の継続的な検証
- precondition / postcondition — リソース作成時の検証
- precondition / postcondition — ライフサイクル中の条件検証
- terraform fmt / validate — コード整形と構文チェック
- resourceブロック — 基本構文と使い方
8. まとめ
terraform test(1.6+)で.tftest.hclファイルにテストケースを記述できるassertブロックで変数・タグ・設定値の正確性を検証するmock_providerでAWSへのAPI呼び出しなしに高速テストできるcommand = applyで実際のリソース作成を検証できる(コスト注意)- モジュール開発にはテストを必ず組み込み、リグレッションを防ぐ
動作確認バージョン: Terraform >= 1.6 公式ドキュメント: https://developer.hashicorp.com/terraform/language/tests