個人的備忘録：Terraform のコード分割について悩みがつきなかったので、一度体系的に整理し、それぞれの手法を比較してみた

## はじめに
Terraform を用いたインフラ管理では、**コードの構成方法がプロジェクトの運用や管理のしやすさに大きく影響** します。  

:::note info
**特に、**チームでの開発や長期的なメンテナンスを考慮すると、適切な分割方法を選択することが重要** になります。**
:::

本記事では、**Terraform のコードをどのように分割できるか、それぞれのアプローチのメリット・デメリット** を解説します。  

## 書こうと思ったきっかけ
Terraform を使ったインフラ管理を進める中で、**「どのようにコードを分割すればよいか」** という問題に直面することが多くありました。  
例えば、  
- **環境ごとに管理するべきか**  
- **機能単位で分けるべきか**  
- **モジュール化すべきか**  

など、選択肢が多く、それぞれに**利点と課題が存在** します。  

:::note warn
***また、**チーム開発や CI/CD の導入を考えると、より適切な分割方法を選ぶ必要がある** と感じました。***
:::

本記事では、こうした経験をもとに、**Terraform の分割パターンについて整理し、それぞれの特徴を比較** します。

## 1. 大分類ごとに分ける
### 概要
ネットワーク・コンピュート（ECS, RDS, ALB）・ストレージ（S3, CloudFront）・IAM を大きな機能単位で分割する方法。

```
terraform/
│── backend.tf             # Terraform のバックエンド設定（State 管理用）
│── variables.tf           # 変数の定義
│── providers.tf           # AWS プロバイダーの設定
│── terraform.tfvars       # 環境ごとの変数（オプション）
│
├── networking/            # VPC・サブネット・ルートテーブル
│   ├── main.tf
│   ├── variables.tf
│
├── compute/               # ECS・RDS・ALB
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│
├── storage/               # S3・CloudFront
│   ├── main.tf
│   ├── variables.tf
│
├── security/              # IAM・セキュリティグループ
│   ├── main.tf
│   ├── variables.tf
```
### メリット
✅ シンプルで見やすい  
✅ 機能ごとに独立して管理できる  

### デメリット
⚠ 環境ごとに変更を加えづらい（開発・本番の切り替えが難しい）

## 2. 環境ごとに完全分離
### 概要
開発環境（dev）と本番環境（prod）を完全に分離し、それぞれ独立した Terraform コードを持つ。

```
terraform/
├── dev/                   # 開発環境
│   ├── backend.tf
│   ├── main.tf
│   ├── variables.tf
│   ├── networking.tf
│   ├── compute.tf
│   ├── storage.tf
│   ├── security.tf
│
├── prod/                  # 本番環境
│   ├── backend.tf
│   ├── main.tf
│   ├── variables.tf
│   ├── networking.tf
│   ├── compute.tf
│   ├── storage.tf
│   ├── security.tf
```
### メリット
✅ 開発環境と本番環境の管理が明確になる  
✅ テスト用の環境を自由にデプロイできる  

### デメリット
⚠ コードの重複が発生する（開発・本番で同じ設定を書く必要がある）  
⚠ Terraform の State 管理がやや複雑になる  

## 3. モジュール化を活用
### 概要
共通のリソースを Terraform モジュールとして作成し、異なる環境（開発・本番）で使いまわす。

```
terraform/
│── backend.tf
│── variables.tf
│── providers.tf
│── terraform.tfvars
│
├── modules/               # 共通モジュール
│   ├── networking/        # VPC・サブネット
│   ├── compute/           # ECS・RDS
│   ├── storage/           # S3・CloudFront
│   ├── security/          # IAM・セキュリティグループ
│
├── environments/          # 環境ごとの適用
│   ├── dev/
│   │   ├── main.tf        # モジュールを利用
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │
│   ├── prod/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── outputs.tf
```
### メリット
✅ コードの重複を減らせる（共通モジュールを使いまわせる）  
✅ 開発環境・本番環境を簡単に切り替え可能  

### デメリット
⚠ モジュールの作成・管理に手間がかかる  
⚠ 初心者には少し難しい  

## 4. CI/CD 向けに分離
### 概要
Terraform を GitHub Actions や GitLab CI/CD で自動化するために、`terraform apply` の対象を分ける。

```
terraform/
├── infra/                 # インフラ（手動 or 定期実行）
│   ├── main.tf
│   ├── networking.tf
│   ├── compute.tf
│   ├── storage.tf
│   ├── security.tf
│
├── apps/                  # アプリ（CI/CD で自動デプロイ）
│   ├── backend/
│   │   ├── main.tf        # ECSタスクのデプロイ
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │
│   ├── frontend/
│   │   ├── main.tf        # CloudFront のデプロイ
│   │   ├── variables.tf
│   │   ├── outputs.tf
│
├── .github/               # GitHub Actions
│   ├── workflows/
│   │   ├── deploy-infra.yml    # Terraform でインフラ構築
│   │   ├── deploy-backend.yml  # バックエンドアプリのデプロイ
│   │   ├── deploy-frontend.yml # フロントエンドアプリのデプロイ
```
### メリット
✅ Terraform の `terraform apply` を環境ごとに自動実行できる  
✅ アプリの更新を CI/CD でデプロイ可能  

### デメリット
⚠ CI/CD パイプラインの設定が必要  
⚠ Terraform の適用タイミングを考慮する必要がある  

## 5. Terraform Cloud / Remote State の活用
### 概要
Terraform Cloud や S3 で State を管理し、環境ごとに異なる Terraform ワークスペースを使う。

```hcl
terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "my-org"
    workspaces {
      name = "my-project-dev"
    }
  }
}
```
### メリット
✅ Terraform Cloud で環境を分離できる  
✅ State 管理が簡単になる  

### デメリット
⚠ Terraform Cloud の設定が必要  
⚠ Remote State のアクセス管理が必要  

## どの分割方法を選ぶべきか？
| 分割方法 | メリット | デメリット |
|---|---|---|
| 大分類ごと | シンプルで見やすい | 環境ごとに変更しづらい |
| 環境ごとに分離 | 開発・本番の管理がしやすい | コードの重複が増える |
| モジュール化 | コードの再利用が可能 | 学習コストが高い |
| CI/CD 向け | 自動化しやすい | パイプラインの管理が必要 |
| Terraform Cloud | State 管理が楽 | セットアップが必要 |

## まとめ
Terraform のコード分割は、**プロジェクトの規模や運用方針に大きく影響を与える重要な設計要素** です。  

本記事では、以下の **5 つの分割方法** を紹介しました。

### **1. 大分類ごとに分割**
- シンプルで見やすく、機能単位で管理しやすい  
- 環境ごとの変更が難しい  

### **2. 環境ごとに完全分離**
- 開発・本番の管理が明確になる  
- コードの重複が発生しやすい  

### **3. モジュール化を活用**
- コードの再利用が可能で、環境ごとの管理がしやすい  
- モジュールの作成・管理に手間がかかる  

### **4. CI/CD 向けに分離**
- Terraform の適用を CI/CD に組み込みやすい  
- インフラとアプリを分離できる  
- CI/CD パイプラインの管理が必要  

### **5. Terraform Cloud / Remote State の活用**
- State 管理が簡単になり、環境を明確に分けられる  
- Terraform Cloud のセットアップやアクセス管理が必要  

:::note warn
それぞれの方法には**メリット・デメリット** があり、**プロジェクトの要件に応じて適切な分割方法を選ぶ** ことが重要です。
:::

**チーム開発や運用のしやすさを考慮しながら、自分たちの環境に最適な構成を検討していきたいと思いました！**