Ansible SSH Connection to EC2

Introduction

This article will show you how to establish SSH connection to an EC2 instance using Ansible. The playbook will run the command lsb_release -a on the EC2 instance and print the output. You must have a running EC2 instance with a key pair setup properly.

Boto3 Python Library

I extended the code from the Managing EC2 and VPC: AWS with Python and Boto3 Series video course by Niyazi Erdogan. You can download the source code from boto3 project. This does not have any error handling and it is not idempotent. For experimentation and learning purposes, this is good enough.

test_deployment.py
    ec2 = EC2(ec2_client)
    # Create a key pair
    key_pair_name = "Boto3-KeyPair"
    key_pair_response = ec2.create_key_pair(key_pair_name)

    print('Created key pair ' + key_pair_name + ' : ' + str(key_pair_response))

    # Extract the KeyMaterial, which is the private key
    key_material = key_pair_response['KeyMaterial']

    # Define the file name for the private key
    key_file_name = f"{key_pair_name}.pem"

    # Save the private key to a .pem file
    with open(key_file_name, 'w') as key_file:
        key_file.write(key_material)

    # Set the file's permissions to read-only for the file owner
    os.chmod(key_file_name, 0o400)

    print(f"Key pair saved to {key_file_name} with read-only permissions for the file owner.")

This will create a key pair called Boto3-KeyPair in your AWS account and save the private key to a file called Boto3-KeyPair.pem on your local machine. You will use this key in the Ansible playbook to connect to the EC2 instance.

Connection Playbook

In the project root directory, create the connection.yml playbook with the following contents:

connection.yml
---
- name: Run tasks on EC2 instance
  hosts: all
  tasks:
    - name: Run command on the EC2 instance
      command: lsb_release -a
      register: lsb_release_output

    - name: Print the command output
      debug:
        msg: "{{ lsb_release_output.stdout_lines }}"

Ansible Inventory File

In the project root directory, create the inventory.ini file:

inventory.ini
[ec2_instances]
3.237.186.53 ansible_user=ubuntu ansible_ssh_private_key_file=/path/to/key.pem

Replace the IP 3.237.186.53 with your EC2 instance public IP. Replace the value for ansible_ssh_private_key_file with the path to your key pair file on your local machine.

Run the Playbook

From the project root directory, run the playbook:

Ansible Playbook Command
$ ansible-playbook -i inventory.ini connection.yml
Playbook Output
PLAY [Run tasks on EC2 instance] 

TASK [Gathering Facts] 
ok: [3.237.186.53]

TASK [Run command on the EC2 instance]
changed: [3.237.186.53]

TASK [Print the command output]
ok: [3.237.186.53] => {
    "msg": [
        "Distributor ID:\tUbuntu",
        "Description:\tUbuntu 22.04.4 LTS",
        "Release:\t22.04",
        "Codename:\tjammy"
    ]
}

PLAY RECAP 
3.237.186.53               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

This shows that we were able to connect to the EC2 instance successfully and run the command lsb_release -a.