In this talk , we’ll cover how and why Ansible was leveraged to automate routine management of EC2 instances/EBS/EIP/ELB etc and why the Ansible approach towards automation is key for code and system deployments across 100’s of nodes and how we achieved this at Webengage. We will provide an overview of the deployment process and give a demonstration as an example
Outlines :
How ansible is a straightforward , easy way to manage multiple cloud resources
Intended Audience :
Previous experience with configuration management systems
Previous experience with AWS and Ansible
2. Who Am I ?
Vishal Uderani (@vishallud)
Lead DevOps Engineer @WebEngage
Grand Maester , House of Bash
(when annoyed , I replace things with tiny shell
scripts)
3.
4. Infrastructure at a glance
150+ instances on AWS
2 billion http req/month
Java , JS , Node , React.js , Clojure
Kafka , Zookeeper , Mongodb , Mysql
Redshift , Blueshift , CitusDB
https://engineering.webengage.com/
6. Why choose Ansible ?
●Immutable Infrastructure
* ability to create/destroy/replace servers
at anytime without service disruptions
* become vendor-agnostic by having
playbooks run on AWS/GCE/Rackspace etc
https://github.com/jlund/streisand
7. ●push based instead of pull
* ideal for deployments
* needs no agents to be installed(ssh-keys)
●configuration is ordered
* commands are structured and executed
one after another
●gentler learning curve/time to get started
$ sudo easy_install pip
$ sudo pip install ansible
8. ●dynamic inventory
* helps maintain inventory sanity in a
distributed cloud
* can run against ec2-tags/hostnames/tons
of predefined variables
“ec2_tag_monitoring": "true"
“ec2_tag_env”: "production”
https://github.com/vishalud/ansible-
playbooks/tree/master/users
9. Deployment playbooks
$ cat deploy-webengage.yml
---
# This playbook deploys the whole application stack for webengage
- name: apply common configuration to base node/build the stack
hosts: ami-nodes
user: "{{ deploy_user }}"
sudo: yes
roles:
- common
- aws
$ cat roles/common/tasks/main.yml
---
- include: config_ant_deploy.yml tags=ant-deploy
- include: config_ant_deploy_api.yml tags=ant-deploy-api
10. $ cat roles/common/tasks/config_ant_deploy.yml
- name: checkout latest web app code from github
git: repo=git@somerepo.com/webengage.git dest=/our/deploy/location key_file=/path/to/id_rsa
accept_hostkey=yes
- name: Ensure the build directory has the correct permissions before building
file: dest=/our/deploy/location/ owner=webengage group=webengage recurse=yes
# Runs ant deploy and poll as an async task
- name: Do ant deploy app
command: /usr/local/ant/bin/ant web clean deploy chdir=/our/deploy/location
async: 1800
poll: 10
#aysnc on very long running operations which may subject to ssh timeout . poll 0 to fire and forget
#Use a higher value for --forks will result in async tasks running faster and increases polling efficiency
12. $ cat roles/aws/tasks/create_ec2_dashboard.yml
- name: Get latest ami based on date
local_action:
module: ec2_ami_find
region: "{{ region }}"
name: "ansible-created-ami-{{ timestamp.stdout }}"
sort: name
sort_order: descending
sort_end: 1
register: existing_ami
- debug: var=existing_ami.results[0].ami_id
● ec2_ami_find is an ansible 2.0 module and must be imported manually for it work under
../library/ec2_ami_find.py
14. - name: Wait for HTTP to come up
local_action:
module: wait_for
host: "{{ item.public_ip }}"
port: 80
delay: 60
timeout: 400
state: started
with_items: ec2.instances
- name: Associate the dashboard EIP to the new instance
local_action:
module: ec2_eip
aws_access_key: "{{ ec2_access_key }}"
aws_secret_key: "{{ ec2_secret_key }}"
region: "{{ region }}"
instance_id: '{{ item.id }}'
ip: “{{ dashboard_ip }}”
with_items: ec2.instances
15. - name: Send notification message via Slack
local_action:
module: slack
channel: "#dev"
token: {{ slack_token }}
msg: "Dashboard has been deployed
successfully.<http://repo.webengage.com/api/v3/projects/18/repository/commits/master?private_token=<token>|Cl
ick here> for details on the last git commit"
$ cat roles/aws/tasks/main.yml
- include: create_ec2_feedback.yml tags=deploy-feedback
- include: create_ec2_notification.yml tags=deploy-notification
- include: create_ec2_dashboard.yml tags=deploy-dashboard
- include: create_new_ami.yml tags=create-ami
- include: search-ami.yml tags=search-ami
$ ansible-playbook deploy-webengage.yml -i hosts --tags "create-ami,deploy-dashboard"
$ ansible-playbook deploy-webengage.yml -i hosts --tags “search-ami,deploy-notification”
16. Using ansible-pull
1. each host has Ansible installed
2. the configuration is stored in a Git repository
3. ansible-pull checkouts the configuration repository at a given branch or tag (hint: think prod,
staging,web,db etc),
4. ansible-pull executes a specified playbook(users , sudoers , logrotate)
5. you automate the process using a cronjob, and then all you have to do is pushing the configuration
changes to a Git repository.
17. Integrating Ansible with Rundeck
● Free replacement for Ansible Tower
● One click deployments/running of ansible playbooks
● Job monitoring/statistics/time taken to execute jobs
● Use workflows . Eg: if playbook A fails , continue executing playbook B
● Delegate jobs to multiple users/Avoid SPOF completely (Integrate with AD)
● Stay lazy
https://github.com/vishalud/ansible-playbooks/tree/master/ansible-elasticsearch
https://github.com/vishalud/ansible-playbooks/tree/master/ansible-newrelic
https://github.com/vishalud/ansible-playbooks/tree/master/ansible-oracle-java
https://github.com/vishalud/ansible-playbooks/tree/master/datadog-agent
https://github.com/vishalud/ansible-playbooks/tree/master/sudo