【実務・中級編】【Terraform 1.6以降】testコマンドを活用したインフラの単体テスト(Unit Test)入門 – インフラ構成管理(IaC)活用バイブル

Terraform 1.6+ のテスト革命:インフラを「品質保証可能なコード」へ昇華させる

「Terraformのコードを書いて `apply` するまで、祈るように待つ」。そんな時代は終わった。

かつて我々は、Terraformのテストといえば `terratest` を使い、Goのコードを書き、クラウド上に実際にリソースを立ち上げては壊すという、遅くてコストのかかる手法に甘んじていた。しかし、Terraform 1.6で標準搭載された `terraform test` は、そのゲームのルールを根本から変えた。

本稿では、単なるマニュアルの解説はしない。現場のテックリードとして、「なぜこのテスト手法が開発速度を劇的に向上させるのか」、そして「チームの生産性を極限まで高めるための構成術」を授ける。

—

1. なぜ「terraform test」がゲームチェンジャーなのか

Terraform 1.6以降のネイティブテストの真価は、「実環境へのデプロイを介さずに、計画(Plan)の妥当性を検証できる」点にある。

  • フィードバックループの高速化: `go test` を書く必要はない。HCLでテストを書ける。
  • モックによる高速化: `mock_provider` を活用すれば、IAM権限を気にせず、ネットワーク疎通も不要な、閉じた世界での単体テストが完結する。
  • 冪等性の担保: `apply` 後に `plan` して「差分なし」を確認するステップをCIに組み込めば、ドリフト問題は過去の遺物となる。

—

2. 実践:モックを活用したテスト構成

テストファイルは `tests/` ディレクトリ配下に配置する。Terraformは `tests/` 内の `.tftest.hcl` を自動的に認識する。

構成例: `tests/s3_bucket.tftest.hcl`

モックプロバイダーでS3をシミュレート
mock_provider “aws” {
alias = “main”
}

run “s3_bucket_validation” {
# テスト対象のモジュールを指定
command = plan

# 変数を注入
variables {
bucket_name = “my-test-bucket”
}

# ここが肝:リソースのプロパティを検証
assert {
condition = aws_s3_bucket.main.bucket == “my-test-bucket”
error_message = “バケット名が期待値と異なります”
}

assert {
condition = aws_s3_bucket_versioning.main.versioning_configuration[0].status == “Enabled”
error_message = “バージョニングが無効です。本番環境では必須です。”
}
}

このテストは、AWS APIを一切叩かない。CIパイプラインにおいて数秒で完了し、「設定ミス」というインフラのバグをデプロイ前に根絶できる。

—

3. 開発スピードを最大化する「神」ツールと設定

効率的にテストを回すためには、開発環境のセットアップがすべてだ。

VS Code 必須プラグイン

  • Terraform (HashiCorp公式): 言わずもがな。
  • TFLint: `terraform test` は論理的な整合性を測るが、TFLintは「クラウドのベストプラクティス」を測る。この二段構えこそが最強だ。
  • Error Lens: エラーや警告をコード行の末尾に表示する。これだけでデバッグ効率が3倍になる。

生産性を倍増させるキーボードショートカット

  • `Cmd + Shift + P` -> `Terraform: Format` (保存時自動実行設定は必須)
  • `Cmd + Shift + P` -> `Terraform: Init` (新規モジュール追加時の儀式)

—

4. チームで勝つためのベストプラクティス

属人化を排除し、コードの品質を担保するための「ルール」を共有しよう。

1. 「テスト駆動インフラ開発 (TDID)」の導入

機能追加の前に、必ず `assert` を書くこと。「このリソースは絶対にパブリックアクセス不可であるべき」という制約を先にコード化する。これが一番の守りになる。

2. 設定ファイルの標準化(JSON/YAMLの扱い)

モジュール間での定数共有には、`locals` で JSON を読み込む手法が最も堅牢だ。

locals.tf
locals {
# 設定を外部化することで、テスト時にテスト用の設定を注入しやすくなる
config = jsondecode(file(“${path.module}/config.json”))
}

3. CI/CDパイプラインの標準化

チームのルールとして、以下のステップを CI (GitHub Actions等) に強制する。
1. `terraform fmt -check` (スタイルの統一)
2. `tflint` (静的解析)
3. `terraform test` (単体テスト)
4. `terraform plan -out=tfplan` (実行計画の保存)

—

伝説のエンジニアからの最後のアドバイス

「コードは負債である」とよく言われるが、「テストがないインフラコードは、時限爆弾である」。

Terraform 1.6の `test` コマンドを使いこなすことは、単なる新機能の習得ではない。インフラエンジニアが「オペレーター」から「ソフトウェアエンジニア」へと進化するための通過儀礼だ。

まずは今すぐ、あなたのレポジトリにある一つのモジュールに対して、テストを一行書いてみてほしい。その瞬間から、あなたの `terraform apply` は、緊張を伴う作業から、確信に満ちたデプロイへと変わるはずだ。

さあ、コードを書こう。そのインフラを、誰よりも強固で、美しいものにするために。

タイトルとURLをコピーしました