Terraformの「データソース地獄」から脱出せよ:大規模インフラを高速化する戦略的設計術
こんにちは。クラウドの海を渡り歩くSREエンジニアです。
Terraformを触り始めて、「`terraform plan` を打つたびにコーヒーを淹れに行けるほど時間がかかる」という経験はありませんか? それ、あなたが書いたコードのせいかもしれません。
今日は、大規模インフラで避けて通れない「データソースのパフォーマンス劣化問題」について、現場の最前線で使われている「刺さる」最適化テクニックを伝授します。
—
1. なぜ「データソース」は計画を重くするのか?
Terraformの `data` ブロックは、既存のリソース情報をAPI経由で取得する「読み取り専用」の窓です。しかし、これが多用されると、Terraformはプラン実行のたびにクラウドのAPIを叩きまくります。
- APIレート制限の壁: 100個のデータソースがあれば、100回以上のAPIコールが発生します。AWSやGCPのレート制限に即座に抵触します。
- 依存関係の直列化: Terraformは依存関係をグラフ化しますが、データソースが多すぎると計算コストが爆発し、プラン完了までの時間が指数関数的に伸びます。
教訓: 「とりあえずデータソースで取ってこよう」という安易な設計が、インフラのデプロイ速度を殺す最大の要因です。
—
2. パフォーマンスを劇的に改善する「ローカル変数」キャッシュ戦略
データソースを何度も呼ぶのは愚策です。「一度取って、ローカル変数で使い回す」のが鉄則です。
悪い例:何度もデータソースを叩く
非推奨:使うたびにAPIを叩くリスクがある
resource “aws_instance” “web” {
ami = data.aws_ami.ubuntu.id
}
resource “aws_instance” “db” {
ami = data.aws_ami.ubuntu.id
}
良い例:ローカル変数で抽象化する
データソースは最小限に絞り、その結果を `locals` に格納して参照します。
locals {
# 一度だけデータソースを評価し、あとは変数として使い回す
base_ami = data.aws_ami.ubuntu.id
}
resource “aws_instance” “web” { ami = local.base_ami }
resource “aws_instance” “db” { ami = local.base_ami }
—
3. 大量ループ処理の「フィルタリング」最適化テクニック
例えば「特定のタグを持つVPCをすべて取得して処理したい」という場合、全リソースを取得してTerraform側でフィルタリングしてはいけません。API側で絞り込むのがエンジニアの流儀です。
効率的なフィルタリングの例
Terraformの `data` ブロックは、APIレベルのフィルタリングをサポートしています。
data “aws_instances” “production_web” {
# サーバーサイド(API側)でフィルタリングを行い、転送量を最小化する
filter {
name = “tag:Environment”
values = [“production”]
}
filter {
name = “instance-state-name”
values = [“running”]
}
}
ポイント: 取得結果の件数が多い場合、`data` リソースをあえて定義せず、`terraform_remote_state` や `SSM Parameter Store` を活用して、必要なメタデータだけを軽量に取得する手法も検討してください。
—
4. 基礎セットアップ:Terraformを最速で動かす第一歩
これから始める方のために、まずは基本の「型」を身につけましょう。
インストール(tfenvを推奨)
バージョン管理は必須です。`tfenv` を使いましょう。
brew install tfenv
tfenv install 1.6.0
tfenv use 1.6.0
精度高い HelloWorld (main.tf)
単にリソースを作るのではなく、「Providerのバージョンを固定する」ことが、プロの現場でのマナーです。
1. バージョン固定で冪等性と安全性を担保
terraform {
required_providers {
aws = {
source = “hashicorp/aws”
version = “~> 5.0”
}
}
}
2. プロバイダー設定
provider “aws” {
region = “ap-northeast-1”
}
3. 動作確認用リソース(最小単位)
resource “aws_vpc” “main” {
cidr_block = “10.0.0.0/16”
tags = {
Name = “HelloWorld-VPC”
}
}
—
最後に:エンジニアとしてのマインドセット
Terraformを書く際、「このコードが1000回実行されたらどうなるか?」を常に想像してください。
1. 疎結合にする: モジュールを分け、データソースの依存関係を最小化する。
2. APIを信じすぎない: 取得したデータが常に最新とは限らない。ステートファイルのキャッシュを理解し、必要に応じて `terraform refresh` を使い分ける。
この最適化をマスターすれば、あなたのインフラ構築は「遅い作業」から「洗練されたコード体験」へと変わります。さあ、次はあなたの番です。美しいコードでクラウドを制御しましょう。
何か詰まったら、いつでも聞いてくださいね。応援しています!