AWS: manage ssh keys from the cli

Using aws cli to manage ssh keys for your ec2 instances is a programmatic way faster than using the Web Interface and can also be used in…

AWS: manage ssh keys from the cli
Photo by Aaron Burden on Unsplash

Using aws cli to manage ssh keys for your ec2 instances is a programmatic way faster than using the Web Interface and can also be used in scripts that have to do with the automation of ec2 resources, in this article we will cover the essential commands used to create, import, list and delete keys before we start this article assumes that following steps have been completed

  • aws cli is installed (How to install aws cli)
  • aws cli is configured (How to configure aws cli)
  • IAM permissions, ensure that your user has the following permissions to manage ec2 keys ec2:DescribeKeyPairs, ec2:CreateKeyPair, ec2:DeleteKeyPair, and ec2:ImportKeyPair

Create a new key pair

The following command will generate a private key and, at the same time will import the public key into AWS to be used with ec2 instances.

aws ec2 create-key-pair \ 
        --key-name MyKeyPair \ 
        --query 'KeyMaterial' \ 
        --output text > MyKeyPair.pem
  • Replace MyKeyPair with your desired key name
  • --query 'KeyMaterial' print on stdout only the private key
  • --output text plain text output

One important step here is to tight up key permissions

chmod 400 MyKeyPair.pem

Since the command is very long you can create a function to add to your ~/.bashrc file to simplify the creation of keys

awsck() { 
    if [ "$#" -ne 2 ]; then 
        echo "Usage: awsck <key-name> <path-to-save-private-key>" 
        return 1 
    fi 
 
    local key_name=$1 
    local private_key_path=$2 
 
    # Check if the file already exists 
    if [ -e "$private_key_path" ]; then 
        echo "Error: The file '$private_key_path' already exists." 
        return 1 
    fi 
 
    # Generate the key pair 
    aws ec2 create-key-pair --key-name "$key_name" --query 'KeyMaterial' --output text > "$private_key_path" 
 
    if [ $? -ne 0 ]; then 
        echo "Error: Failed to create key pair." 
        return 1 
    fi 
 
    # Set permissions for the private key 
    chmod 400 "$private_key_path" 
 
    echo "Key pair '$key_name' created and saved to '$private_key_path'." 
}

This function does the following to help and protect the user

  • if the filename of the ssh key exists the function exits with an error
  • sets the correct rights to the key

The final step to enable this function is to use source to reload .bashrc file

source ~/.bashrc

Then you can use this function like this, first parameter will be the name of the key pair and the second one the path that the private key saved

awsck mykey ~/aws/ec2/mykey 
Key pair 'mykey' created and saved to '/Users/kpatronas/aws/ec2/mykey'.

Import an existing public key

If you already have generated keys with ssh-keygen you might want to use them, to do this we need to import the public key first with the following command

aws ec2 import-key-pair \ 
         --key-name MyImportedKeyPair \ 
         --public-key-material fileb://~/.ssh/id_rsa.pub
  • MyImportedKeyPair , replace with the desired name
  • fileb://~/.ssh/id_rsa.pub path to the public key, adjust the path if the key is somewhere else

I do not use an alias here since this command will used rarely and the command is quite safe, will not let you use twice the key-name value so you cannot overwrite a public key.

List key pairs

To list inserted keys in aws use the following command

aws ec2 describe-key-pairs --query 'KeyPairs[*].[KeyName,CreateTime]' --output text | column -t 
 
MyKey      2024-09-14T19:25:07.087000+00:00 
MyKeyPair  2024-09-14T18:36:50.611000+00:00
  • KeyPairs[*].[KeyName,CreateTime]' outputs per line the Key name and the creation time of the key
  • column -t is a Linux tool that allows to print lines in columnar format

Since the line is too long and you will use it often a nice idea is to create an alias for the command in your ~/.bashrc file

alias awslk="aws ec2 describe-key-pairs --query 'KeyPairs[*].[KeyName,CreateTime]' --output text | column -t"

Then after using source to reload .bashrc file we can use this alias as a normal command

$ awslk 
key2               2024-09-16T21:53:29.332000+00:00 
MyImportedKeyPair  2024-09-16T22:01:08.839000+00:00 
key1               2024-09-16T21:51:21.280000+00:00 
MyKey              2024-09-14T19:25:07.087000+00:00 
MyKey3             2024-09-16T22:12:58.110000+00:00 
MyKey4             2024-09-16T22:13:07.167000+00:00 
MyKeyPair          2024-09-14T18:36:50.611000+00:00

Delete key pairs

To delete a key pair use the following command, note that this command does not physically delete any public or private keys from the host is running but only removes the public key from aws

aws ec2 delete-key-pair --key-name MyKeyPair
  • MyKeyPair the pair name to be deleted

I don't recommend the usage of an alias for this command, is better to have a long command that will get you to second thoughts while typing it!

List key pairs associated with ec2 instances

One common task is to find ec2 instances and their corresponding keys, to do this we use the following command

aws ec2 describe-instances \ 
--query 'Reservations[*].Instances[*].{InstanceId:InstanceId,KeyName:KeyName}' --output text 
 
i-0f2a561b743bf630e MyKeyPair 
i-06c401b243d9730d0 MyKeyPair

Since this command will be used quite often I recommend using an alias, insert this to ~/.bashrc and reload it using source ~/.bashrc

alias awsec2lk="aws ec2 describe-instances --query 'Reservations[*].Instances[*].{InstanceId:InstanceId,KeyName:KeyName}' --output text"

Then you can use the alias as a normal command

awsec2lk 
i-0f2a561b743bf630e MyKeyPair 
i-06c401b243d9730d0 MyKeyPair

How to ssh an ec2 instance using the key

By default, ssh uses the key in ~/.ssh/id_rsa you can add custom configurations per IP or hostname in ssh_config and define the key to be used, but if you don't want to do this and you want just to pass the key file in the command line you can use the following command

ssh -i MyKeyPair.pem ec2-user@<EC2-Instance-Public-IP>
  • MyKeyPair.pem is the filename of the private key assigned to the host
  • ec2-user the default user for Amazon Linux

Conclusion

In this article, we saw how we can manage ssh keys in aws, and also we saw some handy aliases and functions to be used while managing ssh keys in aws, I hope this article made managing ssh keys in aws a bit easier!