環境分離のパターン比較 — workspace vs ディレクトリ vs ブランチ

1. 概要

  • 環境分離の3つのパターン(workspace / ディレクトリ / ブランチ)
  • 各パターンの仕組みとメリット・デメリット
  • どのパターンを選ぶべきか

Terraformで dev/stg/prd などの環境を分離する方法は複数あります。それぞれに向き不向きがあり、誤った選択はチームの生産性や安全性に大きく影響します。この記事では3つのパターンを比較し、どれを選ぶべきかの判断基準を解説します。


2. パターン1: terraform workspace

同一のコードベースから、workspace単位でstateファイルを分離する方法です。

# workspaceの操作
$ terraform workspace new dev
$ terraform workspace new stg
$ terraform workspace new prd
$ terraform workspace select prd
$ terraform apply
terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "my-tfstate"
    key    = "myapp/terraform.tfstate"  # workspaceがprefixとして付く
    region = "ap-northeast-1"
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

locals {
  environment   = terraform.workspace
  is_production = terraform.workspace == "prd"

  instance_type = {
    default = "t3.micro"
    dev     = "t3.micro"
    stg     = "t3.small"
    prd     = "t3.medium"
  }
}

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 = lookup(local.instance_type, local.environment, local.instance_type["default"])

  root_block_device {
    volume_size = local.is_production ? 100 : 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${local.environment}-web"
    Environment = local.environment
    ManagedBy   = "terraform"
  }
}

向いている場面: 個人開発・短期的なブランチテスト・素早い複製 向いていない場面: dev/stg/prd の本番運用・チーム開発・CI/CD環境


3. パターン2: ディレクトリ分離(推奨)

環境ごとにディレクトリを分けて、それぞれに独立した設定を持つ方法です。

project/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │   └── terraform.tfvars   # dev固有の値
│   ├── stg/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │   └── terraform.tfvars
│   └── prd/
│       ├── main.tf
│       ├── variables.tf
│       ├── outputs.tf
│       └── terraform.tfvars
└── modules/
    ├── network/
    └── compute/
# environments/dev/main.tf
terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "my-tfstate"
    key    = "dev/terraform.tfstate"  # 環境ごとに異なるkey
    region = "ap-northeast-1"
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  type    = string
  default = "dev"
}

module "network" {
  source      = "../../modules/network"
  environment = var.environment
  vpc_cidr    = "10.1.0.0/16"  # dev用CIDR
}

module "compute" {
  source        = "../../modules/compute"
  environment   = var.environment
  vpc_id        = module.network.vpc_id
  subnet_ids    = module.network.private_subnet_ids
  instance_type = "t3.micro"
}
# environments/prd/main.tf(prdでは設定が異なる)
module "compute" {
  source        = "../../modules/compute"
  environment   = "prd"
  vpc_id        = module.network.vpc_id
  subnet_ids    = module.network.private_subnet_ids
  instance_type = "t3.medium"
  min_size      = 2
  max_size      = 10
}

向いている場面: dev/stg/prd の本番運用・チーム開発・長期的な環境管理


4. パターン3: ブランチ分離

Gitブランチで環境を分ける方法(main → prd、develop → dev、など)。

main ブランチ   → prd環境にdeploy
develop ブランチ → dev/stg環境にdeploy

向いている場面: 環境ごとにコードが大きく異なる場合・インフラの変更を厳格にレビューしたい場合

向いていない場面: moduleを共通化して一元管理したい場合(ブランチ間のmodule変更同期が困難)


5. パターン比較表

比較workspaceディレクトリ分離ブランチ分離
設定の共有同一ファイルmoduleで共有ブランチごとに独立
環境差異の表現terraform.workspaceで条件分岐ディレクトリの設定ファイルブランチごとのファイル
誤環境へのapplyリスク高(切り替え忘れ)低(ディレクトリで明示)中(ブランチ確認が必要)
CI/CD連携やや難(workspace切り替えが必要)容易(ディレクトリで分岐)容易(ブランチで分岐)
Terraformコミュニティの推奨非推奨(本番用途)✅ 推奨状況による

6. 推奨パターン

ディレクトリ分離 × moduleの組み合わせがTerraformコミュニティで最も推奨されています。

理由は以下の通りです。

  • workspaceは「どのworkspaceにいるか」が一目でわからず、誤ったapplyが起きやすい
  • ブランチ分離はコードの同期が複雑になる
  • ディレクトリ分離はcd environments/prd && terraform applyと明示的で安全

7. 関連記事


8. まとめ

  • workspace: 短期テスト・個人開発向け。本番の環境分離には非推奨
  • ディレクトリ分離: Terraformコミュニティ推奨。moduleと組み合わせてコード共通化
  • ブランチ分離: 環境差異が大きい場合に有効。module共有には不向き
  • 本番運用にはディレクトリ分離 × moduleの組み合わせを選ぶ

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/modules/develop/structure