Ansible for AWS
Setup
ansible-galaxy collection install amazon.aws community.aws
pip install boto3 botocore
Configure credentials:
# Option 1: Environment variables
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=secret...
export AWS_DEFAULT_REGION=us-east-1
# Option 2: ~/.aws/credentials
aws configure
EC2 Instances
- name: Launch EC2 instance
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
network:
assign_public_ip: true
volumes:
- device_name: /dev/sda1
ebs:
volume_size: 30
volume_type: gp3
tags:
Environment: production
Project: webapp
state: running
register: ec2
- name: Show instance IP
ansible.builtin.debug:
msg: "Instance IP: {{ ec2.instances[0].public_ip_address }}"
Security Groups
- name: Create security group
amazon.aws.ec2_security_group:
name: web-sg
description: Web server security group
vpc_id: vpc-abc123
rules:
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 443
to_port: 443
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 10.0.0.0/8
rules_egress:
- proto: all
cidr_ip: 0.0.0.0/0
S3
- name: Create S3 bucket
amazon.aws.s3_bucket:
name: myapp-assets-{{ aws_account_id }}
state: present
versioning: true
encryption: AES256
public_access:
block_public_acls: true
block_public_policy: true
- name: Upload files to S3
amazon.aws.s3_object:
bucket: myapp-assets
object: "app/{{ item }}"
src: "dist/{{ item }}"
mode: put
loop:
- index.html
- app.js
- style.css
RDS
- name: Create RDS PostgreSQL
amazon.aws.rds_instance:
db_instance_identifier: myapp-db
engine: postgres
engine_version: "16.1"
db_instance_class: db.t3.micro
allocated_storage: 20
master_username: admin
master_user_password: "{{ vault_rds_password }}"
vpc_security_group_ids:
- sg-db123
db_subnet_group_name: default
multi_az: false
backup_retention_period: 7
tags:
Environment: production
VPC
- name: Create VPC
amazon.aws.ec2_vpc_net:
name: myapp-vpc
cidr_block: 10.0.0.0/16
region: us-east-1
tags:
Project: myapp
register: vpc
- name: Create subnets
amazon.aws.ec2_vpc_subnet:
vpc_id: "{{ vpc.vpc.id }}"
cidr: "{{ item.cidr }}"
az: "{{ item.az }}"
tags:
Name: "{{ item.name }}"
loop:
- { cidr: '10.0.1.0/24', az: 'us-east-1a', name: 'public-1' }
- { cidr: '10.0.2.0/24', az: 'us-east-1b', name: 'public-2' }
- { cidr: '10.0.3.0/24', az: 'us-east-1a', name: 'private-1' }
IAM
- name: Create IAM role
amazon.aws.iam_role:
name: app-role
assume_role_policy_document:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
managed_policies:
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
- name: Create IAM user
amazon.aws.iam_user:
name: deploy-user
state: present
managed_policies:
- arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
Dynamic Inventory
# aws_ec2.yml - place in inventory directory
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
keyed_groups:
- key: tags.Environment
prefix: env
- key: instance_type
prefix: type
filters:
tag:Project: myapp
instance-state-name: running
hostnames:
- private-ip-address
compose:
ansible_host: public_ip_address
ansible-inventory -i aws_ec2.yml --graph
Conclusion
Ansible's AWS modules cover the full AWS service catalog. Use amazon.aws for core services and community.aws for extended coverage. Combine with dynamic inventory for fully automated cloud management.