terraform fmt / validate — コード整形と構文チェック

1. 概要

  • terraform fmt — HCLコードを自動整形する
  • terraform validate — 設定ファイルの構文と論理を検証する
  • CI/CDパイプラインへの組み込み方
  • よく使うオプション

terraform fmtterraform validateはコード品質を保つための基本コマンドです。fmtはインデントやスペースを自動修正し、validateは構文エラーや参照ミスを事前に検出します。


2. terraform fmt — コードを自動整形する

terraform fmtはTerraformの標準スタイルに従ってHCLコードを自動整形します。手動でインデントを揃える必要がなくなります。

# カレントディレクトリを整形
$ terraform fmt

# 再帰的にすべてのサブディレクトリも整形
$ terraform fmt -recursive

# 差分のみ表示(実際には変更しない)
$ terraform fmt -check -diff

整形前後の比較

# 整形前(インデントがバラバラ)
resource "aws_instance" "web" {
ami = "ami-abc123"
  instance_type = "t3.micro"
   tags = {
  Name = "web"
 }
}
# 整形後(terraform fmt適用後)
resource "aws_instance" "web" {
  ami           = "ami-abc123"
  instance_type = "t3.micro"
  tags = {
    Name = "web"
  }
}

terraform fmtはインデント(2スペース)・等号の位置揃え・改行の正規化を自動で行います。


3. terraform validate — 設定を検証する

terraform validateはHCLの構文チェックと、リソース間の参照が正しいかを検証します。terraform planより高速で、applyの前に実行するのが推奨です。

# カレントディレクトリを検証
$ terraform validate

# 成功時の出力
Success! The configuration is valid.

# エラー時の出力例
Error: Reference to undeclared resource
  on main.tf line 15, in resource "aws_instance" "web":
  15:   subnet_id = aws_subnet.nonexistent.id

validateが検出できるエラーの例

terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

# ❌ 以下はvalidateでエラーになる例
resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  # 存在しないリソースを参照 → validateで検出される
  # subnet_id = aws_subnet.nonexistent.id

  # 存在しない属性を参照 → validateで検出される
  # availability_zone = aws_vpc.main.nonexistent_attr

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${var.environment}-web"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

4. fmt vs validate の違い

比較terraform fmtterraform validate
目的コードスタイルの整形構文・参照の検証
修正ファイルを自動修正する修正はしない(報告のみ)
AWS接続不要不要(terraform initは必要)
検出できるエラーインデントの乱れ・スタイル違反構文エラー・未定義リソース参照・型ミスマッチ
検出できないエラー実行時エラー(AMI IDが存在しない等)

5. CI/CDへの組み込み

GitHub Actionsでのサンプルです。

# .github/workflows/terraform.yml
name: Terraform CI

on: [push, pull_request]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3

      - name: terraform init
        run: terraform init

      - name: terraform fmt check
        run: terraform fmt -check -recursive

      - name: terraform validate
        run: terraform validate

terraform fmt -checkは整形が必要なファイルがあれば非ゼロ終了コードを返すため、CIで整形チェックとして使えます。


6. 関連記事


7. まとめ

  • terraform fmt — HCLを自動整形。-recursiveでサブディレクトリも対象、-checkでCI用チェック
  • terraform validate — 構文と参照の検証。terraform init後に使える
  • fmtは「スタイル」の修正、validateは「論理」の検証という役割分担
  • CI/CDではfmt -checkvalidateplanの順で実行するのが定番
  • どちらもAWSへの接続は不要で高速に実行できる

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/cli/commands/fmt