1. 概要
- シングルモジュール構成(小規模プロジェクト向け)
- 環境別ディレクトリ構成(中規模向け)
- モジュール分割構成(大規模向け)
- ファイルの命名規則と役割分担
.gitignoreで管理すべきファイル
Terraformのディレクトリ構成に「唯一の正解」はありませんが、プロジェクトの規模や運用スタイルに応じたベストプラクティスが存在します。この記事では実務でよく使われる3つのパターンを解説します。
2. 基本ファイルの役割
どの構成でも共通する基本ファイルを理解しておきましょう。
| ファイル名 | 役割 | 必須か |
|---|---|---|
main.tf | リソース定義のメインファイル | ✅ |
variables.tf | variableブロックの定義 | 推奨 |
outputs.tf | outputブロックの定義 | 推奨 |
providers.tf | terraform・providerブロック | ✅ |
locals.tf | localsブロック(大きい場合) | 任意 |
terraform.tfvars | 変数のデフォルト値 | 任意 |
*.auto.tfvars | 自動読み込まれるtfvars | 任意 |
3. パターン1: シングルモジュール構成(小規模)
個人プロジェクトや数十リソース程度の小規模な構成に適しています。
project/
├── main.tf # リソース定義(EC2, S3, RDSなど)
├── variables.tf # 変数定義
├── outputs.tf # アウトプット定義
├── providers.tf # providerとterraformブロック
├── locals.tf # ローカル値定義
├── terraform.tfvars # 変数の値(開発環境デフォルト)
└── .gitignore
providers.tf の例:
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "myapp-terraform-state"
key = "terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "myapp-terraform-locks"
encrypt = true
}
}
provider "aws" {
region = "ap-northeast-1"
}
variables.tf の例:
variable "environment" {
description = "環境名(dev/stg/prd)"
type = string
default = "dev"
}
variable "project_name" {
description = "プロジェクト名"
type = string
}
terraform.tfvars の例:
environment = "dev"
project_name = "myapp"
4. パターン2: 環境別ディレクトリ構成(中規模)
dev / stg / prd のようにディレクトリを分けるパターンです。環境間の設定が大きく異なる場合に適しています。
project/
├── modules/
│ └── ec2/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf # dev環境のリソース定義
│ │ ├── providers.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ ├── stg/
│ │ ├── main.tf
│ │ ├── providers.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ └── prd/
│ ├── main.tf
│ ├── providers.tf
│ ├── variables.tf
│ └── terraform.tfvars
└── .gitignore
environments/prd/terraform.tfvars の例:
environment = "prd"
project_name = "myapp"
instance_type = "t3.medium"
コマンド実行時は環境ディレクトリに移動:
cd environments/dev
terraform init
terraform plan -var-file=terraform.tfvars
terraform apply -var-file=terraform.tfvars
5. パターン3: モジュール分割構成(大規模)
複数チームで管理する大規模なプロジェクトでは、機能ごとにモジュールを分けます。
project/
├── modules/
│ ├── networking/ # VPC, subnet, security group
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── compute/ # EC2, Auto Scaling
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── database/ # RDS, ElastiCache
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── storage/ # S3, CloudFront
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ └── main.tf # moduleを呼び出すだけ
│ └── prd/
│ └── main.tf
└── .gitignore
environments/prd/main.tf の例:
module "networking" {
source = "../../modules/networking"
environment = "prd"
vpc_cidr = "10.1.0.0/16"
}
module "compute" {
source = "../../modules/compute"
environment = "prd"
subnet_ids = module.networking.private_subnet_ids
instance_type = "t3.medium"
}
6. .gitignoreで管理すべきファイル
# Terraformが生成するファイル(コミット不要)
.terraform/
*.tfstate
*.tfstate.backup
.terraform.tfstate.lock.info
crash.log
crash.*.log
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# 秘密情報(絶対にコミットしない)
*.pem
*.key
secrets.tfvars
*secrets*.tfvars
# ロックファイルはコミットする(プロバイダーバージョン固定のため)
# !.terraform.lock.hcl ← 削除しないこと
⚠️ 重要:
.terraform.lock.hclはコミットしてください(.gitignoreで除外しないこと)。プロバイダーバージョンをチームで統一するために必要です。
7. 命名規則のベストプラクティス
# リソース名: <role>または<function>を使う(env/projectはtagsで管理)
resource "aws_instance" "web" { ... }
resource "aws_instance" "app" { ... }
resource "aws_s3_bucket" "assets" { ... }
# 変数名: スネークケース(小文字とアンダースコア)
variable "instance_type" { ... }
variable "vpc_cidr_block" { ... }
# ローカル値: スネークケース
locals {
common_tags = { ... }
az_list = [ ... ]
}
8. 関連記事
- moduleブロックの使い方 — モジュール分割の具体的な実装
- backendの設定方法 — S3+DynamoDBでのState管理
- variable(入力変数)の使い方 — variablesとtfvarsの詳細
- tfvarsファイルの使い方 — 環境別変数管理の詳細
- Terraform命名規則 — リソース名・変数名の統一
- 環境分離パターン比較 — workspace vs ディレクトリ
9. まとめ
- 小規模: フラットなシングルモジュール構成(main.tf, variables.tf, outputs.tf, providers.tf)
- 中規模:
environments/dev/environments/prdのディレクトリ分割 - 大規模:
modules/networking/modules/computeなどの機能別モジュール分割 - どの構成でも
providers.tfにterraformブロックとproviderブロックをまとめる .terraform.lock.hclはコミット必須。.terraform/はgitignore必須
動作確認バージョン: Terraform >= 1.9 / AWS Provider ~> 5.0 公式ドキュメント: https://developer.hashicorp.com/terraform/language/modules/develop/structure