AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible AWS: Complete Guide to Cloud Automation (2026)

By Luca Berton · Published 2026-04-03 · Category: installation

Complete guide to automating AWS with Ansible. Manage EC2, S3, IAM, VPC, RDS, and Lambda with amazon.aws collection and practical examples.

Ansible's amazon.aws and community.aws collections let you automate your entire AWS infrastructure — from EC2 instances to S3 buckets to RDS databases.

Setup

# Install collections
ansible-galaxy collection install amazon.aws
ansible-galaxy collection install community.aws

# Python requirements pip install boto3 botocore

Authentication

# Method 1: Environment variables
# export AWS_ACCESS_KEY_ID='your-key'
# export AWS_SECRET_ACCESS_KEY='your-secret'
# export AWS_REGION='us-east-1'

# Method 2: In playbook (use vault!) - hosts: localhost vars: aws_access_key: "{{ vault_aws_key }}" aws_secret_key: "{{ vault_aws_secret }}" environment: AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" AWS_REGION: us-east-1

# Method 3: AWS CLI profile # ~/.aws/credentials configured, use profile parameter

See also: Ansible for AWS: Complete Guide to Cloud Automation with EC2, S3, RDS, and More

EC2 Instances

Launch an EC2 instance

- name: Launch EC2 instance
  amazon.aws.ec2_instance:
    name: web-server-01
    instance_type: t3.medium
    image_id: ami-0abcdef1234567890
    key_name: my-keypair
    security_groups:
      - web-sg
    vpc_subnet_id: subnet-12345678
    network:
      assign_public_ip: true
    volumes:
      - device_name: /dev/sda1
        ebs:
          volume_size: 50
          volume_type: gp3
    tags:
      Environment: production
      Role: webserver
    state: running
  register: ec2

- name: Show instance IP debug: msg: "Instance IP: {{ ec2.instances[0].public_ip_address }}"

Stop/Terminate instances

- name: Stop instances by tag
  amazon.aws.ec2_instance:
    filters:
      "tag:Environment": staging
    state: stopped

- name: Terminate instance amazon.aws.ec2_instance: instance_ids: - i-1234567890abcdef0 state: terminated

Security Groups

- name: Create security group
  amazon.aws.ec2_security_group:
    name: web-sg
    description: Web server security group
    vpc_id: vpc-12345678
    rules:
      - proto: tcp
        ports: [80, 443]
        cidr_ip: 0.0.0.0/0
        rule_desc: HTTP/HTTPS
      - proto: tcp
        ports: [22]
        cidr_ip: 10.0.0.0/8
        rule_desc: SSH from internal
    rules_egress:
      - proto: all
        cidr_ip: 0.0.0.0/0
    tags:
      Name: web-sg

See also: Ansible Troubleshooting: Resolving community.aws.ec2_instance Issues

S3 Buckets

- name: Create S3 bucket
  amazon.aws.s3_bucket:
    name: my-app-assets-{{ aws_account_id }}
    versioning: true
    encryption: AES256
    public_access:
      block_public_acls: true
      block_public_policy: true
    tags:
      Environment: production

- name: Upload file to S3 amazon.aws.s3_object: bucket: my-app-assets object: configs/app.yml src: /opt/app/config.yml mode: put

- name: Download from S3 amazon.aws.s3_object: bucket: my-app-assets object: configs/app.yml dest: /opt/app/config.yml mode: get

- name: Sync directory to S3 community.aws.s3_sync: bucket: my-website file_root: /opt/website/public permission: public-read

VPC Networking

- name: Create VPC
  amazon.aws.ec2_vpc_net:
    name: app-vpc
    cidr_block: 10.0.0.0/16
    region: us-east-1
    tags:
      Environment: production
  register: vpc

- name: Create public subnet amazon.aws.ec2_vpc_subnet: vpc_id: "{{ vpc.vpc.id }}" cidr: 10.0.1.0/24 az: us-east-1a tags: Name: public-subnet-1a register: public_subnet

- name: Create Internet Gateway amazon.aws.ec2_vpc_igw: vpc_id: "{{ vpc.vpc.id }}" tags: Name: app-igw register: igw

See also: Ansible S3 Module: Upload, Download, Manage AWS S3 Objects (Complete Guide)

RDS Databases

- name: Create RDS PostgreSQL instance
  community.aws.rds_instance:
    db_instance_identifier: myapp-db
    engine: postgres
    engine_version: "16.1"
    db_instance_class: db.t3.medium
    allocated_storage: 100
    master_username: admin
    master_user_password: "{{ vault_rds_password }}"
    vpc_security_group_ids:
      - sg-12345678
    db_subnet_group_name: my-db-subnet-group
    backup_retention_period: 7
    multi_az: true
    tags:
      Environment: production

Dynamic Inventory

# inventory/aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
filters:
  tag:managed_by: ansible
keyed_groups:
  - key: tags.Role
    prefix: role
  - key: tags.Environment
    prefix: env
compose:
  ansible_host: public_ip_address
ansible-inventory -i inventory/aws_ec2.yml --graph

Complete Example: Web Application Stack

- name: Deploy AWS web stack
  hosts: localhost
  connection: local
  tasks:
    - name: Create VPC and networking
      include_tasks: tasks/networking.yml

- name: Create RDS database include_tasks: tasks/database.yml

- name: Launch web servers amazon.aws.ec2_instance: name: "web-{{ item }}" instance_type: t3.medium image_id: "{{ ami_id }}" key_name: deploy-key security_groups: ["{{ web_sg.group_id }}"] vpc_subnet_id: "{{ public_subnet.subnet.id }}" user_data: "{{ lookup('file', 'userdata.sh') }}" count: 1 tags: Role: webserver Environment: production loop: "{{ range(1, 4) | list }}"

FAQ

Should I use Ansible or Terraform for AWS?

Use both: Terraform for infrastructure provisioning (VPCs, subnets, RDS), Ansible for configuration management (installing software, deploying apps). They complement each other.

How do I handle AWS credentials securely?

Use IAM roles for EC2 instances (no credentials needed), AWS SSO profiles, or Ansible Vault for encrypted credentials. Never put keys in plaintext.

Can Ansible replace CloudFormation?

For many use cases, yes. Ansible's AWS modules cover most services. CloudFormation has better drift detection and rollback. Choose based on your team's workflow.

Setup

# Install AWS collection
ansible-galaxy collection install amazon.aws

# Install Python dependencies pip install boto3 botocore

# Configure credentials export AWS_ACCESS_KEY_ID=AKIA... export AWS_SECRET_ACCESS_KEY=... export AWS_REGION=us-east-1

Launch EC2 Instance

- name: Launch EC2
  amazon.aws.ec2_instance:
    name: web-server
    instance_type: t3.micro
    image_id: ami-0c55b159cbfafe1f0
    key_name: deploy-key
    security_groups: [web-sg]
    subnet_id: subnet-abc123
    state: running
    tags:
      Environment: production
      Team: web
    wait: true
  register: ec2

S3 Bucket

- amazon.aws.s3_bucket:
    name: my-app-backups
    versioning: true
    tags:
      Environment: production

- amazon.aws.s3_object: bucket: my-app-backups object: backups/db-backup.sql src: /tmp/db-backup.sql mode: put

VPC and Networking

- amazon.aws.ec2_vpc_net:
    name: my-vpc
    cidr_block: 10.0.0.0/16
    tags: { Name: my-vpc }
  register: vpc

- amazon.aws.ec2_vpc_subnet: vpc_id: "{{ vpc.vpc.id }}" cidr: 10.0.1.0/24 az: us-east-1a tags: { Name: public-subnet } register: subnet

- amazon.aws.ec2_security_group: name: web-sg description: Web server SG vpc_id: "{{ vpc.vpc.id }}" rules: - proto: tcp ports: [80, 443] cidr_ip: 0.0.0.0/0 - proto: tcp ports: [22] cidr_ip: 10.0.0.0/8

RDS Database

- amazon.aws.rds_instance:
    db_instance_identifier: myapp-db
    engine: postgres
    engine_version: "16.2"
    db_instance_class: db.t3.micro
    allocated_storage: 20
    master_username: admin
    master_user_password: "{{ vault_db_password }}"
    vpc_security_group_ids: ["{{ sg.group_id }}"]
    tags: { Environment: production }

Dynamic Inventory

# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
keyed_groups:
  - key: tags.Environment
    prefix: env
  - key: instance_type
    prefix: type
filters:
  instance-state-name: running
ansible-inventory -i aws_ec2.yml --list
ansible -i aws_ec2.yml env_production -m ping

Key Modules

| Module | Purpose | |--------|---------| | ec2_instance | Manage EC2 instances | | s3_bucket | S3 buckets | | s3_object | S3 files | | ec2_vpc_net | VPCs | | ec2_vpc_subnet | Subnets | | ec2_security_group | Security groups | | rds_instance | RDS databases | | iam_role | IAM roles | | route53 | DNS records | | elb_application_lb | ALB |

FAQ

Ansible vs Terraform for AWS?

Terraform is purpose-built for AWS infrastructure with state management. Ansible can provision AWS resources but excels at post-provisioning configuration. Many teams use both.

How do I authenticate?

Environment variables (AWS_ACCESS_KEY_ID), IAM instance profiles, ~/.aws/credentials, or aws_access_key/aws_secret_key in tasks.

Can I manage multiple AWS accounts?

Yes — use profile parameter or set credentials per task/play.

Install Collection

ansible-galaxy collection install amazon.aws
pip install boto3 botocore

Configure Credentials

# Option 1: Environment variables
# export AWS_ACCESS_KEY_ID=AKIA...
# export AWS_SECRET_ACCESS_KEY=...

# Option 2: In playbook - hosts: localhost vars: aws_access_key: "{{ vault_aws_key }}" aws_secret_key: "{{ vault_aws_secret }}" region: us-east-1

Launch EC2 Instance

- amazon.aws.ec2_instance:
    name: web-server-1
    instance_type: t3.medium
    image_id: ami-0c55b159cbfafe1f0
    key_name: my-keypair
    security_group: web-sg
    subnet_id: subnet-abc123
    network:
      assign_public_ip: true
    tags:
      Environment: production
      Role: webserver
    state: running
  register: ec2

Manage S3

# Create bucket
- amazon.aws.s3_bucket:
    name: my-app-backups
    state: present
    versioning: true
    encryption: AES256

# Upload file - amazon.aws.s3_object: bucket: my-app-backups object: backups/db-2026-04-07.sql.gz src: /tmp/db-backup.sql.gz mode: put

Create VPC

- amazon.aws.ec2_vpc_net:
    name: my-vpc
    cidr_block: 10.0.0.0/16
    region: us-east-1
    tags: { Environment: production }
  register: vpc

- amazon.aws.ec2_vpc_subnet: vpc_id: "{{ vpc.vpc.id }}" cidr: 10.0.1.0/24 az: us-east-1a tags: { Name: public-subnet } register: subnet

Security Groups

- amazon.aws.ec2_security_group:
    name: web-sg
    description: Web server security group
    vpc_id: "{{ vpc.vpc.id }}"
    rules:
      - proto: tcp
        ports: [80, 443]
        cidr_ip: 0.0.0.0/0
      - proto: tcp
        ports: [22]
        cidr_ip: 10.0.0.0/8
    rules_egress:
      - proto: all
        cidr_ip: 0.0.0.0/0

Dynamic Inventory

# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
filters:
  tag:Environment: production
keyed_groups:
  - key: tags.Role
    prefix: role
compose:
  ansible_host: public_ip_address
ansible-inventory -i aws_ec2.yml --graph

RDS Database

- amazon.aws.rds_instance:
    db_instance_identifier: my-postgres
    engine: postgres
    engine_version: "16.2"
    db_instance_class: db.t3.medium
    allocated_storage: 50
    master_username: admin
    master_user_password: "{{ vault_rds_password }}"
    vpc_security_group_ids: ["{{ db_sg.group_id }}"]
    state: present
  no_log: true

IAM

- amazon.aws.iam_user:
    name: deploy-bot
    state: present

- amazon.aws.iam_policy: iam_type: user iam_name: deploy-bot policy_name: s3-access policy_json: | { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "s3:*", "Resource": "arn:aws:s3:::my-app-*" }] }

FAQ

Do I need boto3?

Yes — all amazon.aws modules require boto3 and botocore Python packages on the controller.

How to use IAM roles instead of keys?

On EC2 instances with an IAM role, boto3 auto-discovers credentials. No access keys needed.

Can I manage multiple regions?

Yes — set region per task or use dynamic inventory with multiple regions.

Install Collection

ansible-galaxy collection install amazon.aws
pip install boto3 botocore

Authentication

# Environment variables (recommended)
# export AWS_ACCESS_KEY_ID=AKIA...
# export AWS_SECRET_ACCESS_KEY=...
# export AWS_DEFAULT_REGION=us-east-1

# Or in playbook - hosts: localhost vars: aws_access_key: "{{ vault_aws_key }}" aws_secret_key: "{{ vault_aws_secret }}" region: us-east-1

EC2 Instance

- amazon.aws.ec2_instance:
    name: web-server
    instance_type: t3.micro
    image_id: ami-0abcdef1234567890
    key_name: my-keypair
    security_group: web-sg
    subnet_id: subnet-12345
    state: running
    tags:
      Environment: production
      App: mywebapp
  register: ec2

S3 Bucket

- amazon.aws.s3_bucket:
    name: my-app-assets
    state: present
    versioning: true
    tags:
      Environment: production

- amazon.aws.s3_object: bucket: my-app-assets object: config/app.conf src: files/app.conf mode: put

Security Group

- amazon.aws.ec2_security_group:
    name: web-sg
    description: Web server security group
    rules:
      - proto: tcp
        ports: [80, 443]
        cidr_ip: 0.0.0.0/0
      - proto: tcp
        ports: [22]
        cidr_ip: 10.0.0.0/8

VPC

- amazon.aws.ec2_vpc_net:
    name: my-vpc
    cidr_block: 10.0.0.0/16
    tags:
      Environment: production
  register: vpc

- amazon.aws.ec2_vpc_subnet: vpc_id: "{{ vpc.vpc.id }}" cidr: 10.0.1.0/24 az: us-east-1a tags: Name: public-subnet

IAM User

- amazon.aws.iam_user:
    name: deploy-user
    state: present
    managed_policies:
      - arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Dynamic Inventory

# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
keyed_groups:
  - key: tags.Environment
    prefix: env
  - key: instance_type
    prefix: type
filters:
  instance-state-name: running
compose:
  ansible_host: public_ip_address

FAQ

How to use AWS profiles?

Set AWS_PROFILE environment variable or profile parameter in modules.

Costs from Ansible runs?

Ansible API calls to AWS are free. Costs come from resources you create (EC2, S3, etc.).

amazon.aws vs community.aws?

amazon.aws is maintained by Red Hat (certified). community.aws has additional community-contributed modules.

Related Articles

Ansible Galaxy authenticationreading environment variables in Ansible playbooksAnsible Vault Guidestatic and dynamic Ansible inventoryAnsible loop patterns and tips

Related: Ansible Database Automation

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home