Terraform-provider-aws: aws_key_pair forces new resource after importing

Created on 10 Jul 2017  ·  9Comments  ·  Source: hashicorp/terraform-provider-aws

Terraform Version

Terraform v0.9.11

Affected Resource(s)

  • aws_key_pair

Terraform Configuration Files

resource "aws_key_pair" "igor" {
  key_name = "igor_20150712"
  public_key = "${file("igor_20150712.pub")}"
}

Expected Behavior

After using terraform import aws_key_pair.igor igor_20150712 I would have expected a terraform plan to not result in any changes.

Actual Behavior

Got

-/+ aws_key_pair.igor
    fingerprint: "REDACTED" => "<computed>"
    key_name:    "igor_20150712" => "igor_20150712"
    public_key:  "" => "ssh-rsa AAAAREDACTED" (forces new resource)

Steps to Reproduce

  1. terraform import aws_key_pair.igor
  2. terraform plan -target aws_key_pair.igor

Workaround

Manually adding a public_key section into terraform.tfstate. Changing:

"attributes": {
    "fingerprint": "REDACTED",
    "id": "igor_20150712",
    "key_name": "igor_20150712"
},

to

"attributes": {
    "fingerprint": "REDACTED",
    "id": "igor_20150712",
    "key_name": "igor_20150712",
    "public_key": "ssh-rsa AAAAREDACTED"
},

resulted in no changes detected in the next terraform plan.

bug servicec2

Most helpful comment

@Ninir, I understand the reason for why it doesn't currently work as advertised.

Four options are possible:

  1. make terraform import accept an attribute for public key ... ex. terraform import aws_key_pair.igor igor_20150712 igor_20150712.pub, which populates the value of the public key in the terraform.tfstate file
  2. mention this problem in the docs https://www.terraform.io/docs/providers/aws/r/key_pair.html ... still says nothing about needing to manually change the terraform.tfstate file and adding public_key yourself
  3. remove the possibility to import aws_key_pair ... rather not do this one
  4. leave it as is, with a mention in the docs that this will result in the key pair being destroyed and recreated

As it stands right now if you want to import it at the moment, manually changing terraform.tfstate is your only way to go, without destroying and recreating the resource.

All 9 comments

I don't believe AWS exposes the public_key via their API calls. I suppose an instance could be launched and then the key retrieved but I suspect that is out of scope at the moment. Plus it would be strictly better if AWS exposed this information.

Hey folks,

As @recurrence exposed it, the public_key attribute isn't returned by AWS. Terraform simply trims the key for normalization, but the attribute is set in the state and never set again, excepted when the user attribute changes.

@iserko As AWS does not provide this information when using the API, there is nothing Terraform can help on that... 😞
If you import your configuration, you should set your public_key manually. In order to retrieve it, you can still generate it from you private key, or connect to an instance and get it again... 🤷‍♂️

Do you mind me closing this issue?

Thanks!

@Ninir, I understand the reason for why it doesn't currently work as advertised.

Four options are possible:

  1. make terraform import accept an attribute for public key ... ex. terraform import aws_key_pair.igor igor_20150712 igor_20150712.pub, which populates the value of the public key in the terraform.tfstate file
  2. mention this problem in the docs https://www.terraform.io/docs/providers/aws/r/key_pair.html ... still says nothing about needing to manually change the terraform.tfstate file and adding public_key yourself
  3. remove the possibility to import aws_key_pair ... rather not do this one
  4. leave it as is, with a mention in the docs that this will result in the key pair being destroyed and recreated

As it stands right now if you want to import it at the moment, manually changing terraform.tfstate is your only way to go, without destroying and recreating the resource.

+1 to 1! I suppose this breaks with the current form of the import statement but taking a secondary argument is a natural progression. That would save the manual state edit while waiting for AWS to return it.

@Ninir I think we may be able to get around this by using a custom import method that simply sets public_key to "", what do think?

@iserko
My workaround to this was to put the pub key directly in the "public_key" directive as "ssh-rsa..." and it worked as expected. Also be careful when referencing to this object as its not the key.id but the key.name thing you should reference to in your script.

Hi folks,

Circling back to that, editing the state is the only viable solution for now. I created a PR to expose that.
Augmenting the import command is not something I am aware of and would require a lot of thoughts to make it right, especially since this is part of the Terraform core.

I hope documenting this edge case is enough. Let me know!

If there is a safe character delimiter we can use, we can optionally allow the import ID to contain both the key name and public key, e.g. with a comma (,) delimiter

$ terraform import aws_key_pair.example 'example,ssh-rsa AAAA...ZZZ== [email protected]'

Then in the import code it can check for the delimiter to perform either a combined import or fallback to the old behavior of just a key name import. 😄

Wouldn't the _fingerprint_ be the more correct way to match a remote key with local state?

Was this page helpful?
0 / 5 - 0 ratings