One of the parameters required for launching an EC2 instance is a Key Pair which is effectively an SSH Key used for interactive logging into the default user account – on Amazon Linux it’s the ec-user account – or for decrypting the Windows Administrator’s password.

It is easy to create a new Key Pair / SSH Key as part of the EC2 launch process however as soon as you start using more regions and more accounts you will quickly end up with heaps of stored SSH Keys and unless you are diligent with their naming both on the filesystem an in AWS you’ll end up with a mess. Like I did.

Fortunately there is a way to re-use an existing Key Pair in other regions or even other accounts. And it’s actually pretty easy.

Before we start I assume you’ve got an existing Key Pair or SSH Key, either created by Amazon or your own usual SSH Key created using ssh-keygen. Either will work. Let’s say it’s saved as ~/.ssh/michael.ludvig-key.pem

Importing existing Key Pair

To import this key to a new region go to Services ➞ EC2 ➞ Key Pairs and click Import Key Pair.

sshkey1

Key pair name must be unique within the region (i.e. you can’t have two different keys with the same name) but you should keep it the same between all the regions. Keeping it consistent across regions greatly simplifies your automation – you won’t need a per-region key name mapping.

Now the Public key contents – that’s the part that took me a while to figure out because as of now Amazon provides misleading information both online and in the aws-cli help. The format of the public key must be in RFC4716 format, not in the openssh format starting with ssh-rsa AAAAB3… format that’s suggested by Amazon’s docs yet rejected by the import tool. Convert any of your SSH keys to RFC4716 with this command:

~ $ ssh-keygen -e -m RFC4716 -f ~/.ssh/michael.ludvig-key.pem
Enter passphrase: ****
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "2048-bit RSA, converted by michael.ludvig@aws.nz from OpenS"
AAAAB3NzaC1yc2EAAAADAQABAAABAQC3Y5e3oNnxHXZAAPMHjlxuzhXnqt+3q2FC0pEsrP
HdF3HZskjKlFIjW83iBPcAsMi3sf0CGnFvcP0U9o6MAXHhLtKIEjmybAfNP/AJ+qfyE+0k
q4Ui3xIVFDueQqFeYPqv+NnJ7EB2IGH6+4mPQcbw7yIsnKNlckv973ugjs31U9ToUIpZVy
zubpPARjTBALyKj5vAWGRsylo9h6WT62mLFM/JyCHdvchmRb9x9eSxe34iWZZ8hnTF7Lu+
9RxTR1zR87JY4D8w5vFQMXyjj/6p2xRyTwwCHVcU92mxARi4ipjH27uM8SpVjXxGISBa2m
i2HkhsWtDA6JIkd1qpogtj
---- END SSH2 PUBLIC KEY ----

Using the same command you can also convert your public keys (e.g. ~/.ssh/id_rsa.pub) to this format and import them to Amazon.

Now simply copy and paste the output including the BEGIN end END lines and click Import.

sshkey2

You will see it’s successfully imported with a Fingerprint displayed:

sshkey3

Importing with AWS-CLI

The key can also be imported from the command line using aws-cli. It’s a two-step process, first save the public key to a file. Note the pub extension, don’t overwrite your pem key!

~ $ ssh-keygen -e -m RFC4716 -f ~/.ssh/michael.ludvig-key.pem > michael.ludvig-key.pub

And then import it:

~ $ aws --region=xy-abcd-1 ec2 import-key-pair --key-name=michael.ludvig-key --public-key-material=file://michael.ludvig-key.pub
{
  "KeyName": "michael.ludvig-key",
  "KeyFingerprint": "ab:9c:38:ef:4b:99:1e:b1:f6:60:e6:fe:a5:fc:10:fa"
}

Obviously the KeyFingerprint should be the same as with the GUI import.

If the provided file was in a wrong format you will receive an error:

A client error (InvalidKey.Format) occurred when calling the ImportKeyPair operation: Key is not in valid OpenSSH public key format

Importing to all regions

With a simple for loop over the list of regions it’s easy to import the key into all available regions in a few seconds. Grab the regions.txt file from my GitHub aws-utils project.

~ $ for REGION in $(curl https://raw.githubusercontent.com/mludvig/aws-utils/master/regions.txt); do
        echo "== ${REGION} =="
        aws --region=${REGION} ec2 import-key-pair --key-name=... --public-key-material=...
done

That’s it. This way you can get away with just one SSH Key for all your AWS endeavours 🙂