Terraform fails to import key pair with Amazon EC2

The error says that key pair already exists in AWS, and it does not say whether it was created using Terraform or using console.

You should see it in AWS console EC2 -> Key Pairs for correct region. You should delete it using console before retrying import it using Terraform.


The error is telling you that the keypair already exists in your AWS account but Terraform has no knowledge of it in its state files so is attempting to create it each time.

You have two options available to you here. Firstly, you could simply delete it from the AWS account and allow Terraform to upload it and thus allow it to be managed by Terraform and be in its state files.

Alternatively you could use the Terraform import command to import the pre-existing resource into your state file:

terraform import aws_key_pair.personal mschuchard-us-east

Use the ${uuid()} function to always get a random id for key pairs when generating, the selected/generated UUID makes it into the state file, so you will still be able to delete, but updating will not be possible. Every time you apply your terraform file there will be a new keypair generated...

While it is true that you can not generate a key pair from scratch using the AWS provider, you can generate a new key pair object in AWS using an RSA private key that the TLS provider generates.

resource "aws_key_pair" "test" {
    key_name   = "${uuid()}"
    public_key = "${tls_private_key.t.public_key_openssh}"
}
provider "tls" {}
resource "tls_private_key" "t" {
    algorithm = "RSA"
}
provider "local" {}
resource "local_file" "key" {
    content  = "${tls_private_key.t.private_key_pem}"
    filename = "id_rsa"
    provisioner "local-exec" {
        command = "chmod 600 id_rsa"
    }
}

Use the tls provider to generate a key, and import it as a new object every time. Then export the private key so that you have it for access to the server(s) later on.

It is worthy to note that this breaks one of the paradigms that Terraform is attempting to use (infrastructure as code), but from a practical development standpoint that might be a bit too idealistic... Terraform builds fail midway through and states get invalidated. A better solution might be if the AWS plugin received an "already exists" error it imported automatically, or if that was an optional behavior that could be set.