Upload Public Key On this page Introduction# The playbook will upload a key pair from your local machine to AWS account using Ansible. We will use the amazon.aws.ec2_key module. You should have the AWS permissions to import key pairs.
Create the Ansible Playbook# Create a file called upload_key.yml
in the ansible/experiments
directory.
1 ---
2 - name : Upload a key to AWS
3 hosts : localhost
4 gather_facts : false
5 vars :
6 local_pem_path : "/path/to/file.pem" # Update this path to your PEM file
7 key_name : "RailsKey" # Name for the key pair in AWS
8
9 tasks :
10 - name : Read local key file
11 ansible.builtin.slurp :
12 src : "{{ local_pem_path }}"
13 register : pem_file
14
15 - name : Convert key to base64
16 ansible.builtin.set_fact :
17 key_content : "{{ pem_file['content'] | b64decode }}"
18
19 - name : Upload key pair to AWS
20 amazon.aws.ec2_key :
21 name : "{{ key_name }}"
22 key_material : "{{ key_content }}"
23 state : present
Check File Permission# Check PEM file has the correct permission:
-rw-------@ 1 bparanj staff 1674 Mar 24 12:14 /path/to/file.pem
Run the Playbook# Copy the path to your PEM file to the line number 6 in upload_key.yml
playbook .
From the project root, run the playbook:
$ ansible-playbook -i hosts experiments/upload_key.yml
Trouble Shooting Issues# Connection Failure# PLAY [ Upload a key to AWS]
TASK [ Read local key file]
fatal: [ localhost] : UNREACHABLE! = > { "changed" : false, "msg" : "Failed to connect to the host via ssh: ssh: connect to host localhost port 22: Connection refused" , "unreachable" : true}
PLAY RECAP
localhost : ok = 0 changed = 0 unreachable = 1 failed = 0 skipped = 0 rescued = 0 ignored = 0
Set connection to local:
---
- name : Upload a key to AWS
hosts : localhost
gather_facts : false
connection : local
Key Length Issue# Error due to maximum length allowed for the key:
TASK [ Upload key pair to AWS]
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: Ec2KeyFailure: An error occurred ( InvalidParameterValue) when calling the ImportKeyPair operation: Value for parameter PublicKeyMaterial is invalid. Length exceeds maximum of 2048.
fatal: [ localhost] : FAILED! = > { "boto3_version" : "1.34.69" , "botocore_version" : "1.34.69" , "changed" : false, "msg" : "An error occurred (InvalidParameterValue) when calling the ImportKeyPair operation: Value for parameter PublicKeyMaterial is invalid. Length exceeds maximum of 2048.: error importing key" }
PLAY RECAP
localhost : ok = 2 changed = 0 unreachable = 0 failed = 1 skipped = 0 rescued = 0 ignored = 0
It looks like this:
-----BEGIN RSA PRIVATE KEY-----
Multiple lines of string
-----END RSA PRIVATE KEY-----%
We need to extract the public key from the PEM file.
ssh-keygen -y -f /path/to/file.pem > /path/to/file.pub
It looks like this:
ssh-rsa smallerstrings goes here
Revised Playbook# Modify the playbook to upload the public key:
---
- name : Upload a key to AWS
hosts : localhost
gather_facts : false
connection : local
vars :
key_name : "RailsKey" # Name for the key pair in AWS
tasks :
- name : Read public key file
ansible.builtin.slurp :
src : "/path/to/key.pub" # Update this path to your public key file
register : public_key_file
- name : Convert public key to string
ansible.builtin.set_fact :
public_key_content : "{{ public_key_file['content'] | b64decode }}"
- name : Upload public key pair to AWS
amazon.aws.ec2_key :
name : "{{ key_name }}"
key_material : "{{ public_key_content }}"
state : present
Verify the Key# You can view the uploaded key in your AWS console. Go to EC2 dashboard, pick the region used by the playbook and select Key Pairs under Network and Security. If you don’t see it, check the account used by the playbook:
aws sts get-caller-identity
The account ID displayed in the output should match the Account ID shown in your profile of the AWS console.
Using Python SDK# This playbook is useful for learning purposes. The same task is now done by the boto3 Python SDK project . The reason is that we create a key pair and assign it to the instance when it is created. Packer creates a temporary key pair when creating a custom AMI and it deletes it when it is done. So, if you are using Packer, then this is automatically take care of for you.