Terraformのplan出力でjsonencode関数が使われる背景
結論
調査
jsonencode() を使うと < とかもエスケープされるという話を聞く
templatefile() を使えば回避できそうじゃない? とアドバイスするが「templatefile() を使っても jsonencode() が呼ばれる」と聞く
暗黙的な呼び出しっぽいけど、誰が呼んでいるのか気になって調べる
code:input.json.tftpl
{
"name": "${name}"
}
code:input.txt.tftpl
{
"name": "${name}"
}
code:main.tf
terraform {
required_version = "v1.4.5"
}
output "json" {
value = templatefile("./input.json.tftpl", { name = "aereal" })
}
output "txt" {
value = templatefile("./input.txt.tftpl", { name = "aereal" })
}
code:result
Changes to Outputs:
+ json = jsonencode(
{
+ name = "aereal"
}
)
+ txt = jsonencode(
{
+ name = "aereal"
}
)
You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
input.json.tftpl の場合は .json がついているのでパス名から推測されたのかな?と思ったけど input.txt.tftpl でも起きるということは中身を見ていることはほぼ明らか
かつ output で起きているのでproviderの実装は関係なく、Terraformコアの実装に由来している
terraform plan jsonencodeでググると「差分表示に jsonencode() を使うのは仕様なんだよ」というissueが見つかる renderStringDiffAsJson
renderStringDiff の中で str.Json != nil だったら呼ばれる
evaluatePrimitiveString の中で { か [で始まったら str.Jsonにnon-nilな値が入る
試しに templatefile()で読み取るファイルの先頭に空白を足して strings.HasPrefix(str, "{") || strings.HasPrefix(str, "[")がfalseになるよう変更してみる
code:plan
+ txt = <<-EOT
{
"name": "aereal"
}
EOT
jsonencode() が呼ばれなくなった!!