Terraformの「依存関係」で泥沼にハマらないために:明日から使える設計の極意
こんにちは。クラウドインフラの世界へようこそ。
Terraformを触り始めると、誰もが一度は「なぜかリソースが期待通りに作られない」「循環依存のエラーで進めない」という壁にぶつかります。
これらは単なるエラーではありません。Terraformがあなたの書いたコードをどう解釈し、クラウドのAPIとどう対話しているかを知るための、重要な登竜門です。今日は、Terraformの「依存関係」という心臓部を、現場の知見を交えて徹底的に解説します。
—
1. なぜ「依存関係」が重要なのか?
Terraformの本質は「宣言的プログラミング」です。「何を(What)」作りたいかを記述すれば、Terraformが「どうやって(How)」作るかを計算します。
この「どうやって」の計算において、Terraformはリソース同士の依存関係グラフ(Dependency Graph)を自動生成します。このグラフが正しく描けないとき、インフラ構築はカオスと化します。
暗黙的依存関係(Implicit Dependency)
Terraformは、コード内にリソースへの参照がある場合、自動的に依存関係を推測します。
セキュリティグループとインスタンスの例
resource “aws_security_group” “web_sg” {
name = “web-sg”
}
resource “aws_instance” “web” {
# ここでセキュリティグループのIDを参照しているため、
# Terraformは「SGを先に作る必要がある」と判断する(これが暗黙的依存)
vpc_security_group_ids = [aws_security_group.web_sg.id]
}
これが最強です。 基本的に、依存関係は可能な限りこの「暗黙」に任せてください。
明示的依存関係(Explicit Dependency: `depends_on`)
一方で、コード上の参照がないけれど、論理的に先に作ってほしいものがある場合に使うのが `depends_on` です。
—
2. `depends_on` の「正しい使い道」と「罠」
`depends_on` は強力ですが、「とりあえず使っておこう」という安易な実装は禁物です。
罠:リソースの再作成を引き起こす
`depends_on` を過剰に使うと、Terraformの依存グラフが複雑になりすぎ、予期せぬリソースの再作成(Destroy & Create)を誘発することがあります。
NGな例:
プロバイダーの制約などで、明示的に順序を固定しすぎてしまうと、
一部のプロパティ変更だけで連鎖的に全リソースが再作成されるリスクがある
resource “aws_s3_bucket_policy” “example” {
bucket = aws_s3_bucket.my_bucket.id
depends_on = [aws_s3_bucket.my_bucket] # 実は不要!
}
`aws_s3_bucket_policy` の中で `aws_s3_bucket.my_bucket.id` を参照していれば、Terraformは勝手に依存関係を理解します。そこに `depends_on` を書くのは、「地図があるのに目隠しをして歩く」ようなものです。
—
3. 循環依存(Circular Dependency)の回避術
大規模な構成になると、「AはBが必要、BはAが必要」という循環依存エラーに遭遇します。これは設計の敗北ではなく、「抽象化の粒度が間違っている」というシグナルです。
解決パターン:共通リソースの切り出し
もし、ネットワークとインスタンス間で循環依存が起きたら、依存関係の「共通基盤」を作ります。
1. 依存される側を独立させる: 相互に参照し合うのではなく、両者が参照する「共通のデータソース」や「別モジュール」を作成する。
2. データソースの活用: `data` ブロックを使って、既に存在するリソースを外部から読み込む形に変える。
—
4. 実践:Terraformの初期セットアップと確認
まずは、この「依存関係」の感覚を掴むために、最小構成を構築してみましょう。
手順1: プロバイダー設定
`provider.tf` を作成します。
terraform {
required_providers {
aws = {
source = “hashicorp/aws”
version = “~> 5.0”
}
}
}
provider “aws” {
region = “ap-northeast-1”
}
手順2: 依存関係を意識したHelloWorld
`main.tf` で、VPCとサブネットを作成し、依存関係を確認します。
VPCを作成(依存の親)
resource “aws_vpc” “main” {
cidr_block = “10.0.0.0/16”
}
サブネット(VPCに暗黙的に依存している)
resource “aws_subnet” “main” {
vpc_id = aws_vpc.main.id # ここで暗黙の依存が発生!
cidr_block = “10.0.1.0/24”
}
手順3: 動作確認
以下のコマンドで依存グラフを可視化できます。
terraform graph | dot -Tpng > graph.png
これで、Terraformがどうリソースを組み立てているのか、視覚的に確認してください。自分の書いたコードが、Terraformの脳内でどう変換されているかを知ることこそが、SREへの第一歩です。
—
先輩からのアドバイス
「依存関係」に悩むのは、あなたがコードを深く考え始めた証拠です。
「可能な限り暗黙的依存(参照)を使い、どうしても無理なときだけ `depends_on` を使う」。
この原則を守るだけで、あなたのIaCコードのメンテナンス性は劇的に向上します。
Terraformは、単なる設定ファイルではありません。クラウドの「理想の状態」を定義する魔法の杖です。ぜひ、その杖を使いこなして、自動化の快感を味わってください!
何か困ったことがあれば、いつでもまた聞きに来てくださいね。応援しています!