0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

terraformAdvent Calendar 2023

Day 13

入力バリデーションの別解を書いてみたよ

Last updated at Posted at 2023-12-12

tl;dr

input variables の残念なところ

  • input ブロック内では他の variables や locals を参照できない
  • ゆえに、必要な条件、取り得る値などはベタ書きする必要がある
  • なので、条件の追加変更削除時には、それらテキストも同時に修正する必要がある
  • そして、許可しない値の時は通らない(通さないのが正だからいいんだけどね)

以前の(バリデーションの)代替方式

  • locals 等で file() なんかを使ってエラーにさせる(今でも動くけどあんまりよくないよね。file() の引数エラー扱いだし。エラーメッセージ部分はちゃんと出力されるけど用途が違う)
locals {
   env_id_validation = var.env_id == "d" || var.env_id == "p" 
        ? var.env_id 
        : file("エラーメッセージ")
}

  • null_resource 等で lifecycle の precondition, postcondition を使用する
  • 今なら terraform_data が使えるかな
  • 好みの問題かもしれないけど、バリデーションのためにリソースつけたくないかなって

こんな条件の時は違うやり方ができる

  • バリデーションエラーでも通したい(一時的にとか、整備前とか)ワーニングが出ればいいなどの場合
  • 入力値の説明を input block に書かなくてもいい(ドキュメント化処理で取り込まれなくてもいい場合)
  • 要は手抜きで構わない
  • あと、チェックに変数使いたい(条件の追加変更削除で楽したい。もしくはDRYにしたい)

そんなあなたに別解

※変数名とチェックの条件と取り得る値は元の記事から拝借しました

variables.tf

variable "env_id" {
  description = "One-letter of environment ID."
  type        = string
  default     = "d"
  // デフォルトはあってもなくてもOK
}

locals {
  allow_env_ids = {
    "d" = "Development",
    "t" = "Test",
    "s" = "Staging",
    "p" = "Production",
    "g" = "General",
    "b" = "Sandbox",
  }
}

check "env_id" {
  assert {
    condition = contains(keys(local.allow_env_ids), var.env_id)
    error_message = join("", [
      "The env_id value must be: ",
      join(", ", keys(local.allow_env_ids)),
      // output の例で差し替え可
    ])
  }
}

// 以上3つでセットにしておくと追加変更削除があった時に楽かなって。
// 以下 output はおまけ

output "env_id" {
  description = "現在の env_id"
  value       = var.env_id
}

output "examples_error_message_001" {
  description = "ダブルクォーテーションで囲む"
  value       = "\"${join("\", \"", keys(local.allow_env_ids))}\""
  // きれいに見たい(エスケープが邪魔だなって)時は
  // terraform output -raw examples_error_message_001
}

output "examples_error_message_002" {
  description = "丸かっこのほうが見やすいかも(そうでもないか)"
  value       = "(${join("), (", keys(local.allow_env_ids))})"
}

output "examples_error_message_003" {
  description = "一般的には角括弧かな"
  value       = "[${join("], [", keys(local.allow_env_ids))}]"
}

output "examples_error_message_004" {
  description = "Value を表示したいなら"
  value       = join(", ", values(local.allow_env_ids))
}

output "examples_error_message_005" {
  description = "key と value と両方表示したいなら"
  value = join(", ", flatten([
    for key, value in local.allow_env_ids :
    "${key}:${value}"
  ]))
}

  • このまま動くのでディレクトリにでも放り込んで試してみて(このファイルだけで動く)
  • locals block は何回でも書けるので、このような順番で3つをセットにして扱うとわかりやすくない?
  • ちなみに input でのチェックと違って plan 後にチェックされるし、ワーニングにしかならないので実戦投入する時は要件に注意
  • いろいろ遊んでみるといいと思う

最後に

  • ご利用は自己責任でお願いします
  • 別解を考えるの楽しいよね(アドカレにあと2日?くらい空きがあるのでどなたか!)
  • ちなみにイオンのエンジニアさんってやっぱイオンピープルなの?w
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?