TT Lab
はじめる
学ぶ 学習パス コース

Terraform/OpenTofu基礎

変数の優先順位と出力の設計

TT Labで続きを見る

目標

同じ変数に、4つの方法で値を入れて、優先順位を直接確認し、検証・ローカル値・出力・機密値まで備えた設定を1つ完成させます。

なぜ重要なのか

「変数を変えたのに反映されない」という質問の答えは、ほとんどいつも優先順位です。ツールは、同じ名前の値を複数の場所から受け入れ、衝突してもエラーを出さず、静かにより強いほうを使います。便利な分、デバッグが難しくなるので、上書きするために作った値は弱い場所に、必ず守るべき値は強い場所に置く感覚が必要です。特に、コマンドラインで渡した値は、何にでも勝ちますが、どこにも記録されないので、障害対応で使って、コードに反映しなければ、次のデプロイがそれを静かに元に戻します。最後に、sensitive = trueは、画面の出力を隠すだけで、状態ファイルとJSON出力には、値がそのまま残ります。この限界を知らないまま、「機密の指定をしたから安全だ」と信じることが、最もよくある事故の始まりです。

ステップ

  1. /root/tf/vars/variables.tfに、environment変数を宣言してください。type = string、default = "dev"、descriptionがすべてある必要があります。/root/tf/vars/outputs.tfに、名前がenvironmentの出力を作り、デフォルト値のまま適用したあと、出力をJSONで/root/tf/vars/out/default-outputs.jsonに保存してください(.environment.valueがdev)。
  2. /root/tf/vars/terraform.tfvarsにenvironment = "stage"を書いて、再び適用したあと、出力を/root/tf/vars/out/tfvars-outputs.jsonに保存してください。値がstageに変わっている必要があります。ファイルがデフォルト値に勝ちます。
  3. 今度は、コマンドラインから-var environment=prodで値を与えて適用したあと、出力を/root/tf/vars/out/cli-outputs.jsonに保存してください。tfvars-outputs.jsonは、そのままにしておく必要があります(依然としてstage)。
  4. variables.tfにowner変数を宣言してください。ただし、デフォルト値をplatformとして書き込んでおかないでください。TF_VAR_owner=platform環境変数で値を渡して適用し、出力を/root/tf/vars/out/env-outputs.jsonに保存してください(.owner.valueがplatform)。outputs.tfにownerの出力も追加します。
  5. variables.tfにreplica_count変数を追加して、1以上5以下だけを許容するvalidationブロックを入れてください。conditionとerror_messageが両方ある必要があり、error_messageの中に、許容範囲が1-5という文字のまま入っている必要があります。範囲を外れた値(例: -var replica_count=9)で実行して、拒否された出力を、/root/tf/vars/out/validation.txtに保存してください。
  6. /root/tf/vars/main.tfにlocalsブロックを作り、name_prefixを、environmentとownerをハイフンでつないだ値として定義してください。outputs.tfにname_prefixの出力を追加します。ステップ8で再作成するcli-outputs.jsonのname_prefixは、prod-platformでなければなりません。
  7. 出力を/root/tf/vars/outputs.tfの1か所にまとめて、最低4つ(environment、owner、name_prefix、config_path)を置いてください。ただし、すべての出力にdescriptionを付けてください。config_pathは、この設定が作るlocal_fileのfilenameをそのまま出力します。
  8. variables.tfにapi_token変数をsensitive = trueで宣言して、値はTF_VAR_api_tokenで渡してください。outputs.tfにもapi_tokenの出力をsensitive = trueで追加します。最後に、-var environment=prodとTF_VAR_owner=platform、TF_VAR_api_tokenを一緒に与えて適用したあと、cli-outputs.jsonを再作成して、人が読む形式の出力も/root/tf/vars/out/sensitive.txtに保存してください。後者には、値の代わりに隠された表示があり、実際のトークンの文字列が見えてはいけません。

参考

型・デフォルト値・説明を備えた変数を宣言する

/root/tf/vars/variables.tfに、environment変数を宣言してください。type = string、default = "dev"、descriptionがすべてある必要があります。/root/tf/vars/outputs.tfに、名前がenvironmentの出力を作り、デフォルト値のまま適用したあと、出力をJSONで/root/tf/vars/out/default-outputs.jsonに保存してください(.environment.valueがdev)。

変数ブロックには、値のほかに付けられるものがあります。3つともないと、数か月後に、この値が何なのか、誰にもわかりません。出力は-jsonで取り出して保存してください。

tfvarsファイルでデフォルト値を上書きする

/root/tf/vars/terraform.tfvarsにenvironment = "stage"を書いて、再び適用したあと、出力を/root/tf/vars/out/tfvars-outputs.jsonに保存してください。値がstageに変わっている必要があります。ファイルがデフォルト値に勝ちます。

ディレクトリの中の特定の名前のファイルは、別に指定しなくても、自動的に読み込まれます。ファイルの中では、이름 = 값の形式だけを使います(プレースホルダーは、順に名前と値です)。

コマンドラインの値でファイルに勝つ

今度は、コマンドラインから-var environment=prodで値を与えて適用したあと、出力を/root/tf/vars/out/cli-outputs.jsonに保存してください。tfvars-outputs.jsonは、そのままにしておく必要があります(依然としてstage)。

優先順位の頂点は、実行するときに直接与えた値です。前のステップで保存した出力ファイルは、上書きせずに、新しいファイルに残してください。

環境変数で値を注入する

variables.tfにowner変数を宣言してください。ただし、デフォルト値をplatformとして書き込んでおかないでください。TF_VAR_owner=platform環境変数で値を渡して適用し、出力を/root/tf/vars/out/env-outputs.jsonに保存してください(.owner.valueがplatform)。outputs.tfにownerの出力も追加します。

変数名の前に決まった接頭辞を付けた環境変数を、ツールが自動的に読みます。デフォルト値に同じ値を書き込んでおくと、環境変数が効いたことを証明できません。

許容範囲をコードで固定する

variables.tfにreplica_count変数を追加して、1以上5以下だけを許容するvalidationブロックを入れてください。conditionとerror_messageが両方ある必要があり、error_messageの中に、許容範囲が1-5という文字のまま入っている必要があります。範囲を外れた値(例: -var replica_count=9)で実行して、拒否された出力を、/root/tf/vars/out/validation.txtに保存してください。

変数ブロックの中に、条件とメッセージを入れるブロックを入れます。メッセージは、ユーザーがそれだけを見て直せる必要があるので、許容範囲を文字のまま書いてください。

localsで名前の接頭辞を組み合わせる

/root/tf/vars/main.tfにlocalsブロックを作り、name_prefixを、environmentとownerをハイフンでつないだ値として定義してください。outputs.tfにname_prefixの出力を追加します。ステップ8で再作成するcli-outputs.jsonのname_prefixは、prod-platformでなければなりません。

localsは、外から注入できない、名前を付けた式です。2つの変数をハイフンでつないだ値を作って、出力として出してください。

説明が付いた出力をまとめておく

出力を/root/tf/vars/outputs.tfの1か所にまとめて、最低4つ(environment、owner、name_prefix、config_path)を置いてください。ただし、すべての出力にdescriptionを付けてください。config_pathは、この設定が作るlocal_fileのfilenameをそのまま出力します。

出力は、この設定の公開インターフェースなので、1つのファイルにまとめます。1つでも説明が抜けていると、採点が個数を数えて見つけます。

機密値を隠す方法と、その限界を確認する

variables.tfにapi_token変数をsensitive = trueで宣言して、値はTF_VAR_api_tokenで渡してください。outputs.tfにもapi_tokenの出力をsensitive = trueで追加します。最後に、-var environment=prodとTF_VAR_owner=platform、TF_VAR_api_tokenを一緒に与えて適用したあと、cli-outputs.jsonを再作成して、人が読む形式の出力も/root/tf/vars/out/sensitive.txtに保存してください。後者には、値の代わりに隠された表示があり、実際のトークンの文字列が見えてはいけません。

変数と出力の両方に、機密の指定が必要です。人が見る出力と機械が読む出力を、それぞれ保存して、2つの結果がどう違うかを比較してください。