Consul-Template secret parameter with spaces

I’m trying to get SSH host signing working with Vault and Consul-Template. The template file for Consul-Template looks like:

{{ $contents := file "/etc/ssh/ssh_host_rsa_key.pub" }}{{ with secret "ssh-host/sign/ssh.host.linux" "cert_type=host" "public_key=$contents" }}{{ .Data.signed_key }}{{ end }}

The SSH public key file looks like (note this is an example key for a test VM):

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxE3HPu3ZejCJyhYM/da0jIlTKjVlsXEczaiUOrrrr9QPi0InCuU3tZEBSxZ5Xa6bG0iNb/FNEhhPztxgmD9hM7h+54r7fWbW4Zbk3HJFfWeym+EnAzmDx28ImY07XKlTrCok/qV9SrLm+cjt459wzJSAUsTBS2t+D2OnFlVPoM0NKorgO9tepHpMWL9ylG4Xt3M8NtxE0kZksVVv8iuynEeLdzogQbVc+rIU+Xomw5NUxmENJ/8pGFa3WsZnxdbmURlXzCoHAUwLO3Rd1C8LElBNh963mMF1mSx99WqkVDmiaVamtnqRjU3e/YYrr1T9NzT4yGywKiasTUKooTFi9 root@ubuntu-18-04-3

When Consul-Template tries to execute the template it fails, however when I do this manually it works. I suspect that it is not passing on the contents as a single string but doing something with it.

Is there any way of finding out exactly what it is sending to Vault or even better is there a way to make the Consul-Template pass the contents of the key file to Vault for signing?

It turns out that Consul-Template does not process variables inside the key-value pair inside quotes. However if you do the following it will work

{{ $contents := file "/etc/ssh/ssh_host_rsa_key.pub" | trimSpace }}{{ $pair := printf "public_key=%s" $contents }}{{ with secret "ssh-host/sign/ssh.host.linux" "cert_type=host" $pair }}{{ .Data.signed_key }}{{ end }}

Note that here we create a key-value pair string by using printf which is processed correctly

Hey I tried your example; but for some reason vault always returns:

URL: PUT http://127.0.0.1:8300/v1/ssh/sign/my-role
Code: 400. Errors:

* missing public_key (retry attempt 1 after "250ms")

The template I used was:

template {
  contents = <<-EOF
  {{ $contents := file "/home/arian/.ssh/id_rsa.pub" | trimSpace }}{{ $pair := printf "public_key=%s" $contents }}{{ with secret "ssh/sign/my-role" $pair "cert_type=user" }}{{ .Data.signed_key }}{{ end }}
  {{ $contents }}
  EOF
  destination = "blah.crt"
}

How do you make public_key read from a file? I couldn’t get it working

Self-answer. Turns out this is a fluke-error due to consul-template doing a multi-phase execution. The template itself renders fine