Terragrunt vs Terraform Workspaces — DRY化の2択を整理する

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 WorkspacesTerragrunt
追加ツール不要(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. 関連記事


7. まとめ

  • DRY化とは「同じ設定を繰り返し書かない」原則。Terraformでは環境ごとの設定差分をどう管理するかがポイント
  • Workspacesは同一コードで複数環境を管理するTerraform標準機能。シンプルだが複数AWSアカウントへの対応が難しい
  • Terragruntはラッパーツールで、backendやprovider設定を完全にDRY化できる。複数アカウント・多数環境に強い
  • 小規模チームはWorkspaces、大規模・複数アカウントはTerragruntを検討する

対象バージョン: Terraform >= 1.9 / Terragrunt >= 0.55 公式ドキュメント: https://terragrunt.gruntwork.io/