モノレポ vs マルチリポ — Terraformのリポジトリ設計を選ぶ

1. 概要

  • モノレポ(1つのリポジトリで全環境・全サービスを管理)の特徴
  • マルチリポ(環境・サービスごとにリポジトリを分ける)の特徴
  • Terraformリポジトリの設計パターン
  • どちらを選ぶべきかの判断基準

Terraformのリポジトリ設計として「モノレポ」と「マルチリポ」があります。アプリコードとインフラコードをどう配置するかはチームの規模・運用フローに大きく影響します。


2. モノレポ構成の例

infra/(1つのリポジトリ)
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── backend.tf
│   ├── stg/
│   │   └── ...
│   └── prd/
│       └── ...
├── modules/
│   ├── vpc/
│   ├── ec2/
│   └── rds/
└── .github/
    └── workflows/
        └── terraform.yml

モノレポのメリット:

  • 全環境の変更を1つのPRで見られる
  • モジュールと環境コードを同じリポジトリで管理できる(依存関係が明確)
  • CI/CDのワークフローが1箇所にまとまる

モノレポのデメリット:

  • リポジトリが巨大になると変更検知・CI実行が遅くなる
  • アクセス制御がリポジトリ単位のため、細かい権限分けが難しい

3. マルチリポ構成の例

infra-vpc/ リポジトリ
├── main.tf
└── .github/workflows/terraform.yml

infra-ec2/ リポジトリ
├── main.tf
└── .github/workflows/terraform.yml

infra-rds/ リポジトリ
├── main.tf
└── .github/workflows/terraform.yml

terraform-modules/ リポジトリ(モジュールのみ)
├── vpc/
├── ec2/
└── rds/

マルチリポのメリット:

  • リポジトリ単位で細かいアクセス制御ができる
  • 各サービスチームがそれぞれのリポジトリを独立して管理できる

マルチリポのデメリット:

  • モジュールのバージョン管理が複雑(各リポジトリでバージョンを指定)
  • CI/CDのワークフローが各リポジトリに分散する

4. Terraformコードのサンプル(モノレポ・environments/dev/)

# environments/dev/main.tf
terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket         = "my-company-tfstate-dev"
    key            = "app/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    dynamodb_table = "terraform-lock"
  }
}

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

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

# モジュール参照(modules/ec2/)
module "ec2" {
  source = "../../modules/ec2"

  environment   = var.environment
  instance_type = "t3.micro"
}

5. CI/CDでの変更検知(モノレポの場合)

# .github/workflows/terraform.yml
on:
  pull_request:
    paths:
      - 'environments/**'
      - 'modules/**'

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      dev-changed: ${{ steps.changes.outputs.dev }}
      stg-changed: ${{ steps.changes.outputs.stg }}
      prd-changed: ${{ steps.changes.outputs.prd }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: changes
        with:
          filters: |
            dev:
              - 'environments/dev/**'
              - 'modules/**'
            stg:
              - 'environments/stg/**'
              - 'modules/**'
            prd:
              - 'environments/prd/**'
              - 'modules/**'

  plan-dev:
    needs: detect-changes
    if: needs.detect-changes.outputs.dev-changed == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "~> 1.9"
      - name: Plan dev
        run: terraform plan
        working-directory: environments/dev

6. 選択の判断基準

状況推奨
小規模チーム(5人以下)・全員がインフラを触るモノレポ
サービスチームがインフラも持つ自律型組織マルチリポ
中央インフラチームが全環境を管理モノレポ
各サービスのアクセス制御を厳密にしたいマルチリポ

7. 関連記事


8. まとめ

  • モノレポは全環境をひとつのリポジトリで管理。小規模〜中規模チームに向いている
  • マルチリポはサービスごとにリポジトリを分ける。細かい権限分けが必要な大規模組織向け
  • モノレポではpathsフィルターで変更があった環境のみCIを実行する工夫が重要
  • 新規プロジェクトはモノレポから始めて、チームが大きくなったらマルチリポへ分割するのが現実的

対象バージョン: Terraform >= 1.9 / GitHub Actions (2024) 公式ドキュメント: https://developer.hashicorp.com/terraform/language/modules/sources