一般社団法人 全国個人事業主支援協会

COLUMN コラム

  • Terraformで始めるIaC:マルチクラウド環境の構築自動化

なぜ今Terraformなのか

インフラストラクチャのコード化(IaC)は、もはやクラウドを扱うエンジニアにとって避けて通れないスキルとなっています。特にマルチクラウド環境を運用する企業が増加する中、AWS CloudFormationやAzure Resource Managerといったベンダー固有のツールでは対応しきれない場面が増えてきました。

Terraformは、HashiCorpが開発するオープンソースのIaCツールで、AWS・Azure・GCPはもちろん、Kubernetes、Datadog、PagerDutyなど数千のプロバイダーに対応しています。筆者が実際にマルチクラウド環境の構築を担当した経験から、Terraformを選択する明確な理由と実践的なノウハウをお伝えします。

Terraformの基本アーキテクチャ

Terraformを理解するには、まず宣言的アプローチという概念を押さえる必要があります。「どうやって構築するか」ではなく「どういう状態であるべきか」を記述する点が、従来のシェルスクリプトによるインフラ構築との根本的な違いです。

HCLによるリソース定義

TerraformではHCL(HashiCorp Configuration Language)という独自の設定言語を使います。以下は、AWSでVPCとサブネットを作成する基本的な例です。

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "ap-northeast-1"
}
}

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

resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "production-vpc"
Environment = "production"
}
}

resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "public-subnet-${count.index + 1}"
}
}

ポイントはcountパラメータを使ったリソースの複製です。これにより、冗長構成のサブネットを簡潔に定義できます。

Stateファイルの管理

Terraformはterraform.tfstateというファイルで現在のインフラ状態を管理します。チーム開発ではこのファイルをS3やGCSなどのリモートバックエンドに保存し、State Lockingを有効にすることが必須です。上記の例ではbackend "s3"ブロックでリモートバックエンドを設定しています。

マルチクラウド構成の実践

Terraformの真価は、複数のクラウドプロバイダーを一つのコードベースで管理できる点にあります。実際のプロジェクトでは、以下のようなディレクトリ構成が効果的でした。

infrastructure/
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── compute/
│ └── database/
├── environments/
│ ├── production/
│ │ ├── aws/
│ │ │ └── main.tf
│ │ └── gcp/
│ │ └── main.tf
│ └── staging/
└── shared/
└── dns/

モジュールによる再利用

マルチクラウド環境では、共通のパターンをモジュール化することが重要です。例えば、ネットワーク構成のモジュールを以下のように定義し、各クラウドから呼び出す設計が実用的です。

module "aws_network" {
source = "../../modules/networking"
environment = var.environment
cidr_block = "10.0.0.0/16"
subnet_count = 3
}

output "vpc_id" {
value = module.aws_network.vpc_id
}

モジュールの粒度は「一つのチームが管理する論理的な単位」で分けると、運用時の変更影響範囲が把握しやすくなります。

CI/CDパイプラインへの組み込み

Terraformをチームで安全に運用するには、GitOpsの考え方を取り入れたCI/CDパイプラインが不可欠です。筆者のチームではGitHub Actionsで以下のようなワークフローを構築しました。

name: Terraform Plan
on:
pull_request:
paths: ["infrastructure/**"]
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan -out=tfplan
- run: terraform show -no-color tfplan > plan.txt
- uses: actions/github-script@v7
with:
script: |
const plan = require('fs').readFileSync('plan.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Terraform Plan\n\`\`\`\n${plan}\n\`\`\``
});

PRに対してterraform planの結果を自動コメントする仕組みは、レビュー品質を大幅に向上させます。実際にこの仕組みを導入してから、インフラ変更に起因する本番障害がゼロになりました。

運用で得た教訓

Stateの分割戦略

大規模環境では、一つのStateファイルに全リソースを詰め込むとterraform planの実行時間が数十分に膨れ上がります。サービス単位・レイヤー単位でStateを分割し、terraform_remote_stateデータソースで相互参照する設計が実用的です。

Drift検知の自動化

手動変更によるドリフト(コードと実態の乖離)は、IaC運用における最大の敵です。定期的にterraform planを実行し、差分があればSlackに通知する仕組みを構築することを強く推奨します。筆者のチームでは週次でドリフト検知ジョブを実行しています。

tfstateのバージョニング

S3バックエンドを使う場合、バケットのバージョニングを必ず有効にしてください。State破損時のリカバリが可能になります。また、DynamoDBによるState Lockingも忘れずに設定しましょう。

まとめ

Terraformによるマルチクラウドインフラの管理は、初期学習コストこそかかりますが、長期的な運用効率とインフラの品質を劇的に向上させます。特にモジュール化、リモートバックエンド、CI/CDとの統合という三本柱をしっかり押さえることで、安全かつスケーラブルなインフラ運用が実現できます。まずは小さなプロジェクトから始めて、段階的にカバー範囲を広げていくアプローチをお勧めします。

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア