Terraform構成プラクティス:現場で役立つファイル設計と分割戦略 ver2
ver1はこちらから
Terraform Projectでモジュールをどのように整理する?
小規模なProjectであれば、分割せずルートディレクトリに必要なリソースファイルを配置すればいいが、大規模となると、そのようにはいかない。
そこで、モジュールを利用することでDRY原則に従って管理することができます。
モジュールは特定の目的のために作られたTerraform設定ファイルの集まりで、例えば「VPC作成」「DB作成」などの単位で再利用可能です。
これにより、他のプロジェクトにも簡単に組み込めるようになります。
Terraformプロジェクトのルートディレクトリには、リソースの定義だけでなくモジュールブロックも含まれる設定ファイルがあります。
モジュールブロックでは、モジュールの**ソース(source)**を指定し、これは以下のような場所から参照できます:
- リモートのGitリポジトリ
- Terraform Registry
- ローカルに作成したモジュール
ローカルパスにあるモジュールを参照する例
module "project_vpc" {
source = "path/to/vpc/module/directory"
# inputs (required input variable in VPC module)
cidr_range = 10.0.0.0/24
}
モジュールの機能について知りたい場合は素晴らしいブログがあります → https://spacelift.io/blog/what-are-terraform-modules-and-how-do-they-work
VPCの例
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "3.19.0"
}
- 既存のTerraformモジュールを使う場合は、必要な設定を追加するだけでOK
- Spaceliftのモジュールレジストリは、管理を効率化し高度な統合も可能。
モジュール追加時に再初期化され、.terraform
にソースが保存される。
.terraform
ディレクトリ内の追加ファイルは、main.tf
で使用したVPCモジュールに対応しているもので、Terraformが内部的に管理する仕組みを示している。
必要があればこのモジュールファイルをカスタマイズして適用することで、プロジェクトのステートファイルを通じてVPCを作成・管理できる。
また、モジュールはさらにネスト構造を持つことが可能で、これらのファイルはデフォルトで .gitignore
に設定されているため、リポジトリに含まれることはない。
Terraform構成のベストプラクティス
Terraformの構成はモノレポとポリレポの2つの構成にエンジニアによって使い分けられる
モジュール → モノレポ
環境 → ポリレポ
で管理するケースやその逆もある
具体的には、AWS構成においてネットワークモジュール、EC2モジュール、dev/prod 環境をどのように整理するか、ベストプラクティスに沿った例が示される
リポジトリ: terraform-module-network/
└── main.tf # VPCなどネットワーク構成
リポジトリ: terraform-module-ec2/
└── main.tf # EC2構成
リポジトリ: terraform-env-dev/
└── main.tf # module "network" "ec2" を git source で参照
リポジトリ: terraform-env-prod/
└── main.tf # module "network" "ec2" を git source で参照
- 特徴: モジュールと環境ごとにリポジトリを分割。
- 利点: チーム単位での責任分担がしやすく、大規模な組織に適している。
terraform-infra/
├── modules/
│ ├── network/
│ │ └── main.tf
│ └── ec2/
│ └── main.tf
├── envs/
│ ├── dev/
│ │ └── main.tf # module "network", "ec2" を呼び出す
│ └── prod/
│ └── main.tf # module "network", "ec2" を呼び出す
└── README.md
- 特徴: 1リポジトリで完結。moduleもenvもこの中にある。
- 利点: 管理が一元化されて楽。小〜中規模に最適。
Terraform構成のベストプラクティス例
こちらよりそのまま抜粋させていただきます
モノレポ
Moduleと各環境が1つのリポジトリにまとまっています
monorepo tree .
.
├── environments
│ ├── dev
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── provider.tf
│ │ ├── terraform.tf
│ │ ├── terraform.tfvars
│ │ └── variables.tf
│ └── prod
│ ├── main.tf
│ ├── outputs.tf
│ ├── provider.tf
│ ├── terraform.tf
│ ├── terraform.tfvars
│ └── variables.tf
└── modules
├── ec2
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── network
├── main.tf
├── outputs.tf
└── variables.tf
ポリレポ
各ディレクトリ単位でリポジトリが分かれています
Dev repository
dev tree .
.
├── main.tf
├── outputs.tf
├── provider.tf
├── terraform.tf
├── terraform.tfvars
└── variables.tf
Prod repository:
prod tree .
.
├── main.tf
├── outputs.tf
├── provider.tf
├── terraform.tf
├── terraform.tfvars
└── variables.tf
EC2 module:
ec2 tree .
.
├── main.tf
├── outputs.tf
└── variables.tf
Network module:
`network tree .
.
├── main.tf
├── outputs.tf
└── variables.tf`
複雑なIaC環境の管理における課題とその対処法
全体として、モジュール化、セキュリティの自動化、標準化、環境・リージョン対応、そしてSpaceliftによる効率化が、大規模IaC管理における鍵となります。
-
インフラが複雑になるほど、モジュール分割が有効
複数のコンポーネントやネットワーク要件が絡む設計には、IaCをモジュール単位に分割して管理するのが効果的。 -
セキュリティ要件の増大には「Policy as Code」
セキュリティガードレールを自動で適用するために、Terraformと連携可能なポリシーコードの導入が推奨される。 -
標準化と再利用性の確保
組織共通のモジュールをCOE(Center of Excellence)チームが管理・配布し、現場チームはそれを活用して開発を迅速化。 -
マルチ環境・リージョン対応
本番のコピー環境や一時的な環境を管理し、リージョンごとにカスタムサービスを展開可能に。 -
Spaceliftの活用による自動化と一元管理
- GitベースのスタックでIaC運用をCI/CD化
- Contextsによる共通変数の管理
- モジュールレジストリと連携した再利用性の高いインフラ管理を実現
Terraformプロジェクト構成に関する
-
Terraformの構成設計は、IaCの成熟段階で重要になる
インフラが拡張されるにつれて、ファイル構成の最適化が保守性や可読性に大きく影響する。 -
複雑化に備えて、サービス単位やコンポーネント単位でファイルを整理するのが有効
プロジェクトの成長に伴い、構成管理の工夫が必要になる。 -
Terraformのライセンス変更にも注意が必要
バージョン1.5.x以前はOSSだが、それ以降はBUSLライセンスへ。
代替として、Terraform 1.5.6からフォークされたOpenTofuがOSSとして利用可能。
Discussion