🏗️
実践的なTerraform構成設計:モジュール化とベストプラクティス
はじめに
Terraformを使い始めたものの、「どのようにファイルを整理すればいいのか」「どこまでモジュール化すべきか」といった疑問を持つ方は多いでしょう。本記事では、実際のプロジェクトで使用されている構成を例に、実践的なTerraform設計パターンを解説します。
対象読者
- Terraformの基本的な書き方は理解している
- より良い構成設計を学びたい
- チーム開発でのTerraform運用を考えている
全体構成の設計思想
ディレクトリ構造
terraform/
├── modules/ # 再利用可能なコンポーネント
│ ├── vpc/
│ ├── subnet/
│ ├── ec2_instance/
│ └── security_group/
└── services/ # 環境別の設定
└── dev/
├── main.tf
├── var_vpc.tf
├── var_ec2.tf
└── var_secg.tf
この構成の3つの核心原則:
- 関心の分離: モジュール(what)と環境設定(how)を分離
- 再利用性: 同じモジュールを複数環境で利用
- 保守性: 変更影響範囲を限定
モジュール設計のベストプラクティス
1. 適切な粒度でのモジュール化
# modules/vpc/main.tf
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = var.name
Environment = var.tags.Environment
Owner = var.tags.Owner
}
}
ポイント:
- 1つのモジュール = 1つの責任
- AWSリソース単位でモジュール化
- 設定値は全て変数化
2. 統一されたファイル構成
各モジュールは以下の3ファイルで構成:
module/
├── main.tf # リソース定義
├── variable.tf # 入力パラメータ
└── output.tf # 出力値
3. 柔軟な設定管理
# services/dev/var_vpc.tf
locals {
vpc_definitions = {
dev-vpc = {
cidr_block = "172.16.0.0/22"
subnets = {
dev-subnet-public-alb-1a = {
cidr_block = "172.16.0.0/25"
availability_zone = "ap-northeast-1a"
}
# ...
}
}
}
}
メリット:
- 設定の一元管理
- 環境間での差分が明確
- 新しい環境追加が容易
実践的な構成パターン
1. for_eachを活用した動的リソース作成
# services/dev/main.tf
module "module_vpcs" {
source = "../../modules/vpc"
for_each = local.vpc_definitions
name = each.key
cidr_block = each.value.cidr_block
tags = local.tags
}
2. モジュール間の依存関係管理
module "module_subnets" {
source = "../../modules/subnet"
for_each = local.vpc_definitions
vpc_id = module.module_vpcs[each.key].output_vpcs.id
subnets = each.value.subnets
tags = local.tags
}
3. 共通設定の外部化
# services/dev/var_common.tf
locals {
tags = {
Environment = "dev"
Owner = "admin"
}
}
セキュリティ設計のパターン
階層化されたセキュリティグループ
locals {
secg_definitions = {
dev-vpc = {
dev-secg-alb-external = {
description = "external ALB"
rules = [
{
type = "ingress"
protocol = "tcp"
from_port = 443
to_port = 443
cidr_blocks = ["0.0.0.0/0"]
}
]
}
dev-secg-ec2-web = {
description = "Web Instance"
rules = [
{
type = "ingress"
source_security_group_key = "dev-secg-alb-external"
protocol = "tcp"
from_port = 80
to_port = 80
}
]
}
}
}
}
設計原則:
- 最小権限の原則
- セキュリティグループ間参照の活用
- 役割別の明確な分離
運用面での考慮事項
1. 状態管理
terraform {
required_version = ">= 1.12.0"
backend "local" {
path = "./terraform.tfstate"
}
}
本番環境では:
- S3 + DynamoDBでリモート状態管理
- 状態ファイルの暗号化
- 状態ロックの実装
2. プロバイダー設定
provider "aws" {
region = "ap-northeast-1"
profile = "dev-profile"
}
3. タグ戦略
locals {
tags_ec2_control = {
Environment = "dev"
Owner = "admin"
AutoStartStop = true # 自動起動停止用
}
}
この構成の利点
1. スケーラビリティ
- 新環境(staging, prod)の追加が容易
- 設定ファイルをコピーして値を変更するだけ
2. 保守性
- 変更影響範囲が限定的
- モジュールの修正が全環境に反映
3. 可読性
- 設定が構造化されている
- 役割ごとにファイルが分離
4. 再利用性
- モジュールが環境に依存しない
- 他プロジェクトでも利用可能
まとめ
良いTerraform構成の要素:
- 適切な抽象化: モジュールと環境設定の分離
- 一貫性: 命名規則とファイル構成の統一
- 柔軟性: 設定の外部化と構造化
- セキュリティ: 最小権限とベストプラクティスの適用
この構成パターンを参考に、プロジェクトの規模や要件に応じてカスタマイズしてください。重要なのは、チーム全体で一貫した設計原則を共有することです。
次のステップ
- CI/CDパイプラインとの統合
- terraform planの自動化
- セキュリティスキャンの導入
- コスト監視の実装
Discussion