---
title: "Terragruntとは？v1.1の使い方｜root.hcl・run –all・filterの実際の挙動"
url: "https://www.issoh.co.jp/tech/details/12477/"
published: 2026-06-12
updated: 2026-10-09
categories: ["IaC"]
publisher: "株式会社一創"
---

# Terragruntとは？v1.1の使い方｜root.hcl・run –all・filterの実際の挙動

TerragruntはTerraformやOpenTofuの手前で動くオーケストレーションツールで、環境ごとに繰り返し書いていたbackend設定やprovider定義を1か所にまとめ、複数のディレクトリ（ユニット）を依存順に実行します。2026年3月30日にv1.0.0が出て、`run-all`の廃止や設定ファイル名の推奨変更など、0.x時代の解説記事がそのまま使えない変更が入りました。この記事では、Terragrunt v1.1.6とOpenTofu 1.13.1で検証用の構成（local backendと`terraform_data`だけの模擬モジュール）を実行した結果と、v1.1.6の公式ドキュメントをもとに、最小構成から旧版からの移行までを整理します。

## まとめ：Terragruntの役割とv1.x導入時の要点

- 役割は「設定の重複排除」と「複数ユニットの依存順実行」。リソースの作成や差分計算はOpenTofu／Terraform本体が行う
- 現行の安定版はv1.1.6（2026年9月21日）。v1.xの間はCLIのコマンド・フラグとHCL設定の後方互換が公式に保証されている
- 共通設定は`root.hcl`に置き、各ユニットは`find_in_parent_folders("root.hcl")`で読み込む。ルートを`terragrunt.hcl`にする構成は非推奨
- 一括実行は`terragrunt run --all -- plan`。`run-all`はv1.1.6では「unknown command」で止まる
- `--filter`でディレクトリを除外するときは`./prod/**`のように配下まで書く。`./prod`だけでは何も除外されない
- S3バケットなどのバックエンド資源は既定では作られない。`terragrunt backend bootstrap`か`--backend-bootstrap`で明示する
- 環境が1つでモジュールも数個なら、Terraform単体かworkspaceで足りる。Terragruntは環境×ユニットの組み合わせが増えてから入れる

## Terragruntの役割とTerraform・OpenTofuとの分担

### ラッパーとして担う範囲と既定の実行バイナリ

通常のインフラリソースの作成や差分計算はOpenTofu／Terraformが担いますが、Terragrunt自身もバックエンドの作成・管理などでクラウドAPIを呼びます。各ユニットの`terragrunt.hcl`を読み、共通設定のマージ、`backend.tf`や`provider.tf`の生成、モジュールのダウンロードを済ませてから、`.terragrunt-cache`配下の作業ディレクトリで`tofu`または`terraform`を起動します。v1.0.0からは`terraform`ブロックに`source`が無いユニットでも必ず`.terragrunt-cache`が作られるようになりました。

どちらのバイナリを使うかは`--tf-path`（環境変数`TG_TF_PATH`）で決まり、v1.1.6のヘルプでは既定値が「tofu (on PATH)」です。PATHに`tofu`が無くTerraformだけがある環境で実行すると、Terragruntは`terraform`を呼びました。両方を入れているマシンでTerraformを使いたい場合は、`--tf-path terraform`を明示しないとOpenTofuで実行されます。OpenTofuとTerraformの機能差は[OpenTofuとTerraformのライセンス・機能差と移行判断](/tech/details/15299/)で整理しています。

### v1.0以降の互換性保証とMITライセンス

TerragruntはGruntworkがMITライセンスで公開しており、GitHubのスター数は2026年10月9日時点のGitHub APIで9,874です。Terraformは1.6以降BUSL 1.1へ移りましたが、Terragrunt本体のライセンスは変わっていません。v1.0.0ではtflintの同梱をやめました。tflintがBUSLへ移ったため、同梱版が古い版のまま固定されていたことが理由です。

実務上の意味が大きいのは、公式の「Terragrunt 1.0 Guarantees」です。v1.xの間はCLIのコマンドとフラグを削除・改名せず、v1.0で有効だったHCL設定も有効なままと明記されています。裏を返すと、0.x系ではマイナーリリースでも破壊的変更が入っていました。v1.0より前の手順書は、旧コマンドや旧フラグ、ルート設定の記述を確認し、該当箇所を更新します。移行箇所は後半の対応表にまとめました。

## インストール手順と対応バージョンの確認

### Homebrew・公式スクリプト・Chocolateyでの導入

```
# macOS / Linux（Homebrew）
brew install terragrunt

# 公式インストールスクリプト（中身を確認してから実行する場合）
curl -sSfL --proto '=https' --tlsv1.2 -o install.sh https://terragrunt.com/install
less install.sh
bash install.sh

# Windows（Chocolatey）
choco install terragrunt

# 動作確認
terragrunt --version
```

Homebrewのformulaは2026年10月9日時点で1.1.6です。バイナリを直接取る場合はGitHub releasesから`terragrunt_darwin_amd64.tar.gz`などOSに合うアーカイブを取得し、`SHA256SUMS`で照合します。公式手順ではGPG署名（鍵指紋`68C8 0F86 DF98 E710 C0F2 2E2E 5777 74AC A847 CC49`）、Cosign、`gh release verify-asset`による検証も案内されています。v1.2.0は2026年10月7日時点でrc2の段階なので、CIでは1.1系の版を固定します。Terraform本体の入れ方は[Terraformの最新バージョンと確認・アップグレード手順](/tech/details/8928/)を参照してください。

### OpenTofu・Terraformとの互換表と公式テストの範囲

| 本体の版                | 公式テスト対象になったTerragrunt | 2026年10月時点の現行版 |
| ------------------- | --------------------- | -------------- |
| OpenTofu 1.12.x     | 1.0.5以降               | ―              |
| OpenTofu 1.13.x     | 1.2.0以降（rc段階）         | 1.13.1         |
| Terraform 1.14.x    | 0.94.0以降              | ―              |
| Terraform 1.15・1.16 | 表に未掲載                 | 1.16.5         |

この表はTerragruntのCIでテストしている組み合わせで、ドキュメントには「実際の互換性はこれより緩い」と注記があります。手元ではv1.1.6とOpenTofu 1.13.1、Terraform 1.16.5の両方で`plan`と`apply`が通りました。ただし表に無い組み合わせを本番に入れるなら、Terragrunt側の版をテスト対象に含まれる版へ上げるか、ステージングで一巡させてからにします。互換データは`https://docs.terragrunt.com/api/v1/compatibility/opentofu`からJSONでも取得できます。

## root.hclとterragrunt.hclで組む最小構成

### ディレクトリ構成とroot.hclの共通設定

```
live/
├── root.hcl              # 全ユニット共通（backend・provider）
├── dev/
│   ├── env.hcl           # dev固有の値
│   ├── network/terragrunt.hcl
│   └── app/terragrunt.hcl
└── prod/
    ├── env.hcl
    ├── network/terragrunt.hcl
    └── app/terragrunt.hcl
modules/
├── network/main.tf
└── app/main.tf
```

modules配下は、依存順を確かめるためにAWSを使わない模擬モジュールにしています。実際の構成では、VPCやEC2を作るモジュールに置き換えます。

```
# modules/network/main.tf
variable "cidr" { type = string }
resource "terraform_data" "vpc" { input = var.cidr }
output "vpc_id" { value = "vpc-${terraform_data.vpc.id}" }

# modules/app/main.tf
variable "vpc_id" { type = string }
variable "instance_type" { type = string }
resource "terraform_data" "app" { input = "${var.vpc_id}/${var.instance_type}" }
output "summary" { value = terraform_data.app.input }
```

Terragruntではモジュールを呼び出す単位を「ユニット」と呼び、1ユニット＝1ディレクトリ＝1つのstateになります。共通設定は`live/root.hcl`に一度だけ書きます。

```
remote_state {
  backend = "s3"
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite_terragrunt"
  }
  config = {
    bucket       = "example-tfstate-123456789012"
    key          = "${path_relative_to_include()}/tofu.tfstate"
    region       = "ap-northeast-1"
    encrypt      = true
    use_lockfile = true
  }
}

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOT
provider "aws" {
  region = "ap-northeast-1"
}
EOT
}
```

`path_relative_to_include()`はroot.hclから見たユニットの相対パスを返すため、`render`で展開するとdev/appユニットのkeyは`dev/app/tofu.tfstate`になりました。ユニットを増やしてもstateのキーを手で振る必要がありません。このS3版のroot.hclは、AWSに接続しない`hcl validate`と`render`で確認しました。依存順の実行は、backendを`local`に差し替えた同じ構成で検証しています。`use_lockfile = true`はDynamoDBを使わないS3ネイティブのロックで、Terraform 1.10で追加（1.11でGA）、OpenTofuは1.10から使えます。stateの構造やロックの仕組みは[Terraform stateとS3バックエンドの安全な扱い方](/tech/details/16525/)で解説しています。

### ユニット側のterragrunt.hclと設定の継承

```
include "root" {
  path = find_in_parent_folders("root.hcl")
}

locals {
  env = read_terragrunt_config(find_in_parent_folders("env.hcl")).locals
}

terraform {
  source = "../../../modules//network"
}

inputs = {
  cidr = local.env.cidr
}
```

`include`でroot.hclを取り込み、`read_terragrunt_config`で環境ごとの`env.hcl`を読みます。dev/env.hclの中身は次の4行だけです。

```
locals {
  cidr          = "10.10.0.0/16"
  instance_type = "t3.small"
}
```

prodはenv.hclの`cidr`と`instance_type`（例：`m7i.large`）だけを変えれば済み、ユニット側のterragrunt.hclはdevとprodで同じ内容になります。`source`の`//`はモジュールの取得範囲とサブディレクトリの区切りで、`modules`ディレクトリ全体をキャッシュへコピーしたうえで`network`を実行対象にします。モジュール側の分割粒度は[Terraform moduleの分割粒度とoutput設計](/tech/details/16527/)が参考になります。

### dependencyとmock\_outputsによるユニット間の値の受け渡し

appユニットはnetworkユニットが出力するVPC IDを使います。app/terragrunt.hclは、networkと同じ`include`と`locals`を書き、`terraform`ブロックのsourceだけを`../../../modules//app`に変えます。そのうえで次のdependencyとinputsを足します。

```
dependency "network" {
  config_path = "../network"

  mock_outputs = {
    vpc_id = "vpc-mock"
  }
  mock_outputs_allowed_terraform_commands = ["validate", "plan"]
}

inputs = {
  vpc_id        = dependency.network.outputs.vpc_id
  instance_type = local.env.instance_type
}
```

`mock_outputs`は、依存先をまだ一度もapplyしていない段階で`plan`を通すための仮の値です。mockを書かずに未適用のスタックで`run --all -- plan`を実行すると、networkのplanは成功し、appは「detected no outputs」のエラーで失敗しました。`mock_outputs_allowed_terraform_commands`にapplyを含めてはいけません。含めると、依存先の出力がない場合に仮のIDがapplyへ渡ります。リソースやproviderによって作成エラーや誤った値の保存につながるため、applyは許可対象から外します。

## run –allとfilterによる複数環境の一括実行

### 依存順に実行されるrun –allの挙動

```
cd live/dev
terragrunt run --all -- plan

# 実行結果の末尾（OpenTofu 1.13.1）
#   ❯❯ Run Summary  2 units  971ms
#      Succeeded    2
```

`live/dev`で実行すると、Terragruntはdependencyブロックから依存グラフを作り、networkを先に、appを後に実行します。依存グラフは`terragrunt dag graph`でDOT形式で確認でき、この構成では`"app" -> "network"`と出力されました。新規環境で`run --all -- apply`を流すと、networkのapply完了後にappが実際のVPC IDを受け取って作成されます。並列数は`--parallelism`で制限できます。

`run --all`でapplyすると、各ユニットへの`-auto-approve`が自動で付きます。実行前に「Are you sure you want to run ‘terragrunt apply’ in each unit of the run queue displayed above? (y/n)」という確認が一度だけ出ますが、`--non-interactive`を付けたCIではそれも出ません。`--no-auto-approve`は自動承認フラグの追加を止めるだけです。一括実行では標準入力を共有するため、個別承認が必要ならユニット単位で実行するか、CI側に承認工程を設けます。

### –filterのパス一致条件とprod配下の除外

環境を絞る指定は、v1.xでは`--filter`に集約されています（旧`--queue-exclude-dir`なども内部ではfilterへ変換されます）。注意点は、パス式が**ユニットのディレクトリそのもの**に一致する点です。

```
# 誤り：ユニットの親ディレクトリ名だけでは一致しない（4ユニットすべてが対象のまま）
terragrunt find --filter='!./prod'

# 正しい：配下のユニットまで含めて除外する（dev/app と dev/network だけが残る）
terragrunt find --filter='!./prod/**'
terragrunt run --all --filter='!./prod/**' -- plan
```

`live`直下で`--filter='!./prod'`を指定しても、prodはユニットではなく親ディレクトリなので一致せず、dev・prodの4ユニットすべてが残りました。同じ理由で、旧フラグの`--queue-exclude-dir prod`を付けた`run --all -- validate`も4ユニット全部を実行しています。本番除外のつもりで書いた指定が空振りすると、そのままprodへapplyが流れます。本番を触る前に`terragrunt find`へ同じfilterを渡し、対象ユニットの一覧を確認する手順をCIに入れておくのが確実です。

### –backend-bootstrapの既定値とバックエンド資源の作成条件

0.x時代の解説には「S3バケットが無ければTerragruntが自動で作る」と書かれたものが多くあります。v1.1.6のドキュメントでは`--backend-bootstrap`の既定値はfalseで、明示しない限りバケットもDynamoDBテーブルも作られません。

```
# 事前に一度だけ、S3バケットなどのバックエンド資源を作る
terragrunt backend bootstrap

# または実行時に作成を許可する
terragrunt run --all --backend-bootstrap -- plan
```

掲載設定でbootstrapすると、S3バケットにはバージョニングとサーバーサイド暗号化が設定されます。アクセスログは既定では無効で、有効化には`accesslogging_bucket_name`の指定が必要です。`dynamodb_table`を書いていればロック用テーブル（主キー`LockID`）も作られます。既存バケットの設定とremote\_stateの記述が違うと、TerragruntはS3側を記述に合わせて更新します。手で管理しているバケットなら`disable_bucket_update = true`で止めておきます。

## 0.x時代の設定から移行するときの対応表

| 0.x時代の書き方                      | v1.xでの書き方                            | 旧書式のまま実行した結果       |
| ------------------------------ | ------------------------------------ | ------------------ |
| `terragrunt run-all plan`      | `terragrunt run --all -- plan`       | unknown commandで停止 |
| `--terragrunt-non-interactive` | `--non-interactive`                  | tofuへ渡りflag未定義エラー  |
| `TERRAGRUNT_*`環境変数             | `TG_*`                               | ―                  |
| ルートの`terragrunt.hcl`           | `root.hcl`                           | 非推奨の警告             |
| `find_in_parent_folders()`     | `find_in_parent_folders("root.hcl")` | root.hclを見つけられずエラー |
| `--queue-exclude-dir`          | `--filter='!./dir/**'`               | filterの別名として動作     |
| 同梱のtflint                      | tflintを別途インストール                      | v1.0.0で同梱を廃止       |

一番多く引っかかるのは`run-all`です。v1.1.6では「Terragrunt no longer forwards unknown commands by default」と表示されて止まります。`--terragrunt-`接頭辞の旧フラグはTerragruntが解釈せずOpenTofuへそのまま渡すため、エラー文が「flag provided but not defined: -terragrunt-non-interactive」とOpenTofu側の表現になり、原因に気づきにくくなります。ルートの設定ファイルは、名前を`root.hcl`へ変え、子の`find_in_parent_folders()`に引数を足すまでが1セットです。tflintをhookで呼んでいる場合は、ランナーへのtflint導入も必要になります（[TFLintの導入と設定](/tech/details/3393/)）。

## workspace・Atlantis・HCP Terraformとの使い分けと採用しない条件

| 方式                  | 環境の分け方           | stateの分離          | 解決する問題          |
| ------------------- | ---------------- | ----------------- | --------------- |
| Terraform単体         | ディレクトリをコピー       | ディレクトリごと          | ―               |
| terraform workspace | 同一コード＋workspace名 | 同一backend内で分離     | 同じ構成の複製         |
| Terragrunt          | ディレクトリ＋共通設定の継承   | keyの設定によりユニット別に分離 | 設定重複と実行順        |
| Atlantis            | リポジトリ内のプロジェクト    | 各プロジェクトの設定に従う     | PR上でのplan・apply |
| HCP Terraform       | workspace（SaaS）  | SaaS側で管理          | 実行基盤・権限・履歴      |

Atlantisや[HCP Terraform](/tech/details/3340/)は「どこで誰がapplyするか」を扱う道具で、Terragruntは「何をどの順で実行するか」を扱います。役割が重ならないので併用できます。Atlantisの公式ドキュメントにも、カスタムworkflowから`terragrunt`を呼ぶ設定例が載っています（[AtlantisでTerraformをPR運用する構成と権限設計](/tech/details/16549/)）。実際に比較対象になるのはworkspaceです。workspaceは全環境が同じコードを共有するので、prodだけモジュールの版を先に上げる、といった差分を持たせにくくなります。判断基準は[terraform workspaceの使い方と環境分離の判断基準](/tech/details/16529/)で比較しています。

次の条件に当てはまるなら、Terragruntは入れません。環境が1つで、モジュールが数個しかない場合。チームがTerraformのモジュール設計にまだ慣れていない場合。これらに当てはまるときは、Terragrunt固有のHCL関数、`.terragrunt-cache`、依存グラフといった仕組みを調べる手間の方が、重複を減らす効果より大きくなります。導入するのは、dev・stg・prodのように環境が増え、同じbackend設定を複数箇所で変更する作業が繰り返され、設定漏れの確認が負担になった段階が目安です。

## 運用とCIで詰まりやすい箇所

- **キャッシュの肥大**：ユニットごとに`.terragrunt-cache`へモジュールとproviderが展開されます。v1.1.0からはContent Addressable Store（CAS）が既定で有効になり、同じソースのダウンロードは重複排除されます（無効化は`--no-cas`）。OpenTofu 1.10以降ではproviderの共有キャッシュが既定で有効です。Terraformでは`--provider-cache`（`TG_PROVIDER_CACHE`）でTerragruntのProvider Cache Serverを有効にできます
- **シンボリックリンク経由のパス**：macOSの`/tmp`（実体は`/private/tmp`）の下で実行したところ、`dag graph`の依存先が実パスで表示されました。依存関係が一致せず、新規環境の`run --all -- apply`でappがnetworkより先に走って失敗しました。`/private/tmp`で実行し直すと正しい順に完了しています。CIのワークスペースがリンク経由なら実パスで実行してください
- **CIの非対話実行**：`--non-interactive`（`TG_NON_INTERACTIVE=true`）を付けないと、`run --all`の確認プロンプトで止まります。plan結果をPRに残す設計は[TerraformのCI導入ガイド](/tech/details/6528/)と同じ考え方で組めます
- **依存先に追加したoutput**：`dependency`は依存先のstateから`output -json`で値を読みます。依存先に既存のoutputがある場合、既定のno\_mergeでは追加したoutputをmockで補完せず、未適用の属性への参照がエラーになります。依存先をapplyしてstateのoutputを更新してください。適用前のplanでmockに補わせたい場合は`mock_outputs_merge_strategy_with_state = "shallow"`を指定します

```
# .terragrunt-cache をまとめて削除する
find . -type d -name ".terragrunt-cache" -prune -exec rm -rf {} +
```

ディスクを圧迫したときや、モジュールの差し替えが反映されないときに実行します。この記事のS3構成ではstateはキャッシュ外に保存されます。ただし、ローカルbackendのstateや保存済みplanがキャッシュ内にある場合は一緒に消えるため、削除前に保存場所を確認してください。

## よくある質問

### Terragruntとは何ですか？

Gruntworkが開発するオープンソース（MIT）のツールで、TerraformやOpenTofuのコードを複数環境・複数ディレクトリに展開するときの設定の重複と実行順を管理します。2026年10月時点の安定版はv1.1.6です。

### TerraformとTerragruntの違いは何ですか？

Terraformはインフラの差分計算とAPI呼び出しを担う本体で、Terragruntはその実行を束ねるラッパーです。Terraform単体でも設定は再利用できますが、環境別のルートモジュールではbackendやproviderの設定が重複しがちです。Terragruntでは`root.hcl`に一度書けば各ユニットが継承し、ユニット間の値の受け渡し（`dependency`）と依存順の一括実行も担います。

### Terragruntはどうやってインストールしますか？

macOS・Linuxは`brew install terragrunt`、Windowsは`choco install terragrunt`が手軽です。公式のインストールスクリプトやGitHub releasesのバイナリも使えます。導入後は`terragrunt --version`で版を確認し、CIでは版を固定します。

### root.hclとterragrunt.hclはどう使い分けますか？

`terragrunt.hcl`は各ユニットのディレクトリに置く設定で、そのディレクトリが実行単位であることを示します。`root.hcl`は全ユニットに共通する設定を置く親ファイルで、ユニット側から`find_in_parent_folders("root.hcl")`で読み込みます。以前はルートにも`terragrunt.hcl`を置くのが定番でしたが、ユニットと区別できず`run --all`の対象判定が分かりにくくなるため、現在は非推奨です。

### run-allが動かないときはどうすればよいですか？

v1.xでは`run-all`が廃止されており、`terragrunt run --all -- plan`のように`run`コマンドへ`--all`を付け、OpenTofu／Terraformへ渡すコマンドを`--`の後に書きます。`--terragrunt-`で始まる旧フラグも接頭辞を外した名前に変わっているので、スクリプト全体を置き換えてください。

## 関連記事

- [OpenTofuとは？Terraformとのライセンス・機能差と移行判断を実装視点で解説](/tech/details/15299/)
- [terraform workspaceの使い方と環境分離の判断基準｜分割方式の比較](/tech/details/16529/)
- [AtlantisでTerraformをPR運用する構成と権限設計｜採用条件を解説](/tech/details/16549/)
- [Terraform stateとは？tfstateの構造とS3バックエンド・移動削除の安全手順](/tech/details/16525/)
- [TerraformのCI導入ガイド｜fmt・validate・planを自動化するパイプライン設計とツールの選び方](/tech/details/6528/)

---

出典: [Terragruntとは？v1.1の使い方｜root.hcl・run –all・filterの実際の挙動](<https://www.issoh.co.jp/tech/details/12477/>)（株式会社一創）
