How to Integrate Ansible with AWS EC2 and Manage Instances Dynamically

If you're working with AWS EC2 and want to automate your infrastructure using Ansible, this guide shows how to set up a dynamic inventory system. This means Ansible will automatically detect your EC2 instances based on tags—no need to maintain static inventory files!


Step 1: Install Required Dependencies

On your Ansible control node, make sure you have Python and pip installed. Then install the AWS SDK for Python (boto3), which is required for Ansible to communicate with AWS APIs.

sudo yum install python3 -y
pip3 install boto3

Also, configure AWS CLI with appropriate credentials:

aws configure

Why this matters: Boto3 and AWS CLI let Ansible fetch details about your EC2 infrastructure dynamically, based on filters like tags and regions.


Step 2: Create the Dynamic Inventory Configuration

mkdir -p /home/ec2-user
cd /home/ec2-user

Create a file called aws_ec2.yml with the following content:

plugin: amazon.aws.aws_ec2
regions:
  - ap-south-1
filters:
  tag:Env: Test
hostnames:
  - tag:Name
keyed_groups:
  - key: tags['Env']
    prefix: Env
compose:
  ansible_host: public_ip_address
ansible_user: ec2-user
ansible_ssh_private_key_file: /home/ec2-user/New-key.pem

Key Points:

  • plugin: Enables the AWS EC2 dynamic inventory plugin.
  • regions: Specify which AWS region to look into.
  • filters: Restrict to EC2 instances tagged with Env=Test.
  • hostnames: Uses the Name tag for each host's name in Ansible.
  • keyed_groups: Automatically groups hosts under Env_Test.
  • compose: Uses the instance’s public IP address as the target for SSH.

Make sure the SSH key file matches the key associated with your EC2 instances.


⚙️ Step 3: Install or Update the Ansible AWS Collection

ansible-galaxy collection install amazon.aws --upgrade

This collection includes the dynamic inventory plugin and AWS modules that Ansible needs.


Step 4: Enable Plugin in Ansible Configuration

Edit or create /home/ec2-user/ansible.cfg and add:

[inventory]
enable_plugins = aws_ec2

[defaults]
ansible_user = ec2-user

Why this matters: This tells Ansible to use the dynamic inventory plugin when you specify -i aws_ec2.yml.


Step 5: Test Your Dynamic Inventory

ansible-inventory -i /home/ec2-user/aws_ec2.yml --list

This command outputs a JSON structure of all EC2 instances that match your filter. It's useful to confirm that your instances are being discovered correctly.


Step 6: Create Your Ansible Playbook

sudo mkdir -p /var/playbook
sudo touch /var/playbook/patch.yml
sudo chown ec2-user:ec2-user /var/playbook/patch.yml

Now add the following content to /var/playbook/patch.yml:

- name: Retrieve OS version
  hosts: Env_Test
  become: yes
  gather_facts: yes
  tasks:
    - name: Display OS distribution and version
      debug:
        msg: "The operating system is {{ ansible_distribution }} version {{ ansible_distribution_major_version }}"

    - name: Retrieve system uptime
      command: uptime -p
      register: uptime_result

    - name: Display system uptime
      debug:
        msg: "System uptime: {{ uptime_result.stdout }}"

    - name: Display private IP address
      debug:
        msg: "Private IP address: {{ ansible_default_ipv4.address }}"

Explanation: This playbook collects system facts, uptime, and private IP from all EC2 instances tagged as Env=Test.


Step 7: Upload SSH Key and Set Environment Variable

If your key is in .ppk format, convert it to .pem using PuTTYgen and upload to the Ansible master node:

scp New-key.pem ec2-user@your-ansible-host:/home/ec2-user/
chmod 400 /home/ec2-user/New-key.pem

Disable SSH host key checking (optional):

echo "export ANSIBLE_HOST_KEY_CHECKING=False" >> ~/.bashrc
source ~/.bashrc

Why: This prevents Ansible from halting if the host key is not already known.


Step 8: Run the Playbook

ansible-playbook -i /home/ec2-user/aws_ec2.yml /var/playbook/patch.yml \
--private-key=/home/ec2-user/New-key.pem --check

This runs the playbook in check mode, showing what would happen without making changes.

Sample Output:

PLAY [Retrieve OS version] ****************************************************

TASK [Gathering Facts]
ok: [Terraform-EC2-0]

TASK [Display OS distribution and version]
ok: [Terraform-EC2-0] => {
    "msg": "The operating system is Amazon version 2023"
}

TASK [Display private IP address]
ok: [Terraform-EC2-0] => {
    "msg": "Private IP address: 172.31.2.184"
}

Conclusion

By using Ansible's dynamic inventory with the AWS EC2 plugin, you eliminate the need to manually track and update your hosts. It’s a scalable and efficient way to manage cloud infrastructure based on tags, environment, or region.

Best Practices:

  • Use consistent tagging in AWS (e.g., Env, Project, Owner).
  • Secure your SSH keys and restrict access to the Ansible control node.
  • Test playbooks in --check mode before actual execution.

Feel free to share this post if it helped you simplify your EC2 management with Ansible!

Comments

Popular Posts

Why SELinux Is Blocking Your Service (and How to Fix It)

Puppet Code Deploy Troubleshooting & Resolution Guide

Fix: SSH Permission Denied Issue | Real Solution