Terraform: Extra $ is not escaping in template_file rendered in inline

Created on 15 Jun 2016  ·  7Comments  ·  Source: hashicorp/terraform

I need to generate a shell script on a remote node that references terraform variables and shell variables within the script. I know that I can use $ to escape, however, when using a cat heredoc method in the inline, something like $$var1 will be empty.

I need to reference the instance local dns and ip address in the configuration. When the count > 1, I cannot reference the instance output (i.e. "${aws_instance.example.private_ip}").

Terraform Version

0.6.15

Affected Resource(s)

  • aws_instance
  • template_file

    Terraform Configuration Files

resource "template_file" "example" {
    template       = "${file("${path.module}/example.sh.tpl")}"
    vars {
        name        = "${var.name}"
    }
}

resource "aws_instance" "test" {
    provisioner "remote-exec" {
        inline = [    
            "cat <<EOF > example.sh",
            "${template_file.example.rendered}",
            "EOF"
        ]
    }
}
# example.sh.tpl
var1="$$(some linux command)"

cat <<TMP > somefile
$$var1
TMP

When example.sh is written to the remote instance, $$var1 should be $var1 however it is empty. I am generating two files because I need to reference the instance private ip in a file. When the file is generated, the first line will not show the command, but will show the output of the command.

I'm also doing this with a count > 1. The remote-exec provisioner does not allow me to reference the instance private_ip with a count > 1. I've tried:

"${aws_instance.example.private_ip}" # which works only on the first instance

"${element(aws_instance.example.*.private_ip, count.index)}" # which errors out before launching the instances.

EDIT: For the issue above, I totally missed the self attribute. However, I would still like to be able to do this with a template as it makes the .tf file look cleaner. I am trying to generate a json file and requires a lot of escaping for the quotes.

Expected Behavior

In generating the file from the remote-exec, $$var1 should output to $var1

# example.sh
var1="$(hostname)"

cat <<TMP > somefile
$var1
TMP

Actual Behavior

The file will contain a var that contains a linux command. The generated file shows the actual output instead of the command. And the referenced var that is using the $ escape is blank.

# example.sh
var1="ip-10-0-0-100.ec2.local"  # showing the actual output and not the command

cat <<TMP > somefile
                                # is blank
TMP
bug core

Most helpful comment

When implementing a cloudwatch agent config I had to use \$$ to escape a value of a template file:

  "append_dimensions": {
      "ImageId": "\$${aws:ImageId}",
      "InstanceId": "\$${aws:InstanceId}",
      "InstanceType": "\$${aws:InstanceType}",
      "AutoScalingGroupName": "\$${aws:AutoScalingGroupName}"
  }

Just had this EXACT same problem, and went round in circles for ages before trying this. Then found this post :-)
Thanks

All 7 comments

Hi @nocode99 - thanks for taking the time to write up this nice bug report and repro case for us! I agree that template_file should respect the documented dollar-sign escaping behavior. One of us will get back to you when we have had a chance to take a look. 🔍

This is working on master, so I believe this was fixed at some point (and likely has a test to cover it since this is in HCL).

Why this closed? This still happens in v0.8

@akaspin I just ran the exact same example again (v0.8) to verify and got the expected result:

2016-12-14 at 9 43 am

When implementing a cloudwatch agent config I had to use \$$ to escape a value of a template file:

    "append_dimensions": {
        "ImageId": "\$${aws:ImageId}",
        "InstanceId": "\$${aws:InstanceId}",
        "InstanceType": "\$${aws:InstanceType}",
        "AutoScalingGroupName": "\$${aws:AutoScalingGroupName}"
    }

When implementing a cloudwatch agent config I had to use \$$ to escape a value of a template file:

  "append_dimensions": {
      "ImageId": "\$${aws:ImageId}",
      "InstanceId": "\$${aws:InstanceId}",
      "InstanceType": "\$${aws:InstanceType}",
      "AutoScalingGroupName": "\$${aws:AutoScalingGroupName}"
  }

Just had this EXACT same problem, and went round in circles for ages before trying this. Then found this post :-)
Thanks

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gwagner picture gwagner  ·  81Comments

phinze picture phinze  ·  86Comments

oillio picture oillio  ·  78Comments

felnne picture felnne  ·  133Comments

shubhambhartiya picture shubhambhartiya  ·  72Comments