User_data in terraform unable to receive variable of pem key

While creating ec2 instance with Terraform, I wish to inject the whole pem key file into the script.

resource "aws_instance" "myinstance" {
  ...
  user_data = base64encode(templatefile(
    "${path.module}/userdata.sh", {
       conf_tls_private_key = tls_private_key.mykey.private_key_pem
       conf_tls_self_signed_cert = tls_self_signed_cert.mykey2.cert_pem
    }
  ))
}

The terraform file implementation is as above. While using terraform console, I tested the tls_private_key.mykey.private_key_pem expression and it gives me the normal OPENSSH PRIVATE KEY format.

❯ tf console
> tls_private_key.boundary.private_key_pem
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAql5ImjYHynOkQGWL0DGT/3FGCIM6gouUi57MllyZCztzrBwp
FtWe+zJNWWjAu+WeyESqSnzmdFRnUiIqqo4Fq98yvF3+pjsbSMsC9s4H4wz/gp4o
ZzYXja4u7fBWGFMUKfU53M6zZS0FL0QQ/Tgt9u+p9q6HlyhtxiNKY0e3aX4xdCMH
QSrBLBIHLlpapkl/bvWk1xkSPEPNkNHbTvBd+3z2iWtxANEqO6ARItCCI+DcGyWP
W1FIwwKFBftNQAgxfs2pxdSnqpoaHSi4M9XjY7r7bADUItf9zpAy+PbqJr+F3Bzc

However, while the userdata.sh gets executed in ec2, it gives an error like below.

/var/lib/cloud/instance/scripts/part-001: line 8: RSA: command not found
/var/lib/cloud/instance/scripts/part-001: line 9: MIIEogIBAAKCAQEAql5ImjYHynOkQGWL0DGT/3FGCIM6gouUi57MllyZCztzrBwp: No such file or directory
/var/lib/cloud/instance/scripts/part-001: line 10: FtWe+zJNWWjAu+WeyESqSnzmdFRnUiIqqo4Fq98yvF3+pjsbSMsC9s4H4wz/gp4o: No such file or directory
/var/lib/cloud/instance/scripts/part-001: line 11: ZzYXja4u7fBWGFMUKfU53M6zZS0FL0QQ/Tgt9u+p9q6HlyhtxiNKY0e3aX4xdCMH: No such file or directory
/var/lib/cloud/instance/scripts/part-001: line 12: QSrBLBIHLlpapkl/bvWk1xkSPEPNkNHbTvBd+3z2iWtxANEqO6ARItCCI+DcGyWP: No such file or directory
/var/lib/cloud/instance/scripts/part-001: line 13: W1FIwwKFBftNQAgxfs2pxdSnqpoaHSi4M9XjY7r7bADUItf9zpAy+PbqJr+F3Bzc: command not found

It seems that each line in file is interpreted as a command, which is not I’ve intended.

The code in userdata.sh that caused the problem is as below.

echo $conf_tls_private_key | sudo tee "/etc/pki/tls/boundary/boundary.key"

Is there anything I’m unaware of or anything I can fix this problem? Thanks a lot !

Hi! If I’m not mistaken, this is the part of your command that is causing the problem. If you want the contents of the environment variable to be stored in the key file, you should execute this instead:

echo $conf_tls_private_key > /etc/pki/tls/boundary/boundary.key

(If the account doesn’t have sufficient privileges to create that file, then prepend this command with sudo.)

The command from your post sends the contents of the environment variable to tee, which then writes it to the key file, but also writes it to standard output (stdout), which the shell is then interpreting as a series of commands.

man tee for more information. (It’s normally used when you want to output some information for the person who is running your script, but also want to capture that information in a log file.

Hope that helps!

This seems like a quoting problem in your script causing the shell to understand the key as something to be executed rather than as data. Can you share the contents of your template too? I expect adding some extra quoting and escaping there will help make this work.

1 Like