IaC(Infrastructure as Code)の基本
IaC(Infrastructure as Code)は、サーバーやネットワークなどのインフラ構成を、GUIやCLIの手作業ではなくコードで定義・管理する手法を指す。
IaCではこれらをすべてコードに落とし込むことで、Gitによるバージョン管理、プルリクエストでのレビュー、CI/CDによる自動適用が可能になる。
宣言的アプローチと命令的アプローチ
IaCツールには「宣言的」と「命令的」の2つのアプローチがある。
| 項目 | 宣言的 | 命令的 |
|---|---|---|
| 記述内容 | 「あるべき状態」を定義 | 「手順」を記述 |
| 代表ツール | Terraform, CloudFormation | Ansible, シェルスクリプト |
| 冪等性 | ツールが担保 | 自分で担保する必要あり |
| 状態管理 | ツールが現在の状態を追跡 | 基本的に追跡しない |
Terraformを例にすると、「EC2インスタンスが1台、t3.microで、このサブネットに存在する」と書く。Terraformは現在の状態と比較して、差分だけを適用する。すでに存在すれば何もしない。これが「宣言的」の意味であり、何度実行しても同じ結果になる冪等性が自然に得られる。
一方Ansibleは「このパッケージをインストールせよ」「このファイルを配置せよ」と手順を並べる。モジュール単位では冪等性があるが、全体の設計は書く側の責任になる。
IaCには3つのレイヤーがある
IaCを「Terraform = IaC」と理解してしまうケースは多いが、実際にはIaCがカバーする範囲はもっと広い。大きく3つのレイヤーに分かれ、それぞれ担当するツールが異なる。
インフラ層
VPC、サブネット、セキュリティグループ、EC2、RDS、ロードバランサーなど、クラウド上の「箱」にあたる部分。Terraformの主戦場はここだ。
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
tags = {
Name = "web-server"
}
}
この例では、EC2インスタンスを1台、t3.microで作成する。terraform applyを実行すれば、AWSのAPIが叩かれて実際にインスタンスが起動する。
OS・ミドルウェア層
EC2が立ち上がっても、中身は素のAMIのままだ。Nginxのインストール、設定ファイルの配置、ユーザーの作成といったOS内部の構成は、Ansibleなどが担当する。
- name: Install and start Nginx
hosts: web_servers
tasks:
- name: Install Nginx
apt:
name: nginx
state: present
- name: Start Nginx
service:
name: nginx
state: started
enabled: true
Terraformでもprovisioner機能でシェルスクリプトを流すことは技術的には可能だが、公式ドキュメント自体が「provisionerは最後の手段」と明記しており、推奨されない。インフラ層はTerraform、OS層はAnsibleと分離するのが定石だ。
アプリケーション層
アプリケーションのビルド・デプロイ定義を管理するレイヤー。DockerfileやKubernetesのマニフェスト、Helmチャートがここに該当する。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
spec:
containers:
- name: web
image: myapp:1.2.0
ports:
- containerPort: 80
各レイヤーのツールは独立して動作するが、相互に依存関係がある。Terraformで作ったEKSクラスターに対して、Helmチャートでアプリをデプロイする、という流れが典型的だ。
TerraformとAWS CloudFormationの比較
AWSを使うなら、Terraformの他にAWS純正のCloudFormationという選択肢がある。やっていることは「インフラをコードで定義して適用する」という点で同じだが、設計思想に違いがある。
| 項目 | Terraform | CloudFormation |
|---|---|---|
| 対応クラウド | AWS, Azure, GCP, その他多数 | AWSのみ |
| 記述言語 | HCL(HashiCorp Configuration Language) | JSON / YAML |
| 状態管理 | tfstateファイルを自分で管理 | AWSが管理(不要) |
| 新サービス対応 | プロバイダーの更新を待つ | AWS公式なので即対応が多い |
| 学習コスト | HCLの習得が必要 | JSON/YAMLが書ければすぐ始められる |
| マルチクラウド | 同一言語で複数クラウドを扱える | 不可 |
Terraformの最大の強みはマルチクラウド対応だ。AWSとGCPを組み合わせた構成でも、同じHCLで一貫して管理できる。一方CloudFormationはtfstateの管理が不要で、AWSに閉じるプロジェクトであれば運用負荷が低い。
実務では「AWS専業ならCloudFormation、マルチクラウドや将来的な移行可能性があるならTerraform」という選び方が多い。ただし、近年はTerraformのエコシステムの広さからTerraformを第一選択にするチームが増えている。
ローカル環境で練習する方法
Terraform自体はローカルにインストールして使うCLIツールだ。ただしterraform applyでリソースを作るには、接続先のクラウドアカウントが必要になる。クラウドアカウントなしでも学習を進める方法はいくつかある。
LocalStackでAWSをエミュレートする
LocalStackは、AWSの主要サービスをローカルのDockerコンテナ上でエミュレートするツールだ。無料版(Community Edition)でもS3、Lambda、DynamoDB、SQS、SNSなどが使える。
# LocalStackの起動
docker run --rm -p 4566:4566 localstack/localstack
# Terraformから接続するためのprovider設定
provider "aws" {
access_key = "test"
secret_key = "test"
region = "ap-northeast-1"
endpoints {
s3 = "http://localhost:4566"
dynamodb = "http://localhost:4566"
lambda = "http://localhost:4566"
}
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
}
この設定でterraform applyを実行すると、AWSではなくLocalStackに対してリソースが作られる。料金は一切かからない。
注意点として、LocalStackのエミュレーションは完全ではない。IAMのポリシー評価やVPCのネットワーク挙動など、本物と異なる部分がある。HCLの文法やワークフロー(init → plan → apply → destroy)の学習には十分だが、本番設計の検証には向かない。
Docker Providerで手軽に試す
TerraformにはDocker用のプロバイダーがあり、ローカルのDockerコンテナをTerraformで管理できる。クラウドアカウントが一切不要で、Terraformの基本操作を体験するには最も手軽な方法だ。
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}
resource "docker_image" "nginx" {
name = "nginx:latest"
}
resource "docker_container" "web" {
name = "learn-terraform"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 8080
}
}
terraform applyすると実際にNginxコンテナが起動し、localhost:8080でアクセスできる。terraform destroyで消える。Terraformのライフサイクルを体感するには最適だ。
AWS Free Tierで本物に触る
学習目的であれば、AWSの無料利用枠(Free Tier)を使うのが最終的には一番効率がいい。EC2のt2.micro/t3.microが月750時間、S3が5GBまで無料で使える。
ただし注意点がある。
terraform destroyを忘れるとリソースが残り、課金される- NAT GatewayやElastic IPなど、Free Tier対象外のリソースを知らずに作ると課金される
- AWS Budgetsでアラートを設定しておくこと
HCLの文法とTerraformのワークフローを掴むだけならDocker Providerが最速。AWSリソースの定義を練習したいならLocalStack。実際のAWSの挙動まで確認したいならFree Tier。目的に応じて使い分けるのが効率的だ。