1. 概要
- DRY化とは何か(Don’t Repeat Yourself)
- Terraform Workspacesによる環境管理の仕組みと限界
- Terragruntによる設定の共通化アプローチ
- どちらを選ぶべきか判断基準
TerraformでDRY(Don’t Repeat Yourself)なコードを書く方法として、Terraform Workspacesと、サードパーティツールのTerragruntがあります。どちらも「同じTerraformコードで複数環境を管理する」という目的ですが、アプローチが根本的に異なります。
DRY化とは: プログラミングの原則で、同じコードや設定を繰り返し書かないことを指します。Terraformでは「dev/stg/prdで同じリソース構成を、環境ごとに設定値だけ変えて管理する」場面でDRY化が求められます。
2. Terraform Workspacesとは
# Workspaceの作成と切り替え
terraform workspace new dev
terraform workspace new stg
terraform workspace new prd
terraform workspace select prd
# 現在のWorkspaceを確認
terraform workspace show
# → prd
# Workspaceを使ったコード例
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-company-tfstate"
key = "app/terraform.tfstate" # Workspaceごとに自動でenv:/dev/等が付く
region = "ap-northeast-1"
}
}
provider "aws" {
region = "ap-northeast-1"
}
locals {
env_config = {
dev = {
instance_type = "t3.micro"
min_size = 1
max_size = 2
}
stg = {
instance_type = "t3.small"
min_size = 1
max_size = 3
}
prd = {
instance_type = "t3.medium"
min_size = 2
max_size = 10
}
}
config = local.env_config[terraform.workspace]
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = local.config.instance_type
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${terraform.workspace}-web"
Environment = terraform.workspace
ManagedBy = "terraform"
}
}
Workspacesの限界:
- 同一バックエンド内に全環境のStateが混在する(誤操作のリスク)
terraform.workspaceを使った条件分岐が増え、コードが複雑になる- AWSアカウントを環境ごとに分けたい場合に対応しにくい
3. Terragruntとは
TerragruntはTerraformのラッパーCLIです。terragrunt.hclという設定ファイルを使って、共通設定をDRYに管理します。
# ディレクトリ構成例
infra/
├── terragrunt.hcl ← 共通設定(backendのbucket名等)
├── dev/
│ ├── terragrunt.hcl ← dev固有の変数
│ └── vpc/
│ └── terragrunt.hcl
├── stg/
│ └── terragrunt.hcl
└── prd/
└── terragrunt.hcl
# infra/terragrunt.hcl(ルート共通設定)
remote_state {
backend = "s3"
generate = {
path = "backend.tf"
if_exists = "overwrite"
}
config = {
bucket = "my-company-tfstate"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
generate "provider" {
path = "provider.tf"
if_exists = "overwrite"
contents = <<EOF
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
EOF
}
# infra/prd/terragrunt.hcl(prd固有設定)
include "root" {
path = find_in_parent_folders()
}
inputs = {
environment = "prd"
instance_type = "t3.medium"
min_size = 2
max_size = 10
}
# Terragrunt コマンド
terragrunt plan # 単一モジュールのplan
terragrunt run-all plan # 全モジュールのplan
terragrunt run-all apply # 全モジュールのapply
4. 比較まとめ
| 比較軸 | Terraform Workspaces | Terragrunt |
|---|---|---|
| 追加ツール | 不要(Terraform標準) | Terragrunt CLIのインストールが必要 |
| 学習コスト | 低 | 中(terragrunt.hcl の書き方) |
| DRY化の程度 | 中(条件分岐で管理) | 高(共通設定を完全に分離) |
| 複数AWSアカウント対応 | 難 | 容易(assume_roleをrootで定義) |
| 複数モジュール一括実行 | 不可 | run-allで可能 |
| Terraform本体との追従 | — | Terragruntのバージョン対応待ちになることあり |
5. どちらを選ぶか
Workspacesで十分なケース:
- 環境数が少ない(dev/prd の2環境)
- AWSアカウントを環境で分けていない
- Terragruntの学習・導入コストをかけたくない
Terragruntが有効なケース:
- AWSアカウントを環境ごとに分けており、assume_roleを切り替えたい
- 環境が多く(dev/stg/prd/sandbox等)、共通バックエンド設定の繰り返しが辛い
- 複数のTerraformモジュールを依存関係順に一括applyしたい
6. 関連記事
- workspace — 同一コードで複数環境を管理する(と落とし穴) — Workspacesの詳細
- 環境分離のパターン比較 — workspace vs ディレクトリ戦略
- Terraform CI/CDのブランチ戦略 — 環境ごとのapply設計
- backend — stateファイルの保存場所を設定 — S3バックエンド設定
- モノレポ vs マルチリポ — リポジトリ設計 — リポジトリ構成
- Terraformのディレクトリ構成 ベストプラクティス — 基本構成
7. まとめ
- DRY化とは「同じ設定を繰り返し書かない」原則。Terraformでは環境ごとの設定差分をどう管理するかがポイント
- Workspacesは同一コードで複数環境を管理するTerraform標準機能。シンプルだが複数AWSアカウントへの対応が難しい
- Terragruntはラッパーツールで、backendやprovider設定を完全にDRY化できる。複数アカウント・多数環境に強い
- 小規模チームはWorkspaces、大規模・複数アカウントはTerragruntを検討する
対象バージョン: Terraform >= 1.9 / Terragrunt >= 0.55 公式ドキュメント: https://terragrunt.gruntwork.io/