Leveraging Ansible to automate AWS instance management
Ansible is an open-source software automation tool suited for instance configuration and provisioning, enabling an Infrastructure as Code approach to the Cloud.
In this page we provide a set of ansible-playbooks templates to perform the most common task to tune EC2 instance types with Akamas, such as:
The orchestrator requires access to an account or role linked to the correct policies; this requires managing AWS Policies and having access to the required security groups.
Instance Creation
The following example playbook provisions an EC2 instance using the latest Ubuntu 18-04 LTS image and then waits for it to be available.
The playbook requires the following set of arguments:
key: the name of the SSH key pair to use
Name: the instance name
security_group: the name of the AWS security group
region: the selected AWS region
You can update the ec2_ami_info task to query for a different AMI family or specify directly the id under ec2.image.
When executing the script we must assign the following arguments as extra-vars:
intance_type: type of instance to provision
volume_size: size of the attached volume
# Launch an ubuntu instance and wait for ssh
- name: Create an instance request
hosts: localhost
gather_facts: False
tasks:
- name: query api
ec2_ami_info:
filters:
name: "ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"
owner-id: "099720109477" # Canonical Group Limited
register: amis
- name: sort by creation date
set_fact:
sorted_amis: "{{ amis.images | sort(attribute='creation_date') }}"
- name: get latest
set_fact:
latest_ami: "{{ sorted_amis | last }}"
- name: Launch instance
ec2:
key_name: "{{ key }}"
instance_type: "{{ instance_type | default('m5.xlarge') }}"
group:
- <your-security-groups>
image: "{{ latest_ami.image_id }}"
count: "{{ count | default('1') }}"
wait: yes
wait_timeout: 500
region: "{{ region }}"
spot_wait_timeout: 600
instance_initiated_shutdown_behavior: terminate
ebs_optimized: yes
volumes:
- device_name: /dev/sda1
volume_type: gp2
volume_size: "{{ volume_size | default('20') }}"
delete_on_termination: yes
instance_tags:
Name: "{{ Name }}"
CNAME: "{{ Name }}.<your-domain>"
register: ec2
- name: Wait for SSH to come up
wait_for:
host: "{{ item.public_dns_name }}"
port: 22
delay: 60
timeout: 320
state: started
with_items: "{{ ec2.instances }}"
To apply the EC2 parameters from the AWS Optimization Pack selected by the Akamas engine you can generate the playbook arguments through a template like the following one, where ec2 is the name of the component:
Instance resizing is a little trickier to deploy as it requires you to install AWS CLI and setup the required credentials.
The following playbook provides a simple way to stop, update and restart your instance: it is intended as a building block for more elaborate workflows.
It makes use of a list of arguments:
instance_name: your instance name
region: the selected AWS region
For a successful workflow it requires:
The instance to exist
The instance to be unique
# Change instance type, requires AWS CLI
- name: Resize the instance
hosts: localhost
gather_facts: no
connection: local
tasks:
- name: save instance info
ec2_instance_info:
filters:
"tag:Name": "{{ instance_name }}"
register: ec2
- name: stop the instance
ec2:
region: "{{ region | default('us-east-2') }}"
state: stopped
instance_ids:
- "{{ ec2.instances[0].instance_id }}"
instance_type: "{{ ec2.instances[0].instance_type }}"
wait: True
- name: Change the instances ec2 type
shell: >
aws ec2 modify-instance-attribute --instance-id "{{ ec2.instances[0].instance_id }}"
--instance-type "{{ new_instance_type }}"
delegate_to: localhost
- name: restart the instance
ec2:
region: "{{ region }}"
state: running
instance_ids:
- "{{ ec2.instances[0].instance_id }}"
wait: True
register: ec2
- name: wait for SSH to come up
wait_for:
host: "{{ item.public_dns_name }}"
port: 22
delay: 60
timeout: 500
state: started
with_items: "{{ ec2.instances }}"
To apply the EC2 parameters from the AWS Optimization Pack selected by the Akamas engine you can generate the playbook arguments through a template like the following, where ec2 is the name of the component: