Terraform Associate 004 #7 設定の作成 — 変数の優先順位、関数、カスタム条件
設定作成の領域は、基礎 #3・#4 で手に馴染んだ文法がほとんどですが、2 つだけ事情が違います。試験は優先順位の正確な順序を問い、004 はトラックで浅くしか触れなかったカスタム条件を正面から問います。知っている部分は素早く圧縮し、補強部分に分量を割きます。
変数 — 型と優先順位 #
型には string、number、bool と、コレクション(list、set、map)、構造型(object、tuple)があり、型違反は plan の前に拒否されます。試験の定番は値の入力元の優先順位です。後に評価される側が勝ちます。
(弱い) 環境変数 TF_VAR_名前
→ terraform.tfvars
→ terraform.tfvars.json
→ *.auto.tfvars (ファイル名のアルファベット順)
→ -var、-var-file (コマンドライン、指定した順) (強い)トラックで使わなかった項目が 2 つ混ざっています。*.auto.tfvars は名前に関係なく自動で読み込まれるファイルで、tfvars には JSON 表記も存在します。「同じ変数が複数の場所で定義されていたら?」という問題には、このはしごのより下(コマンドライン側)が勝つ、と答えます。sensitive = true は plan の出力を隠すだけで state には平文のまま、という点(#5)もここで思い出しておきます。
output と locals — 圧縮復習 #
output は値の出口で、terraform output コマンドで再取得でき、output にも sensitive の指定が可能で、モジュール間の通路になります(#6)。locals は内部の計算に名前を付けるもので、宣言は locals ブロック・参照は local.名前 という単数・複数の違いが細かい引っかけです。「利用者が変える値は variable、内部の組み合わせは locals」という基礎 #3 の基準が、設計問題の答えです。
関数と式 — 頻出だけ #
関数は自作できず、組み込み関数だけを使うという大前提が最初の出題ポイントです。問題によく登場するものだけに絞ると次のとおりです。
- コレクション:
length、merge(マップの結合、後が勝つ)、lookup(マップからキーを検索、デフォルト値を指定)、toset(for_each 用の変換) - 文字列・エンコード:
format、join/split、jsonencode(IAM ポリシーの定番)、base64encode - ファイル:
file(内容の読み込み)、templatefile(変数を差し込みながら読み込み、user_data の定番) - 型判定・条件:
can(式が成功するかどうか)、try(失敗時の代替値)
式の側は条件式 a ? b : c、for 式(角かっこ=リスト、波かっこ=マップ)、スプラット [*] がすべてで、基礎 #4 のままです。terraform console が式の実験ツールであることも、コマンド問題として出ます。
補強 — カスタム条件の 3 種類 #
004 が強化した領域です。条件をどこに掛けるかで 3 種類あり、何を検証するのかで区別します。
変数の validation: 入力値の検証です。基礎 #3 で実習したもので、値が入ってくる時点で評価されます。
precondition・postcondition: リソース・データソース・output の
lifecycleブロックの中に掛ける前提の検証です。
data "aws_ami" "al2023" {
# ... 検索条件 ...
lifecycle {
postcondition {
condition = self.architecture == "x86_64"
error_message = "取得した AMI は x86_64 アーキテクチャである必要があります。"
}
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.al2023.id
lifecycle {
precondition {
condition = data.aws_ami.al2023.state == "available"
error_message = "AMI が available 状態でなければインスタンスを作成できません。"
}
}
}precondition はそのオブジェクトを評価する前に成立しているべき前提(主に依存先に対する確認)で、postcondition は評価された結果が満たすべき保証です。postcondition の中では self で自分の属性を参照します。失敗すると plan・apply がエラーで止まるため、「誤った前提でインフラが作られること」をコード自身が防ぐ仕組みです。
- check ブロック: インフラの継続的な検証です。トップレベルの
checkブロックに assert を入れます。決定的な違いは、失敗しても apply を止めず、警告を残すだけという点です。「デプロイは止めないが状態は監視したい」(証明書の期限が近いかの確認など)が用途です。
区別問題の軸は 2 つです。検証の対象(入力値 / 前提・結果 / 継続的な状態)と、失敗の効果(ブロック / ブロック / 警告)です。この 2 軸さえ押さえれば、3 つの仕組みのどんな組み合わせ問題も解けます。
まとめ #
今回扱った内容です。
- 変数の優先順位は環境変数 → tfvars → auto.tfvars → コマンドラインの順で、後が勝ちます。auto.tfvars の自動読み込みが馴染みの薄い項目です
- 関数は組み込みだけが使え、merge、lookup、templatefile、jsonencode、try・can が頻出です
- validation は入力値の検証で、失敗するとブロックします
- precondition は評価前の前提、postcondition は評価後の保証で self 参照が可能、どちらも失敗するとブロックします
- check ブロックは継続的な検証で、唯一、失敗しても apply を止めず警告だけを残します
次回(#8 新範囲集中)では、004 の看板となる新範囲 ephemeral 値と write-only 引数、そして depends_on・lifecycle のメタ引数をまとめて整理します。