Terraform

Terraform fmt 徹底ガイド: Associate 試験と実務で使い倒すコードフォーマッタ

2026-04-19
NicheeLab編集部

terraform fmt は、Terraform 言語ファイルを公式のカノニカルスタイルに自動整形するコマンドです。コードの可読性と差分の安定化に直結します。

HashiCorp Terraform Associate(基礎)でも、fmt の役割や validate との違い、CI での使い方がよく問われます。ここでは公式の安定した挙動に絞って、現場でそのまま使える知識に落とし込みます。

terraform fmt の基本と試験ポイント

terraform fmt は .tf および .tfvars などの Terraform 言語ファイルを、公式スタイルに従って上書き整形します。構文や意味を変えず、空白・インデント・改行などのレイアウトのみを正規化します。

Associate 試験では「コードスタイルを統一するにはどのコマンドを使うか」「CI で整形ずれを検出してビルドを失敗させるにはどうするか」といった観点で問われます。fmt は構文検証(validate)や実行計画(plan)とは役割が異なる点を明確に押さえてください。

  • デフォルトはカレントディレクトリのファイルを整形(再帰はしない)
  • ディレクトリまたは個別ファイルを引数に指定可能
  • 整形スタイルは Terraform 公式のカノニカル形式に準拠
  • JSON バリアント(.tf.json / .tfvars.json)は整形対象外
  • 構文エラーの検出は目的外(それは validate の役割)

基本的な使い方

terraform fmt
terraform fmt main.tf
terraform fmt ./modules/network

主要オプションと実務での組み合わせ

実務でよく使うのは、-recursive(再帰)、-check(書き換えず整形ずれを検出)、-diff(差分表示)、-write=false(出力のみ、上書きしない)、-list=false(ファイル名の列挙を抑制)の組み合わせです。目的に応じて適切に選びます。

CI では「ファイルを上書きせず、整形ずれを検出して失敗させ、必要なら差分を表示する」のが定石です。ローカルでは上書き整形で構いません。

  • -recursive: サブディレクトリも処理。大規模リポジトリで有用
  • -check: 書き換えずに整形要否を判定。未整形があると非ゼロ終了コード
  • -diff: 変更が必要な箇所を unified diff で表示
  • -write=false: ファイルを上書きせず、整形結果を標準出力へ
  • -list=false: 整形差分があるファイル名の出力を抑制(ログを簡潔に)
  • -no-color: CI ログの可読性を上げたいときに併用

よく使うコマンド例

# リポジトリ全体を再帰的に上書き整形(ローカル作業)
terraform fmt -recursive

# CI 向け: 書き換えず、差分を表示し、未整形があれば失敗
terraform fmt -check -diff -recursive

# ログを簡潔に(ファイル名の列挙を抑制)
terraform fmt -check -diff -list=false -recursive

# プレビューだけ確認(上書きしない)。単一ファイルに向く
terraform fmt -write=false main.tf > main.tf.preview

CI に組み込むときの設計とワークフロー

CI では、pull request 単位で terraform fmt -check -diff -recursive を実行し、未整形があればパイプラインを失敗させます。-diff を併用すると、レビューアは PR のログで必要な変更点を即座に把握できます。

チームで安定した結果を得るために、CI とローカルで同一系統の Terraform バージョンを使うのが無難です。整形ルールは公式実装に内包されるため、ツールを追加インストールする必要はありません。

  • 失敗条件は「未整形ファイルが一つでもあること」
  • 差分表示は -diff。書き換えは行わない(-check が優先)
  • PR で失敗させ、開発者にローカルで fmt 実行を促す
  • 大規模モノレポでは対象ディレクトリを絞る運用も有効

CI での基本フロー(例)

Dev(PR作成)CI Trigger(PR/Open/Push)terraform fmt -check-diff -recursivevalidate(任意)plan/apply保護ブランチでDev → CI Trigger → terraform fmt -check -diff -recursive → validate → plan/apply (保護ブランチで)

GitHub Actions 例

name: terraform-fmt-check
on:
  pull_request:
jobs:
  fmt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.x
      - name: Check formatting
        run: terraform fmt -check -diff -recursive

フォーマット対象と非対象、パス設計のコツ

fmt の主対象は Terraform 言語ファイル(.tf、.tfvars、.auto.tfvars など)です。JSON バリアント(.tf.json / .tfvars.json)は対象外です。テンプレート文字列やヒアドキュメントの内容など、言語リテラルの中身は基本的に変更されません。

再帰実行では指定ディレクトリ配下をたどります。依存モジュールを格納する .terraform ディレクトリは通常コード管理の対象外であり、CI では誤って処理対象に含めないよう、パスを明示指定したり、シェルの find で除外する運用が安全です。

  • 対象: .tf、.tfvars、.auto.tfvars など Terraform 言語ファイル
  • 非対象: .tf.json、.tfvars.json(JSON バリアント)
  • 文字列リテラル(含ヒアドキュメント)の中身は原則保持
  • 処理対象は明示パス指定で絞ると安全(例: ./modules, ./envs)

.terraform ディレクトリを除外して整形(bash 例)

# .terraform を除外し、見つかった .tf を個別に fmt
find . -type d -name .terraform -prune -o -name '*.tf' -print0 | xargs -0 -n1 terraform fmt

よくある落とし穴とトラブルシュート

terraform fmt -write=false は「上書きせず標準出力に整形後を出す」動作です。複数ファイルに適用すると出力が連結されるため、プレビュー用途は単一ファイルに限定するのが無難です。差分を見たい場合は -diff を使います。

整形しても差分が残るケースは、文字列リテラル内部の空白や改行、コメント位置など、fmt の対象外部分が原因であることが多いです。また Terraform のメジャー/マイナー差で微細な整形差が生じる可能性があるため、チームで CLI の系統を揃えると安定します。

  • プレビューは -diff または単一ファイル + -write=false
  • 複数ファイルに -write=false は出力が混ざる点に注意
  • fmt はスタイルのみ変更。構文エラー検出は validate の役割
  • CLI バージョンが混在すると微妙な差が出ることがある

ヒアドキュメント内は内容維持(例)

resource "local_file" "example" {
  content = <<-EOT
  indented line
  another   spaced   line
  EOT
  filename = "example.txt"
}
# fmt はブロックやインデントを正規化しますが、ヒアドキュメント内部の空白は保持されます。

試験向け: fmt と他コマンドの違い(要点整理)

Associate で頻出なのは、fmt と validate の役割分担です。fmt はスタイル統一、validate は構文および一部の静的検証、plan は実行計画の作成という三者三様の目的を持ちます。フォーマットの有無で挙動は変わりませんが、レビュー容易性と差分の安定化のために fmt は必須運用です。

Linter(例: tflint)はベストプラクティスやポリシー準拠の検査を行いますが、公式 CLI の範囲ではありません。試験回答ではまず公式コマンドの役割を優先して選択します。

  • fmt: 見た目(スタイル)の正規化。意味は変えない
  • validate: 構文/参照の静的検証。意味は変えない
  • plan: 変更点の計画を作る。状態やプロバイダと対話
  • tflint(参考): ベストプラクティス検査。非公式
コマンド/ツール主目的ファイル上書き失敗の典型条件
terraform fmtスタイルの正規化(整形)既定で上書き(-write=false で回避)未整形(-check 時に非ゼロ終了)
terraform validate構文・型・参照の検証しない構文/参照エラーの検出
tflint(参考)Lint によるベストプラクティス検査しないルール違反の検出(設定による)

fmt → validate の最小パイプライン例

terraform fmt -recursive .
terraform validate

問題で確認

Associate

問題 1

チームの CI で、Terraform コードが公式スタイルに整形されていない場合はビルドを失敗させ、必要な変更点はログに差分として表示したい。最も適切なコマンドはどれか。

  1. terraform fmt -check -diff -recursive
  2. terraform fmt -write=false -recursive
  3. terraform validate -no-color
  4. terraform plan -out=tfplan

正解: A

CI でファイルを書き換えずに未整形を検出しつつ、変更点を表示するには、-check と -diff の併用が適切です。-recursive で配下も対象にします。-write=false は出力を標準出力に流すだけで不整形の検出/失敗は行いません。validate と plan は目的が異なります。

よくある質問

terraform fmt は .tf.json や .tfvars.json を整形しますか?

いいえ。terraform fmt は Terraform 言語ファイル(.tf、.tfvars など)を対象とし、JSON バリアント(.tf.json、.tfvars.json)は整形しません。

未整形があるときの終了コードは決まっていますか?

terraform fmt 自体は整形を行います。-check を付けた場合、未整形が一つでもあると非ゼロ終了コードで終了します(具体的な数値に依存しない前提で運用するのが安全です)。

プロジェクトのどこで terraform fmt を実行するのが良いですか?

ローカルでは保存時やコミット前に実行し、CI では pull request 時に -check -diff -recursive を実行するのが定石です。大規模リポジトリでは対象ディレクトリを明示し、.terraform など依存物は処理から外す運用が安全です。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (101件)
© 2026 NicheeLab All rights reserved.