Hi,
GOAL
Using Terraform I want to use a connection to run an remote-exec on a Amazon Linux EC2 instance in AWS
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, which is a standard action
Here is a simple example:
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"
]
}
}
And my tfvars file looks like:
key_name = "#{awsPublicKey}"
aws_key_path = "#{martinTestPrivateKey}"
My variable martinTestPrivateKey
is saved as type sensitive under my project
I copy and paste my Private Key PEM which is encoded as UTF-8 with Windows Line Endings CR LF
ISSUE
When I run my Terraform Apply step with this setup my script falls over with the error:
invalid value "octopus_vars.tfvars" for flag -var-file: Error parsing octopus_vars.tfvars: At 9:20: expected '/' for comment
We wrote a Powershell script to determine what happens to the PEM data after it’s stored in Octopus Deploy Project Variable:
if (! (Test-Path $temp_pem_folder)) {
New-Item -Path $temp_pem_folder -ItemType "directory"
}
$file_name = "martinPrivateKey.pem"
$long_path = Join-Path $temp_pem_folder $file_name
$martinPrivateKey | Out-File $long_path
write-highlight $long_path
When we view this data in Notepad++ it tells us that the data of the file is saved as:
Unix(LF) UCS-2 LE BOM
When I test this with a less complex string in my var martinTestPrivateKey
, so a one liner rather than multiple lines and I check my test file in Notepad++ the data is saved as Windows(CR LF) UCS-2 LE BOM
which is still incorrect for Terraform to understand.
WORKAROUND
For me to workaround this problem I have to create a step before and a step after my Terraform Apply Step
The first step takes the contents of my variable and fixes it in a temp file so that the file is saved as UTF-8 with Windows File endings and NOT Unix file endings or UTF-8 BOM
Then I run my Apply which works and after that I run my third step which is to remove the file with the temp sensitive data
BUG/FUNCTIONALITY
Ok here is the thing I really don’t want to add unnecessary steps to my Project when in my mind they’re not needed. I hope and like to think that the data I add to my variable is not changed by Octopus Deploy to a encoding/format that breaks my Terraform Script, and also why does what I see as a Windows tech decide to change my file to add Unix style line endings
Can you let us know if this is by design for some reason that is not known to us yet? Otherwise I’d see this as a bug that needs to be fixed?
NOTE:
I do understand that the standard way to read data from a PEM file in Terraform is to use the following syntax using the var function where the var.aws_key_path
is the path to your PEM
connection {
host = self.public_ip
user = "ec2-user"
private_key = "${file(var.aws_key_path)}"
}
But the file
functions job is to convert the file data to a string with UTF-8 encoding
Just in case someone tries to point that out