Ansible

IT Automation Tool
Configure - Deploy - Orchestrate

Ad-hoc Commands


Given an inventory defining 'webservers'

ansible webservers -m user -a "name=marsel state=present"
hosts
module

arguments


ansible webservers -m user -a "name=moriarty state=absent"

Playbook

Describe a policy or set of steps to apply to
groups of hosts
---
- hosts: webservers
   remote_user: config
   sudo: true
   tasks:
     - name: Add Pythonista
       user: name=marsel state=present
     - name: Remove bad guy
       user: name=moriarty state=absent
 

Nginx

Install Nginx

   - name: Install nginx

      apt: pkg=nginx state=present update-cache=yes

NGINX

Add repo for latest stable nginx package

- name: Install nginx key

  apt_key: url=http://nginx.org/keys/nginx_signing.key state=present

- name: Add repo for nginx

  apt_repository: repo='deb http://nginx.org/packages/debian/ wheezy nginx'

- name: Add src repo for nginx

  apt_repository: repo='deb-src http://nginx.org/packages/debian/ wheezy nginx'

Nginx Role

Reusable container for related actions
In roles/nginx/tasks/main.yml:
---
- name: Install nginx key
  apt_key: url=http://nginx.org/keys/nginx_signing.key state=present

- name: Add repo for nginx
  apt_repository: repo='deb http://nginx.org/packages/debian/ wheezy nginx'

- name: Add src repo for nginx
  apt_repository: repo='deb-src http://nginx.org/packages/debian/ wheezy nginx'

- name: Install nginx
  apt: pkg=nginx state=present update-cache=yes

NGINX ROLE (cont)

Apply the role in a playbook

---
- hosts: webservers
  sudo: true
  roles:
    - nginx

Nginx Config File

In roles/nginx/tasks/main.yml
<snip>...- name: Install main config file
  copy: src=nginx.conf dest=/etc/nginx/nginx.conf
    owner=root group=root mode=0644  notify:    - Restart nginx # define handler in roles/nginx/handlers/main.yml or below
In roles/nginx/templates/nginx.conf
server {
    listen 80;
    server_name example.com;

    location /static/ {
        alias {{ website_static_dir }};
    }
    # ...
}
In roles/nginx/defaults/main.yml
---
website_static_dir: /whatever/path/you/like 

Variables

  • In inventory file (we'll see these in a moment)
  • In group/host var files
  • In playbooks
  • In roles (defaults)
  • In roles (vars)
  • On command line (-e)

Inventory File

production
[dbservers]
db.mydomain.com

[app1-servers]
app1-[1-4].mydomain.com

[app2-servers]
wizard.mydomain.com

[redis-servers:children]
dbservers

[appservers:children]
app1-serversapp2-servers

[all:vars]
env=production

[appservers:vars]
git_branch=master

Runtime!


Run myapp playbook against the production inventory
ansible-playbook -i production myapp.yml

limited to a group (-l)
ansible-playbook -i production -l appservers myapp.yml


Execution model:
  • separate ssh connection for each module invocation
  • parallelized across machines 

Environments (RYO)


In inventory file:
[all:vars]
env=production 

In playbook:
---
- hosts: all
  remote_user: config
  vars_files:
    - "vars/common.yml"
    - "vars/{{ env }}.yml"
  roles:
    - webserver
    - node 

Ansible - Key Benefits


Shallow learning curve
Minimal number of abstractions
Data, not code
Predictable execution model
Good documentation
Few moments of hair-tearing frustration

ansible

By Simon Robson