EC2 SSH key pairs are fundamentally just public/private key cryptography. You give AWS your public key, they store it, and when you try to SSH in with your private key, they verify you. The problem is, AWS doesn’t let you replace an existing public key associated with an EC2 instance’s key pair. You can only add new key pairs or remove existing ones.
This means you can’t just "rotate" the key pair in place. You have to effectively swap it out.
Here’s the most common way to do it, and why it’s not as straightforward as you’d think:
The "Replace" Method (Which Isn’t Really Replacing)
The core idea is to associate a new key pair with your instance, and then remove the old one.
Step 1: Create a New Key Pair
First, generate a new SSH key pair.
ssh-keygen -t ed25519 -f ~/.ssh/my-new-instance-key
This creates my-new-instance-key (private key) and my-new-instance-key.pub (public key). Crucially, keep your private key safe and don’t lose it!
Step 2: Add the New Public Key to the Instance
This is where it gets tricky. You can’t directly "update" the key pair associated with an instance through the AWS console or API. You have to do it from within the instance itself.
-
SSH into your instance using your current key pair.
-
Add the new public key to the
~/.ssh/authorized_keysfile on the instance.First, copy the content of your new public key:
cat ~/.ssh/my-new-instance-key.pubThen, SSH into your instance and append it to the
authorized_keysfile:# On your EC2 instance echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC... your_new_public_key_content_here ... user@host" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys # Ensure correct permissions
Step 3: Test the New Key
Before you remove the old key, open a new terminal window and try to SSH into your instance using your new private key.
ssh -i ~/.ssh/my-new-instance-key ec2-user@your_instance_public_ip
If this works, you have successfully added the new key and can now proceed. If it doesn’t, troubleshoot the authorized_keys file and permissions on the instance.
Step 4: Remove the Old Public Key from the Instance
Once you’ve confirmed the new key works, you need to remove the old public key from the ~/.ssh/authorized_keys file on the instance. You can do this by SSHing in with the new key (or the old one, if you haven’t removed it yet) and editing the file.
For example, if you used sed to remove a specific line (replace your_old_public_key_content_here with the actual content of your old public key):
# On your EC2 instance
sed -i '/ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... your_old_public_key_content_here ... user@host/d' ~/.ssh/authorized_keys
Step 5: Remove the Old Key Pair from your AWS Account
Now, go to the AWS EC2 console -> Key Pairs. Select your old key pair and click "Actions" -> "Delete".
Why This Isn’t a True "Rotation"
The above process is a workaround. You’re not replacing the key pair associated with the instance in the AWS infrastructure. Instead, you’re manually managing the authorized_keys file on the instance itself. AWS only knows about the key pairs you’ve registered with it.
Common Pitfalls and Why They Happen
- Losing Access After Deleting the Old Key Pair: This is the most common disaster. It happens if you delete the old key pair from your AWS account before successfully testing and confirming access with the new key pair. The AWS infrastructure still trusts the old key for authentication as long as it’s registered. Once unregistered, only keys in
authorized_keyswork. - Typos in
authorized_keys: A single misplaced character, an extra space, or an incorrect newline can render the key unusable. Thechmod 600is critical; if it’s not set, SSH will often refuse to use theauthorized_keysfile for security reasons. - Incorrect Permissions on
.sshDirectory: The~/.sshdirectory itself should have permissions700(drwx------). If it’s too open, SSH will ignoreauthorized_keys. - Using the Wrong Private Key: When testing, ensuring you specify the new private key with
ssh -iis paramount. If you forget-i,sshwill try its default locations, which might still be your old key. - Forgetting to Add the Public Key: You might SSH in, edit
authorized_keys, but then forget to actually paste the public key content into the file. - Instance Metadata vs.
authorized_keys: AWS EC2 instances, by default, pull the public keys registered in the key pair and inject them into the~/.ssh/authorized_keysfile on first boot or when an instance is launched from a fresh AMI. However, once the instance is running, changes to the key pair association in AWS don’t automatically update theauthorized_keysfile. You are managing the file directly.
A More Robust (But More Complex) Approach: Instance Connect
For newer EC2 instances (launched from Amazon Linux 2023, Amazon Linux 2, or Ubuntu 20.04/22.04 AMIs with the latest SSM Agent and EC2 Instance Connect installed), you can use EC2 Instance Connect. This service allows you to push temporary SSH public keys to your instances without modifying authorized_keys directly.
-
Install EC2 Instance Connect Agent: Ensure it’s installed on your instance.
-
Use the
ec2-instance-connectCLI:# Make sure you have your new private key ready and its public key content aws ec2-instance-connect send-ssh-public-key \ --instance-id i-0123456789abcdef0 \ --instance-os-user ec2-user \ --ssh-public-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC... your_new_public_key_content_here ... user@host" \ --availability-zone us-east-1aThis pushes your public key for a short duration. You can then SSH with your private key. Once the temporary key expires, you’re effectively locked out unless you use the new key pair method described above or re-push a key.
The Next Hurdle: Managing SSH Keys at Scale
Once you’ve mastered rotating keys for a single instance, you’ll quickly realize that doing this manually for dozens or hundreds of instances is a nightmare. This leads to exploring configuration management tools like Ansible, Chef, or Puppet, or leveraging AWS Systems Manager Parameter Store and Run Command to automate the distribution and removal of SSH keys.