jsonencode
S3 の Policy 情報など、terraform の tf ファイル中に JSON を書くケースはそれなりにあります。
terraform 0.12 から for ~ endfor
に対応したので、リストなどの情報を foreach 的に回して記述をしたいケースがあります。
https://www.terraform.io/docs/configuration/expressions.html
上記2つが交わったときに、いかに JSON に適合した記法にできるか、という課題があります。端的に言うと「ケツカンマ問題」とかです。
同じような課題は他の人も同じように抱えているのか、terraform の公式リポジトリの Issue に以下のようなものが投稿されていました。
github.com/hashicorp/terraform - template for loop trailing comma in JSON
結論としては、 jsonencode
という組み込み関数を使うと解決します。
Issue に書かれた内容を例にすると
"mountPoints": [
%{ for mount in mount_map }
{
"sourceVolume": "${mount.source}",
"containerPath": "${mount.path}"
},
%{ endfor }
]
と書くと、ケツカンマ問題が発生し構文エラーになります。
"mountPoints": ${jsonencode([
for mount in mount_map : {
sourceVolume = mount.source
containerPath = mount.path
}
])}
と書くと、ループの内容を JSON 記法に置き換えてくれます。
Reference
jsonencode
の仕様については以下の公式ドキュメントにも記載されています。
https://www.terraform.io/docs/configuration/functions/jsonencode.html
なお、 jsonencode の逆の処理を行う jsondecode
という関数も存在します。
https://www.terraform.io/docs/configuration/functions/jsondecode.html
jsonencode のような組み込み関数は、terraform のソースの中では以下で定義されているので、どのような機能が使えるか概観したいときはこちらを読むとわかりやすいと思います。
https://github.com/hashicorp/terraform/blob/285e5457352530ba0fe8ff2840260d12f5237028/lang/functions.go#L32-L133
なお jsonencode は内部的には go-cty
の JSONEncodeFunc
を呼び出しているんですね。
https://github.com/zclconf/go-cty/blob/master/cty/function/stdlib/json.go#L9-L34