2

In another thread I have asked how to keep ECS task definitions active in AWS. As a result I am planning to update a task definition like this:

resource "null_resource" "update_task_definition" {
  triggers {
    keys = "${uuid()}"
  }

  # Workaround to prevent older task definitions being deactivated
  provisioner "local-exec" {
    command = <<EOF
aws ecs register-task-definition \
--family my-task-definition \
--container-definitions ${data.template_file.task_definition.rendered} \
--network-mode bridge \
EOF
  }
}

data.template_file.task_definition is a template data source which provides templated JSON from a file. However, this does not work, since the JSON contains new lines and whitespaces.

I figured out already that I can use the replace interpolation function to get rid of new lines and whitespaces, however I still require to escape double quotes so that the AWS API accepts the request.

How can I safely prepare the string resulting from data.template_file.task_definition.rendered? I am looking for something like this:

Raw string:

{
  "key": "value",
  "another_key": "another_value"
}

Prepared string:

{\"key\":\"value\",\"another_key\":\"another_value\"}
bitbrain
  • 603
  • 5
  • 12

1 Answers1

3

You should be able to wrap the rendered JSON with the jsonencode function.

With the following Terraform code:

data "template_file" "example" {
  template = file("example.tpl")

  vars = {
    foo = "foo"
    bar = "bar"
  }
}

resource "null_resource" "update_task_definition" {
  triggers = {
    keys = uuid()
  }

  provisioner "local-exec" {
    command = <<EOF
echo ${jsonencode(data.template_file.example.rendered)}
EOF
  }
}

And the following template file:

{
  "key": "${foo}",
  "another_key": "${bar}"
}

Running a Terraform apply gives the following output:

null_resource.update_task_definition: Creating...
  triggers.%:    "" => "1"
  triggers.keys: "" => "18677676-4e59-8476-fdde-dc19cd7d2f34"
null_resource.update_task_definition: Provisioning with 'local-exec'...
null_resource.update_task_definition (local-exec): Executing: ["/bin/sh" "-c" "echo \"{\\n  \\\"key\\\": \\\"foo\\\",\\n  \\\"another_key\\\": \\\"bar\\\"\\n}\\n\"\n"]
null_resource.update_task_definition (local-exec): {
null_resource.update_task_definition (local-exec):   "key": "foo",
null_resource.update_task_definition (local-exec):   "another_key": "bar"
null_resource.update_task_definition (local-exec): }
ydaetskcoR
  • 53,225
  • 8
  • 158
  • 177
  • 1
    Looks like `vars {` should be `vars = {` – mathieux51 Nov 19 '20 at 06:41
  • @mathieux51 Thanks for the pointer. I've updated from the old HCL1 syntax to the HCL2 syntax here. In general I'm not going back through my hundreds of HCL1 answers and converting them but where someone suggests an edit or comments on an answer I'm happy to update it, especially with the looming 0.14 release making 0.12 a very old release now. – ydaetskcoR Nov 19 '20 at 09:41
  • Hi I have a similar question: https://stackoverflow.com/questions/65938396/json-parsing-error-when-running-aws-stepfunctions-update-state-machine-via-ter/65940756?noredirect=1#comment116588888_65940756 I'm trying to encode json for the logging JSON message, just wondering what is a .tpl file, how to generate it? Should I put my json message inside that file? – wawawa Jan 29 '21 at 11:08