Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to read key for aws_instance ssh provisioner #9308

Closed
radekg opened this issue Oct 10, 2016 · 17 comments
Closed

Failed to read key for aws_instance ssh provisioner #9308

radekg opened this issue Oct 10, 2016 · 17 comments

Comments

@radekg
Copy link

radekg commented Oct 10, 2016

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 ["..."]

@radekg
Copy link
Author

radekg commented Oct 10, 2016

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.

@jbardin
Copy link
Member

jbardin commented Oct 10, 2016

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 jbardin closed this as completed Oct 10, 2016
@radekg
Copy link
Author

radekg commented Oct 10, 2016

@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

@jbardin
Copy link
Member

jbardin commented Oct 10, 2016

@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.

@radekg
Copy link
Author

radekg commented Oct 10, 2016

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?

@jbardin
Copy link
Member

jbardin commented Oct 10, 2016

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.

@radekg
Copy link
Author

radekg commented Oct 10, 2016

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

@jbardin
Copy link
Member

jbardin commented Oct 10, 2016

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

@nungster
Copy link

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

@ghost
Copy link

ghost commented Oct 11, 2016

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.

@ghost
Copy link

ghost commented Oct 11, 2016

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

and it is working again with 0.7.5

@codesoda
Copy link

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")}"

@radekg
Copy link
Author

radekg commented Oct 11, 2016

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

@jbardin
Copy link
Member

jbardin commented Oct 12, 2016

Hi @radekg,

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

@jbardin
Copy link
Member

jbardin commented Oct 14, 2016

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.

@cricri777
Copy link

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)

@ghost
Copy link

ghost commented Dec 13, 2019

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.

@ghost ghost locked and limited conversation to collaborators Dec 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants