Terraformのjsonencode関数でjson文字列を生成するとき、 <
>
&
U+2028
U+2029
はエスケープされる。
このため、例えば aws_cloudwatch_event_target の input_transformerを用いて送信メッセージをカスタマイズしたい場合に <
>
を利用すると上手く動作しなくなる。
resource "aws_cloudwatch_event_target" "http" { event_bus_name = "default" arn = aws_cloudwatch_event_api_destination.this.arn rule = aws_cloudwatch_event_rule.this.name role_arn = aws_iam_role.this.arn input_transformer { input_paths = {sender_ip = "$.detail.senderIP"} input_template = jsonencode( # <------------ This is where the problem occurs {message = "Connection from <sender_ip>"} ) } }
回避策としては、ヒアドキュメントを利用するかreplace関数を利用するか。
# ヒアドキュメントを利用 resource "aws_cloudwatch_event_target" "http" { event_bus_name = "default" arn = aws_cloudwatch_event_api_destination.this.arn rule = aws_cloudwatch_event_rule.this.name role_arn = aws_iam_role.this.arn input_transformer { input_paths = {sender_ip = "$.detail.senderIP"} input_template = <<<EOT { "message": "Connection from <sender_ip>" } EOT } }
# replace関数を利用 resource "aws_cloudwatch_event_target" "http" { event_bus_name = "default" arn = aws_cloudwatch_event_api_destination.this.arn rule = aws_cloudwatch_event_rule.this.name role_arn = aws_iam_role.this.arn input_transformer { input_paths = {sender_ip = "$.detail.senderIP"} input_template = replace(replace(jsonencode({message = "Connection from <sender_ip>"}), "\\u003c", "<"), "\\u00e3", ">") } }
また、こちらのissueにコメントがある通り、Terraform 1.8からは Provider-defined functionsもサポートされたので、terraform-provider-aws 側にてカスタム関数を構築して実装を容易にするアプローチも考えられるらしい。 terraform-provider-aws リポジトリでは新しくnew-functionラベルが生まれたが、このアプローチはIssue化まではされていない。