10
votes

Within Octopus Deploy I've setup a Terraform Apply Step using their Apply a Terraform template

In my Terraform main.tf file I want to use a connection to run an remote-exec on a Amazon Linux EC2 instance in AWS

    resource "aws_instance" "nginx" {
      ami           = "${var.aws_ami}"
      instance_type = "t2.nano"
      key_name      = "${var.key_name}"

      connection {
        type        = "ssh"
        user        = "ec2-user"
        private_key = "${var.aws_key_path}"
      }

      provisioner "remote-exec" {
        inline = [
          "sudo amazon-linux-extras install epel -y",
          "sudo yum update -y",
          "sudo amazon-linux-extras install nginx1.12 -y",
          "sudo systemctl enable nginx.service",
          "sudo systemctl start nginx.service",
          "sudo systemctl status nginx.service"
        ]
      }
    }

As part of the connection block we need to connect using an SSH key pair using a Private Key PEM to auth with the Public Key stored on AWS

My Private Key is stored as a variable in my Project in Octopus deploy

For my private key to be interpreted correctly in Terraform as a multi-line string I had to use 'here doc' syntax using a starting EOF and an ending EOF

This syntax explanation can be found on the Terraform official documentation at

https://www.terraform.io/docs/configuration-0-11/syntax.html

This was my original problem that my variable syntax was falling over as I wasn't handling the multi-line PEM file correctly and I raised the ticket below with Octopus Deploy Support

https://help.octopus.com/t/terraform-apply-step-pem-variable-set-to-unix-lf-ucs-2-le-bom/23659

Where they kindly were able to point me in the direction of the EOF syntax

This all worked great on Terraform v0.11 but we've a lot of code here on this side that's been written in the latest HCL2 in v0.12

So I wanted to force Octopus Deploy to use a v0.12 binary rather than the prepackaged v0.11 that Octopus Deploy comes with. And they offer a built in Special var so you can use a different binary

But when I run it with this binary the script blows up with the error below

Error: Unterminated template string
No closing marker was found for the string. 
August 6th 2019 14:54:07 Error
Calamari.Integration.Processes.CommandLineException: The following command: "C:\Program Files\Octopus Deploy\Octopus\bin\terraform.exe" apply -no-color -auto-approve -var-file="octopus_vars.tfvars" 
August 6th 2019 14:54:07 Error
With the working directory of: C:\Octopus\Work\20190806135350-47862-353\staging 
August 6th 2019 14:54:07 Error
Failed with exit code: 1 
August 6th 2019 14:54:07 Error
Error: Unterminated template string 
August 6th 2019 14:54:07 Error
  on octopus_vars.tfvars line 34:

I've had a look at the official documentation for v0.12

https://www.terraform.io/docs/configuration/syntax.html#terraform-syntax

And I'm not sure if there is anything that helps in relation to how to manage multi-line that they had in v0.11

Here is the code block that worked in v0.11 successfully from my tfvars file

aws_ami = "#{ami}"
key_name = "#{awsPublicKey}"
aws_private_key = <<-EOF
#{testPrivateKey}
-EOF

The expected result when I ran this with the latest version of Terraform v0.12.6 was that it would function normally and run my Terraform Apply within Octopus Deploy

My hope here is that someone from Hashicorp has a workaround for this as I see this was supposed to be fixed with https://github.com/hashicorp/terraform/pull/20281

But I'm using the latest binary at the time of writing this v0.12.6 downloaded today

Any suggestions anyone on how to get this working in v0.12? Cheers

1
Terraform 0.12 has been having a lot of issues with heredoc.Matt Schuchard

1 Answers

15
votes

The correct syntax for a "flush heredoc" does not include a dash on the final marker:

aws_key_path = <<-EOF
#{martinTestPrivateKey}
EOF

If prior versions were accepting -EOF to end the heredoc then that unfortunately was a bug, which has now been fixed in Terraform 0.12 and so moving forward you must use the syntax as documented, with the marker alone on the final line.