Terraform: Failed to read key for aws_instance ssh provisioner

Created on 10 Oct 2016  ยท  17Comments  ยท  Source: hashicorp/terraform

I have just upgraded from terraform 0.6.x to 0.7.x and suddenly Terraform has issues with SSH provisioner key_file. Details below. Help, please.

Terraform Version

$ terraform -v
Terraform v0.7.5

Affected Resource(s)

  • aws_instance ssh provisioner

    Terraform Configuration Files

Only the relevant parts.
This is now I define my var.provisioner map:

variable "provisioner" {
  type = "map"
  default = {
    username  = "centos"
    key_name  = "my-key-file"
    directory = "/home/centos/provision"
  }
}

and this is how I use it awith aws_instance:

resource "aws_instance" "consensus" {
...
  connection {
    user = "${var.provisioner["username"]}"
    key_file = "${path.module}/keys/${var.provisioner["key_name"]}.pem"
  }
...
}

Debug Output

Debug output does not show anything relevant.

Expected Behavior

SSH provisioner uses the existing PEM file to provision an instance.

Actual Behavior

Error applying plan:

1 error(s) occurred:

* Failed to read key "[full-path-to-the-file]/my-key-file.pem": no key found

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Yet:

$ stat [full-path-to-the-file]/my-key-file.pem
16777220 9791590 -rw------- 1 rad staff 0 1692 "Oct 10 15:38:49 2016" "Sep 14 16:37:08 2016" "Sep 14 16:37:08 2016" "Sep 14 16:37:08 2016" 4096 8 0 [full-path-to-the-file]/my-key-file.pem

Steps to Reproduce

  1. terraform apply

Every single time.

Important Factoids

Just upgraded from 0.6.x to 0.7.x, changed how I access my maps, from . notation to ["..."]

bug core

Most helpful comment

If you don't have the private/public keys in variables you'll need to quote them.

# e.g.
public_key = "${file("ssh/insecure-deployer.pub")}"
# or
private_key = "${file("ssh/insecure-deployer")}"

All 17 comments

I tried with connection.private_key instead of connection.key_file. Same error. The file exists but Terraform claims is can't read the file.

aws_instance.consensus.0: Provisioning with 'remote-exec'...
Error applying plan:

1 error(s) occurred:

* Failed to read key "[full-path-to-the-file]/my-key-file.pem": no key found

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Hi @radekg,

The key_file argument is deprecated, and you should use the private_key argument:

private_key - The contents of an SSH key to use for the connection. These can be loaded from a file on disk using the file() interpolation function. This takes preference over the password if provided.

Both of those however expect the key value directly, which you can get with the file(path) interpolation function.

Feel free to comment to reopen this if you are still have trouble with the configuration.

Thanks!

@jbardin Thanks for closing the issue, however, the problem does not magically resolve itself. Just FYI, you say that key_file expects the key material directly. Well, is this a changed behavior on a deprecated property? That's shite. Because in 0.6.x it worked just with a path.

I used the private_key but... how do I interpolate this?

"${path.module}/keys/${var.provisioner["key_name"]}.pem"

Trying this

 "${file("${path.module}/keys/${var.provisioner["key_name"]}.pem")}"

returns

Error loading config: Error parsing .../main.tf: At 256:14: expected: IDENT | STRING | ASSIGN | LBRACE got: SU

@radekg, Sorry, I did forget that the key_file also took a direct file path.

That file() interpolation looks like it should work. I'll open this back up for investigation.

What I can't understand is why would the property be deprecated AND its behavior changed? Surely, if it's deprecated, don't break it? Give me a slight chance to migrate?

I apologize that this is causing a problem, any undocumented change in behavior was not intended. We're looking into the issue now.

As for the issue with using the file() interpolation function, do you have an example of a config that causes that error? The interpolation looks correct, so I'm suspecting there's another problem in the configuration.

I'll put it in secret gist shortly. Any chance I can share the link with you offline?

Feel free to email me at my username at hashicorp.com

I wrote a .tf file last week and it worked with v0.7.5 and the key_file variable. today it stopped as I destroyed and applied my .tf
I've changed key_file to private_key and I still get the error.
Failed to read key "xxxxxx": no key found

same as 'nungster' destroyed a instance that used key_file and ran into this problem when making new. 0.7.5. Actually destroyed everything (blank state) and got this error.

replaced: key_file = "${var.private_key_path}"
with: private_key = "${file(var.private_key_path)}"

and it is working again with 0.7.5

If you don't have the private/public keys in variables you'll need to quote them.

# e.g.
public_key = "${file("ssh/insecure-deployer.pub")}"
# or
private_key = "${file("ssh/insecure-deployer")}"

@codesoda it seems the interpolation of variables inside of the "${file("...")}" does not work though.

Hi @radekg,

Did you have an example that shows variables not interpolating inside the file function? I'm not able to reproduce that here.

We have to apologize about the initial confusion about key_file, and poor handling of the deprecation there. The key_file and bastion_key_file argument were deprecated last year during the 0.6.x cycle. Recently there was a patch that broke some of the legacy behavior of those arguments, which should have also removed the 2 fields and their documentation.

These 2 arguments will be officially removed in the next release.

@radekg, if you still have an issue with interpolation in the file function, we can open a new issue specifically for that.

On terraform 0.12.17
I had this issue with my private/public key (generated by puttygen ssh2-rsa)
I solved it by changing my key with : ssh-gen -o (linux openssh)

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