Terraformの「外」へ手を伸ばせ:externalプロバイダで構築の限界を突破する
こんにちは。インフラの現場で「Terraformだけじゃ、この情報取れないな…」と壁にぶつかったことはありませんか?
AWSやGCPのプロバイダが提供するリソース定義だけでは、どうしても手の届かない領域があります。例えば、「オンプレミスのレガシーDBから最新の設定値を取得したい」「独自APIで管理されている動的なIDを動的に参照したい」といったケースです。
ここで諦めて手動設定に逃げるのは、SREとして一番やってはいけないこと。Terraformの `external` プロバイダを使いこなせば、Terraformの柔軟性は無限に広がります。今日は、その「裏技」とも言える実践的活用術を、現場の視点から伝授しましょう。
—
1. なぜ `external` プロバイダなのか?
Terraformは「宣言的」なツールです。「あるべき状態」をコードで記述します。しかし、その「あるべき状態」の値が、外部の実行結果に依存している場合はどうすればいいでしょうか?
`external` プロバイダは、外部のシェルスクリプトやバイナリを実行し、その標準出力をJSONとして受け取るための窓口です。
`null_resource` との違い
よく比較されるのが `null_resource` ですが、目的が全く違います。
- `null_resource`: 「副作用」を起こすもの(構築後にスクリプトを走らせて設定を流し込むなど)。Terraformのグラフ管理外で動くため、状態管理には向かない。
- `external` プロバイダ: 「データ」を取得するもの。出力されたJSONをTerraformの変数として扱えるため、リソースの依存関係を正しく構築できる。
—
2. HelloWorld:外部から「今、何時?」を取得する
まずは、外部スクリプトの結果をTerraformに取り込む最小構成を試しましょう。
手順1:シェルスクリプトの作成 (`get_time.sh`)
Terraformは、標準出力(stdout)にJSON形式で結果を出すスクリプトを期待します。
!/bin/bash
JSON形式で出力するのが鉄則です
エラー時はstderrに出力すればTerraform側で捕捉できます
echo ‘{“timestamp”: “‘$(date +%s)'”, “message”: “hello from script”}’
※ 実行権限を忘れずに (`chmod +x get_time.sh`)。
手順2:Terraformでの呼び出し (`main.tf`)
`data “external”` ブロックを定義します。
data “external” “example” {
program = [“bash”, “${path.module}/get_time.sh”]
}
取得したデータを出力してみる
output “script_result” {
value = data.external.example.result.timestamp
}
これで `terraform plan` を実行すれば、スクリプトが叩かれ、JSONの中身が変数として取り込まれます。感動しませんか?これが自動化の第一歩です。
—
3. 実践:現場で震えるほど役立つ「エラーハンドリング」
現場で使うなら、スクリプトが失敗した時のケアが必須です。Terraformは標準エラー出力(stderr)を受け取ると、自動的にエラーとして認識して停止してくれます。
堅牢にするためのコツ:
1. JSONのバリデーション: スクリプト内で `jq` コマンドを使うと、安全にJSONを構築できます。
2. 終了ステータス: スクリプトが失敗した時は `exit 1` を返すことで、Terraformのパイプラインを確実に止められます。
!/bin/bash
エラーハンドリングの例
set -e # エラー時に即時終了
何らかのAPIリクエストをシミュレーション
失敗したらstderrにメッセージを出して終了
if ! curl -s https://api.example.com/data > /dev/null; then
echo “Error: API connection failed” >&2
exit 1
fi
成功時のみJSONを出力
echo ‘{“status”: “ok”}’ | jq -c .
—
4. セキュリティと設計思想の注意点
この手法は強力ですが、乱用は禁物です。
- 機密情報の取り扱い: スクリプトの実行結果は `terraform.tfstate` に保存されます。APIキーやパスワードをそのまま出力しないよう、`sensitive = true` を活用してください。
- 冪等性(べきとうせい)の意識: スクリプト内で「DBのレコードを削除する」などの破壊的な処理を行ってはいけません。`data` ソースはあくまで「読み取り専用」であるべきです。
- 代替案の検討: もし取得先がポピュラーなサービスなら、まずはTerraform Registryで公式のプロバイダがないか探してください。`external` はあくまで「最後の手段」です。
—
最後に:自動化の先にあるもの
`external` プロバイダをマスターするということは、「Terraformというツールに、あなたのチーム独自の知見(ロジック)を統合できる」ということです。
最初は小さなスクリプトからで構いません。動的な設定値の取得、独自のバリデーションチェックなど、手作業を一つずつコードに置き換えていく過程こそが、真のSREエンジニアへの道です。
これをマスターすれば、あなたのインフラ管理は劇的に、そして圧倒的に楽になります。さあ、あなたの環境で「Terraformの境界線」を越えてみてください。応援しています!