境界線を極める:Terraform × Ansibleで構築する「不変と可変」のインフラアーキテクチャ
「Terraformで全部できないのか?」という問いに対し、私は迷わず「やるべきではない」と答える。
インフラの世界には「静的なプロビジョニング」と「動的な構成管理」という、明確に異なる二つのレイヤーが存在する。この境界線を曖昧にすることは、運用時の技術的負債を蓄積させる最大の要因だ。
本稿では、世界最高峰の現場で採用されている「Terraformで箱を作り、Ansibleで魂を吹き込む」という、疎結合かつ堅牢なパイプライン設計の極意を伝授する。
—
1. 役割の再定義:なぜその組み合わせなのか
TerraformとAnsibleを混同してはいけない。
- Terraform (The Provisioner): APIを叩き、Cloud上のリソース(VPC, EC2, RDS)を宣言的状態へ導く。「箱」を作ることに特化せよ。
- Ansible (The Configurator): OS内部に入り、ミドルウェアの設定やユーザー管理、デプロイを行う。継続的な「状態維持」に特化せよ。
TerraformでOS内部のパッケージ管理までやろうとすると、実行時間が肥大化し、API制限に抵触し、再実行時の冪等性が崩壊する。「Terraformはインフラを焼き、AnsibleはOSを調律する」。これが黄金律だ。
—
2. 現場を加速させる「神」設定とツール群
生産性を極限まで高めるには、ツールを手に馴染ませる必要がある。
VS Code用必須プラグイン
- HashiCorp Terraform: 言語サーバーの精度が別次元。`terraform validate`を統合し、保存時にフォーマットする設定は必須。
- Ansible (Red Hat): 構文ハイライトだけでなく、Ansible Lintとの連携が強力。
- YAML (Red Hat): `ansible.builtin` などのスキーマ検証に不可欠。
開発を高速化するTips
- Ansible Ad-hocの限界突破: 複雑なPlaybookを叩く前に、`ansible -m setup` で対象ホストのFactをJSONで出し、`jq`で加工して期待値と一致するか確認せよ。これがトラブルシュートを3分で終わらせる鍵だ。
—
3. 実践:TerraformとAnsibleを繋ぐ「動的インベントリ」戦略
静的な`hosts`ファイルなど、2024年のインフラには不要だ。Terraformで構築したリソースは、Ansibleから「動的」に参照する。
Terraform側の出力設定 (`outputs.tf`)
Ansibleが識別できるよう、リソースに`ansible_group`タグを付与するのが定石だ。
output “instance_ips” {
value = {
for instance in aws_instance.web :
instance.tags[“Name”] => instance.public_ip
}
}
Ansible連携用パイプライン設計
Terraformの出力をJSON形式でファイルに落とし、Ansible側で`community.aws.aws_ec2`プラグインまたは外部JSONスクリプトで読み込む。
ansible.cfg: チーム共有設定
[defaults]
inventory = ./inventory/aws_ec2.yml
remote_user = ec2-user
private_key_file = ~/.ssh/id_rsa
大規模環境では必ず有効化
pipelining = True
実行速度を劇的に上げる高速化設定
forks = 20
—
4. 冪等性を担保するディレクトリ構成のベストプラクティス
「どこに何があるか」を迷わせない構造こそが、チームの認知負荷を下げる。
├── terraform/
│ ├── modules/ # 再利用可能なリソース定義
│ ├── environments/ # prod/stagingの変数定義
│ └── main.tf
├── ansible/
│ ├── group_vars/ # 冪等性を担保する変数
│ ├── roles/ # 責務ごとに分割された役割
│ ├── site.yml # 全体実行のオーケストレーター
│ └── ansible.cfg
└── Makefile # 全ての操作を抽象化するインターフェース
プロのこだわり:`Makefile`の活用
コマンドを覚えるな、`make`を定義せよ。
実行例: make deploy env=prod
deploy:
cd terraform && terraform apply -auto-approve
cd ansible && ansible-playbook -i ./inventory site.yml
—
5. 最後に:テックリードからの提言
多くの現場が陥る罠は、「自動化のための自動化」だ。
Ansibleの役割は「一度書いて終わり」ではない。OSのパッチ適用やセキュリティ設定の変更など、「日々の運用で発生する変更を、コードベースで繰り返し適用できるようにすること」にこそ真の価値がある。
1. 失敗を許容せよ: 冪等性が担保されていれば、Playbookは何度叩いても同じ結果になる。恐れずに失敗し、自動で直る仕組みを構築せよ。
2. Lintを強制せよ: `ansible-lint` や `tflint` をCIに組み込め。個人の癖を排除し、チームの「共通言語」をツールに強制させるのだ。
技術とは、人間が本来やるべき創造的な仕事に集中するためのレバレッジに過ぎない。この構成を基盤とし、インフラを「管理するもの」から「自律的に進化するもの」へと昇華させてほしい。
健闘を祈る。