How to Use Ansible for Automating EC2 Instances and RDS Databases: A Complete Guide

Ansible automates EC2 instances and RDS databases using agentless architecture and cloud-specific modules like amazon.aws.ec2 and community.aws.rds, enabling you to provision, configure, and manage AWS infrastructure through declarative YAML playbooks.

Ansible serves as a powerful automation engine for managing diverse cloud infrastructure components without requiring agents on target systems. In the bregman-arie/devops-exercises repository, comprehensive exercises demonstrate how to leverage Ansible's cloud modules and dynamic inventory to automate EC2 instances and RDS databases, making infrastructure provisioning repeatable and version-controlled.

Understanding Ansible Cloud Automation Architecture

Ansible manages cloud resources through four distinct layers that work together to provide declarative infrastructure management.

Inventory Layer

The inventory lists target hosts or cloud services Ansible communicates with. Static files work for on-premises hosts, while dynamic inventory pulls live data from AWS APIs. According to topics/ansible/README.md, dynamic inventory is essential when hosts are created or terminated automatically, ensuring playbooks always reference current cloud state.

Playbook Layer

Playbooks are YAML files that orchestrate tasks, groups, roles, and variables. As shown in topics/ansible/my_first_playbook.md, playbooks define what should exist (EC2 instances, security groups, RDS clusters) rather than how to create them.

Module Layer

Modules perform single actions such as creating an EC2 instance or modifying an RDS parameter group. Ansible ships with official AWS modules under amazon.aws.* and community.aws.* collections. The ansible-doc -l command lists available modules as referenced in the repository's self-assessment section.

Dynamic Inventory Implementation

Dynamic inventory scripts or plugins query AWS APIs to generate runtime inventories. The aws_ec2.yaml configuration file defines how Ansible discovers EC2 instances:

plugin: amazon.aws.ec2
regions:
  - us-east-1
filters:
  tag:Environment: production
keyed_groups:
  - key: tags.Role
    prefix: role

Save this file as inventory/aws_ec2.yaml and execute:

ANSIBLE_INVENTORY=inventory/aws_ec2.yaml ansible-playbook provision.yml

Automating EC2 Instances with Ansible

Managing EC2 instances requires combining dynamic inventory discovery with the amazon.aws.ec2 module for idempotent provisioning.

Configuring Dynamic Inventory for AWS

Before provisioning, configure the dynamic inventory plugin to discover existing instances. As noted in topics/aws/exercises/launch_ec2_instance/exercise.md, understanding EC2 parameters (AMI ID, instance type, security groups) is prerequisite to automating them.

Provisioning EC2 Instances Using the amazon.aws.ec2 Module

The following playbook demonstrates complete EC2 automation:

---
- name: Provision EC2 instances for production
  hosts: localhost          # control host talks directly to AWS

  gather_facts: false
  collections:
    - amazon.aws

  vars:
    instance_type: t3.medium
    ami_id: "{{ lookup('env','AWS_AMI') | default('ami-0c55b159cbfafe1f0') }}"
    key_name: my-ssh-key
    security_group: sg-0123456789abcdef0
    subnet_id: subnet-0a1b2c3d4e5f6g7h8

  tasks:
    - name: Ensure EC2 instance exists
      amazon.aws.ec2:
        key_name: "{{ key_name }}"
        instance_type: "{{ instance_type }}"
        image_id: "{{ ami_id }}"
        region: us-east-1
        vpc_subnet_id: "{{ subnet_id }}"
        group_id: "{{ security_group }}"
        count: 2
        wait: true
        state: present
      register: ec2

    - name: Show created instance IDs
      debug:
        var: ec2.instances

This playbook uses the amazon.aws.ec2 module documented in the AWS collection. It is fully idempotent—re-running it will only create missing instances, preventing duplicates.

Managing RDS Databases with Ansible

RDS automation follows similar patterns but requires the community.aws collection for database-specific modules.

Deploying RDS Instances with community.aws.rds

As referenced in topics/aws/exercises/mysql_db/exercise.md, RDS configuration involves subnet groups, parameter groups, and engine specifications. The following role tasks automate RDS deployment:

---
- name: Ensure DB subnet group exists
  community.aws.rds_subnet_group:
    name: prod-db-subnet
    description: Subnet group for production RDS
    subnet_ids:
      - subnet-0a1b2c3d4e5f6g7h8
      - subnet-1b2c3d4e5f6g7h8i9
    state: present

- name: Deploy PostgreSQL RDS instance
  community.aws.rds:
    command: create
    instance_name: prod-db
    engine: postgres
    engine_version: "13.4"
    db_instance_class: db.t3.medium
    allocated_storage: 20
    master_username: "{{ rds_username }}"
    master_user_password: "{{ rds_password }}"
    multi_az: true
    publicly_accessible: false
    db_subnet_group_name: prod-db-subnet
    tags:
      Environment: production
    state: present

Include this role in a top-level playbook that runs against localhost (no remote host needed—Ansible communicates directly with AWS APIs):

- name: Deploy RDS
  hosts: localhost
  gather_facts: false
  collections:
    - community.aws
  vars:
    rds_username: admin
    rds_password: "{{ lookup('env','RDS_PASSWORD') | default('ChangeMe123!') }}"
  roles:
    - rds_provision

Configuring DB Subnet Groups and Security

The community.aws.rds_subnet_group module ensures network isolation prerequisites exist before database deployment. This declarative approach prevents deployment failures due to missing infrastructure dependencies.

Orchestrating Complete Infrastructure Stacks

A single orchestrating playbook can provision a VPC, launch EC2 workers, spin up an RDS instance, and wire security groups together:

---
- import_playbook: provision_ec2.yml
- import_playbook: rds_deploy.yml

Running ansible-playbook site.yml provisions both compute and database layers in a single, reproducible run. Because Ansible is push-based, you can trigger this from CI pipelines (GitHub Actions) or local developer machines. The same playbooks serve both development and production environments through different inventory files or variable overrides.

Summary

  • Ansible uses agentless architecture to manage EC2 and RDS through cloud-specific modules without installing software on target instances.
  • Dynamic inventory (amazon.aws.ec2 plugin) automatically discovers cloud resources, ensuring playbooks always reference current infrastructure state.
  • Idempotent modules like amazon.aws.ec2 and community.aws.rds ensure repeated runs create no duplicate resources.
  • Role-based organization separates EC2 provisioning from RDS management, enabling reusable infrastructure code.
  • Push-based execution allows integration with CI/CD pipelines for automated infrastructure deployment.

Frequently Asked Questions

What is the difference between static and dynamic inventory for AWS automation?

Static inventory requires manually listing hostnames or IP addresses in files, which becomes unmanageable with auto-scaling EC2 instances. Dynamic inventory uses plugins like amazon.aws.ec2 to query AWS APIs at runtime, automatically grouping instances by tags or regions. According to topics/ansible/README.md, dynamic inventory is essential when hosts are created or terminated automatically.

How does Ansible ensure idempotency when managing EC2 instances?

Ansible modules like amazon.aws.ec2 check the current state of AWS resources before taking action. When you specify state: present and provide instance parameters, the module queries existing instances and only creates new ones if the desired count or configuration is not met. Re-running the same playbook from provision_ec2.yml will not create duplicate instances if the desired state already exists.

Can Ansible manage RDS databases without installing agents on database servers?

Yes, Ansible manages RDS through AWS API calls rather than direct host connections. The community.aws.rds module communicates with the AWS RDS service to create, modify, or delete database instances. As shown in the rds_provision role tasks, playbooks run against localhost with gather_facts: false, using API credentials to manage the database lifecycle without ever connecting to the RDS instance directly.

Which Ansible collections are required for AWS cloud automation?

For comprehensive AWS automation, you need the amazon.aws collection for core EC2, VPC, and IAM resources, and the community.aws collection for additional services like RDS. The amazon.aws.ec2 module handles instance provisioning, while community.aws.rds and community.aws.rds_subnet_group manage database resources. Install these via ansible-galaxy collection install amazon.aws community.aws before executing cloud playbooks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →