tflint・terraform fmt・validateでコード品質を自動チェックする方法|pre-commitとCIへの組み込み手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Terraform > tflint・terraform fmt・validateでコード品質を自動チェックする方法|pre-commitとCIへの組み込み手順
terraform applyを実行してから書き間違いに気づいた」「チームで開発していると、インデントや命名規則がバラバラになってPRの差分がノイズだらけになる」こういった問題を放置すると、Terraformコードのレビューコストが静かに積み上がっていきます。

この記事では、Terraformのコード品質を静的チェックで自動化する3つのツール(terraform fmt・terraform validate・tflint)の役割と使い分けを解説し、pre-commitフックへの組み込みとGitHub Actions CIへの統合手順をステップごとに説明します。動作確認環境はRocky Linux 9.4 / Ubuntu 24.04 LTSです。

この記事のポイント

・tflint / terraform fmt / validateは「規約違反・構文・書式」をそれぞれ担当する
・実行順序はfmt → validate → tflintの順が鉄則
・pre-commitフックに登録するとコミット前にチェックが自動実行される
・GitHub Actionsに組み込むとPRレビュー時にチェック結果が可視化される


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜterraform applyの前に静的チェックが必要なのか

Terraformのコード品質チェックを「applyが通ればよい」という運用にしていると、フィードバックサイクルが極端に遅くなります。applyにはプロバイダーの認証・初期化、リソースの依存関係の解決、tfstateの更新といったステップがあり、単純なタイポでも数十秒~数分待ってからエラーが出ることになります。

1. applyを起点にしたフィードバックサイクルの問題

例えば変数の参照ミス(var.region_namevar.reagion_nameとタイポした場合)は、terraform validateであれば即座に検出できます。しかしチェックをかけずにapplyすると、プロバイダーの初期化が完了した後にエラーが出るため、無駄な待ち時間が発生します。

自分のPCでの手元テストで「とりあえずapplyして確認する」習慣が染みつくと、CIに組み込んだ際も同じアプローチを取りがちです。その結果、CI実行時間が長くなり、PRごとのフィードバックが返ってくるまでの待機時間が伸びていきます。

静的チェックを最初に挟むことで、apply可能なコードかどうかをAPIコールなしに判定できます。認証情報が不要なため、ローカル開発環境でもCI環境でも同じコマンドが使えるのも利点です。

2. チーム開発でコード品質が崩れやすい理由

複数のエンジニアが同じTerraformリポジトリで作業する場合、各自のエディタ設定によってインデント幅や引用符の種類がバラバラになりやすいです。VSCodeでTabキーを使う人とスペース4つを使う人が混在すると、コードの差分が本質的な変更ではなくフォーマットの差分になります。

また、tflintを使わないと「構文は正しいが廃止予定のインスタンスタイプを使っている」「required_versionが未定義でプロバイダーバージョンが固定されていない」といった問題はコードレビューで見落とされがちです。レビュアーがプロバイダーの廃止スケジュールをすべて把握していることを前提にしないためにも、ツールによる自動チェックは有効です。

3つのツールの役割と実行順序を設計する

terraform fmt・terraform validate・tflintの3ツールは、それぞれ独立した問題領域をカバーしています。役割を正確に理解することで、どの順番で実行すべきかの設計判断が明確になります。

1. terraform fmt — HCLフォーマットの自動修正

terraform fmtはHCL(HashiCorp Configuration Language)のフォーマットを公式スタイルに揃えるコマンドです。インデントの深さ、引用符の統一(ダブルクォートへの統一)、属性のアライメントを自動修正します。

# フォーマット修正(差分を表示しながら上書き) $ terraform fmt # 変更があるファイル名だけ表示(修正はしない) $ terraform fmt --check main.tf variables.tf # 終了コードで確認(0=変更なし、1=変更あり) $ echo $? 1 # サブディレクトリも含めて再帰的に実行 $ terraform fmt -recursive

--checkフラグはファイルを修正せずに差分の有無だけを返します。CIではこのフラグを使い、フォーマットが崩れているコミットをブロックするのが一般的なパターンです。

2. terraform validate — 構文とプロバイダースキーマの整合性チェック

terraform validateはHCLの構文が正しいかどうか、および参照しているリソース・変数・出力が定義されているかをチェックします。実際にAPIを呼び出さないため、AWSの認証情報がなくても実行できます。ただしterraform initによるプロバイダーの初期化が完了していることが前提です。

以下はRocky Linux 9.4環境でterraform validateを実行したときの出力例です。リソース参照のタイポを検出しています。

$ terraform validate ╷ │ Error: Reference to undeclared resource │ │ on main.tf line 15, in resource "aws_instance" "web": │ 15: subnet_id = aws_vpc.main.id │ │ A managed resource "aws_vpc" "main" has not been declared in this module. ╵ $ echo $? 1

エラーメッセージはファイル名・行番号・問題のある式を明示します。参照先リソースのスペルミスや、モジュール間での変数受け渡しの型不一致なども検出できます。

validateで検出されないのは「構文は正しいが意図しない設定」です。たとえばinstance_type = "t2.micro"は構文的に正しいため、validateではスルーされます。この種の問題はtflintが担当します。

3. tflint — ベストプラクティス違反の検出

tflintは、構文チェックを超えて「実務上問題のある書き方」を検出するLinterです。デフォルトで有効なルールセットに加え、AWSやGCPなどクラウドプロバイダー固有のルールをプラグインで追加できます。

tflintが検出する問題の代表例は以下の通りです。

廃止予定のインスタンスタイプ:t2系は旧世代(t3系への移行推奨)
required_versionの未設定:Terraformバージョン固定なしでチーム開発すると挙動が変わるリスクがある
プロバイダーのバージョン制約なし:required_providersにversionを指定しないとリリースのたびに動作が変わりうる
廃止された属性:将来のプロバイダーバージョンで削除予定の属性を使っている

以下は実際の出力例です(Rocky Linux 9.4・tflint v0.54.0・tflint-ruleset-aws v0.34.0)。

$ tflint 3 issue(s) found: Warning: Missing version constraint for provider "aws" in "required_providers" (terraform_required_providers) on main.tf line 1: 1: terraform { Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.9.1/docs/rules/terraform_required_providers.md Warning: "t2.micro" is previous generation instance type. (aws_instance_previous_type) on main.tf line 10: 10: instance_type = "t2.micro" Reference: https://github.com/terraform-linters/tflint-ruleset-aws/blob/v0.34.0/docs/rules/aws_instance_previous_type.md Warning: terraform "required_version" attribute is required (terraform_required_version) on main.tf line 1: 1: terraform {

4. fmt → validate → tflintの順序が正しい理由

3つのツールはterraform fmtterraform validatetflintの順序で実行するのが正しい設計です。

フォーマットが崩れたままのファイルはコードとして読みにくく、後続のチェックで誤検知が出ることもあります。まずfmtでフォーマットを揃え、次にvalidateで構文とリソース参照の整合性を確認し、最後にtflintでベストプラクティス準拠を確かめる順序は「問題を早い段階から解消する」原則に沿っています。

また、terraform validateはプロバイダーの初期化(terraform init)が必要で、tflintはtflint --initで独自にプラグインを取得します。この2つは独立しているため、validateとtflintを並列実行するオプションもありますが、シンプルな構成では直列実行で十分です。

tflintのインストールと.tflint.hclの設定

1. インストール手順(Rocky Linux 9.4 / Ubuntu 24.04 LTS)

tflintはシングルバイナリで配布されており、パッケージマネージャを使わずにインストールできます。

# Rocky Linux 9.4 / Ubuntu 24.04 LTS どちらも同じ手順 $ TFLINT_VERSION="0.54.0" $ curl -sLo tflint.zip \ "https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/tflint_linux_amd64.zip" $ unzip tflint.zip -d /tmp/tflint $ sudo mv /tmp/tflint/tflint /usr/local/bin/ $ sudo chmod +x /usr/local/bin/tflint # バージョン確認 $ tflint --version TFLint version 0.54.0 + ruleset.terraform (0.9.1-bundled)

公式インストールスクリプトを使う方法もあります。

# 公式インストールスクリプト(curl経由) $ curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash

2. .tflint.hclの基本設定とAWSプラグインの有効化

tflintは実行ディレクトリ(またはホームディレクトリ)の.tflint.hclで設定を読み込みます。Terraformのリポジトリルートに配置するのが一般的です。

# .tflint.hcl(リポジトリルートに配置) config { # プラグインの保存先(デフォルト: ~/.tflint.d/plugins) plugin_dir = ".tflint.d/plugins" } # Terraform基本ルールセット(バンドル済み) plugin "terraform" { enabled = true version = "0.9.1" source = "github.com/terraform-linters/tflint-ruleset-terraform" # 推奨ルールを一括有効化 preset = "recommended" } # AWSプロバイダー固有のルールセット plugin "aws" { enabled = true version = "0.34.0" source = "github.com/terraform-linters/tflint-ruleset-aws" }

preset = "recommended"を指定すると、recommended設定のルール(required_version・required_providersのバージョン制約など)が一括で有効になります。個別ルールを細かくオン・オフしたい場合はruleブロックを追加します。

# 特定ルールを無効化する例(.tflint.hclに追記) rule "terraform_required_version" { enabled = false }

3. tflint --initでプラグインを取得する

.tflint.hclを配置したら、tflint --initでプラグインをダウンロードします。初回のみ必要な操作です。

$ tflint --init Installing "terraform" plugin... Installed "terraform" (source: github.com/terraform-linters/tflint-ruleset-terraform, version: 0.9.1) Installing "aws" plugin... Installed "aws" (source: github.com/terraform-linters/tflint-ruleset-aws, version: 0.34.0) # インストール確認 $ ls .tflint.d/plugins/ github.com

CIではtflint --initをワークフローのステップとして実行し、プラグインディレクトリをキャッシュすることで実行時間を短縮できます。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、tflint・terraform fmt・validateをCI/CDパイプラインに組み込み、コード品質チェックを自動化するIaCスキルをハンズオン形式で習得できるセミナーを開催しています。
>> Terraform実践セミナーの詳細はこちら

pre-commitフックへの組み込み手順

pre-commitは、Gitのコミット前フック(.git/hooks/pre-commit)を一元管理するフレームワークです。複数のチェックツールを.pre-commit-config.yamlで設定し、git commitを実行するたびに自動でチェックが走ります。

1. pre-commitフレームワークのインストール

# pipでインストール(Python 3.8以上が必要) $ pip install pre-commit # バージョン確認 $ pre-commit --version pre-commit 3.7.1 # または pipx を使う(グローバルインストール時に推奨) $ pipx install pre-commit

2. .pre-commit-config.yamlの設定

リポジトリルートに.pre-commit-config.yamlを配置します。ここでは3ツールに絞った最小構成を示します。

# .pre-commit-config.yaml repos: - repo: https://github.com/antonbabenko/pre-commit-terraform rev: v1.96.1 hooks: # terraform fmt --check(フォーマットチェック) - id: terraform_fmt # terraform validate(構文・スキーマチェック) - id: terraform_validate # tflint(ベストプラクティスチェック) - id: terraform_tflint args: - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl

pre-commit-terraformはterraform関連フックをまとめたコミュニティリポジトリです。revにはGitHubリリースのタグを指定します。使用するTerraformバージョンとの互換性を定期的に確認することを推奨します。

フックをインストールします。

# .git/hooks/pre-commitとして登録 $ pre-commit install pre-commit installed at .git/hooks/pre-commit # 全ファイルに対して手動で試し実行 $ pre-commit run --all-files

3. コミット前の動作確認

実際にコミットを試みて、フォーマットが崩れたファイルや構文エラーがある場合にブロックされることを確認します。

$ git add main.tf $ git commit -m "add ec2 instance" terraform_fmt...........................................................Failed - hook id: terraform_fmt - exit code: 1 Files were modified by this hook. Additional output: main.tf # terraform_fmt がファイルを自動修正したためコミットはブロックされた # 修正後のファイルを再ステージしてコミットする $ git add main.tf $ git commit -m "add ec2 instance" terraform_fmt...........................................................Passed terraform_validate......................................................Passed terraform_tflint........................................................Passed [main 3f2a1b4] add ec2 instance

terraform_fmtフックはファイルを自動修正したうえでコミットを失敗させます。修正後のファイルをgit addしてから再度コミットする手順になります。この挙動に違和感がある場合は、git add -pで差分を確認する習慣をつけると見通しがよくなります。

GitHub Actions CIへの組み込み手順

pre-commitはローカルのチェックですが、GitHub ActionsによるCIに組み込むことで「フックを無効化してコミットした場合」「他のブランチからのマージ」も含めてチェックを強制できます。

1. チェック専用ジョブの設計方針

コード品質チェックはterraform plan・applyと分離した独立ジョブとして設計します。チェックジョブはAWSの認証情報を必要としないため(terraform validateはinitが必要ですが認証なしで実行できます)、セキュリティリスクが低く、PRのたびに高速に実行できます。

トリガー:pull_requestイベント(opened・synchronize)
認証:不要(チェックのみ)
pathsフィルター:.tfファイルに変更がないPRではワークフローをスキップ

2. ワークフローYAMLの全体構成

# .github/workflows/terraform-lint.yml name: Terraform Lint on: pull_request: branches: - main paths: - '**.tf' - '**.tfvars' - '.tflint.hcl' jobs: terraform-lint: name: Terraform Code Quality Check runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: "1.9.8" - name: Terraform Init run: terraform init -backend=false - name: Terraform Format Check run: terraform fmt --check -recursive - name: Terraform Validate run: terraform validate - name: Setup TFLint uses: terraform-linters/setup-tflint@v4 with: tflint_version: v0.54.0 - name: TFLint Init run: tflint --init - name: TFLint Run run: tflint --format=compact

terraform init -backend=falseはバックエンドの初期化をスキップしてプロバイダーのスキーマだけをダウンロードします。S3バックエンドの認証なしにvalidateを実行するための定番の設定です。

pathsフィルターを設定することで、.tfファイルに変更がないPR(ドキュメントや設定ファイルのみの変更)ではワークフローが起動しないようにできます。不要なCI実行を減らし、コストと待ち時間を削減できます。

PRがこのワークフローをトリガーすると、GitHub ActionsのUIのChecksタブにチェック結果が表示されます。フォーマットエラーや構文エラーがある場合は該当ステップで失敗し、マージをブロックします(Branch protection rulesと組み合わせた場合)。

よくあるエラーと対処法

「Failed to initialize plugins」エラー(tflint --init)

$ tflint --init Failed to initialize plugins; Diagnostics: ... plugin "aws" is not installed

原因と対処法は以下の通りです。

プロキシ環境:GitHubへの通信がブロックされている場合はHTTPSプロキシを設定する(export HTTPS_PROXY=http://proxy.example.com:3128
バージョン不一致:.tflint.hclのpluginバージョンが存在しないタグを指定している。GitHubのリリースページで有効なタグを確認する
plugin_dirの権限:plugin_dirで指定したディレクトリへの書き込み権限がない。先にディレクトリを作成する(mkdir -p .tflint.d/plugins

terraform validate「Could not load plugin」エラー

$ terraform validate ╷ │ Error: Could not load plugin │ │ Plugin reinitialization required. Please run "terraform init". │ │ Plugins are external binaries that Terraform uses to access and │ manipulate resources. The configuration's requirements have changed │ since the last "terraform init" ran. ╵

terraform initが完了していないか、.terraform/ディレクトリが存在しない状態でvalidateを実行した際に発生します。terraform init -backend=falseを先に実行することで解決します。CIではvalidateステップの前にinitステップを必ず配置してください。

pre-commitフックがスキップされるケース

以下のケースではpre-commitフックが動作しません。

git commit --no-verifyを使った場合:フックを意図的にスキップするオプションです。緊急時のみ使い、通常の運用では使わないようにチームで合意することを推奨します
GUIクライアントでのコミット:一部のGUIツールはフックを実行しないデフォルト設定になっている場合があります。使用ツールの設定を確認してください
pre-commit installを実行していない端末:新しいメンバーがリポジトリをクローンした際にpre-commit installを実行しないとフックが登録されません。READMEにセットアップ手順として明記するか、Makefileにmake setupコマンドとして組み込む方法が有効です

CIで全員のコードにチェックをかけることで、pre-commitを設定していない端末からのコミットもブロックできます。pre-commitはローカルでの早期発見、CIはチーム全体への強制、という二段構えが推奨パターンです。

まとめ — 3ツールのチェック範囲と役割一覧

ツール チェック範囲 認証不要か 自動修正
terraform fmt HCLフォーマット(インデント・引用符・配置) 不要 あり(--checkなしの場合)
terraform validate HCL構文・リソース参照・変数定義の整合性 不要(terraform init必要) なし
tflint ベストプラクティス違反・廃止予定属性・プロバイダー固有ルール 不要(tflint --init必要) なし
3ツールを組み合わせることで、「フォーマットの統一」「構文エラーの早期発見」「ベストプラクティス準拠の自動確認」を実現できます。pre-commitでローカルでの早期発見を実現し、GitHub Actions CIでチーム全体への強制を確保する二段構えが、現場での標準的な設計です。
TerraformのコードQA設計からCI/CD統合・モジュール設計まで、現役サーバー管理者が直接指導する少人数ハンズオンセミナーを開催しています。「設計の型」を体系的に習得したい方はぜひご確認ください。
>> Terraform実践セミナーの詳細はこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。