MEET ANSIBLE

about me

cristian vargas

Electronic Engineer

Universidad del Valle

cristian@swapps.co

Python developer

Does not hate Javascript that much

Rustacean from time to time

WHY ARE MACHINES BETTER THAN HUMANS?
WHY AUTOMATE?

  • Pesky humans are error prone
  • Humans get bored with repetitive tasks
  • Humanity should be renamed bottleneck

Regular flow for a regular human

Boss: Hey Joe, you got to install Redis on every server we use because we heard it was a cool thing to do.

Joe:

- SSH to server 1

- $ sudo apt-get update

- $ sudo apt-get install redis-server

100 servers and a couple hours later:

Joe: Mission accomplished.

BETTER flow for a BETTER human

Boss: Hey Carl, you got to install Redis on every server we use because we heard it was a cool thing to do.

Carl: ./my_pretty_script_for_installing_random_things.sh

100 servers and a couple minutes later:

Carl: Mission accomplished.

#!/bin/bash
# Taken from: http://stackoverflow.com/questions/13928116/write-a-shell-script-to-ssh-to-a-remote-machine-and-execute-commands
USERNAME=someUser
HOSTS="host1 host2 host3..host100"
SCRIPT="sudo apt-get update; sudo apt-get install -y redis-server"
for HOSTNAME in ${HOSTS} ; do
    ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"
done

GOOD ENOUGH?

  • No error checking
  • May apply operations where they are not needed
  • Completely sequential (May be my lack of knowledge on bash)
  • Hard to adapt to other use cases
  • Does not guarantee that the service is started

MEET ANSIBLE:

WE CAN DO BETTER

Boss: Hey Andres, you got to install Redis on every server we use because we heard it was a cool thing to do.

 

Andres: Inventory file

 

 

 

Andres: 

[my-servers]
some.com
some-other.com
123.123.123.123
ansible my-servers -i my-inv -m apt -a "update-cache=yes name=redis-server state=present" -b

How is that better?

  • Error tolerant: one single failure won't break everything
  • Results report: We can know what succeeded and what failed
  • Forks: We can run our "plays" on several hosts at a time
  • Idempotency: You describe states, not operations, so ansible will detect if the state needs to change or not and act accordingly. Running the same play several times will have the same effect as running it only once.

 

why ansible?

We have a lot of tools to choose from. There are a lot of alternatives to ansible, with chef, puppet and salt being the most used ones. With other choices why should we pick Ansible?

  • No agents required on host
  • Requires only Python and SSH, which comes by default on most linux distributions. Chef and puppet require installing Ruby on host machines.
  • Is "just text files".
  • Most tasks won't require any programming, and where it is needed any language that can return JSON can be used (about any language).

so i should use only ansible for everything?

This is just about what i have learnt from using Ansible for a couple months now.

If you use alternatives that is OK. The point is to automate as much as possible to improve the quality and speed of your releases.

who uses ansible?

Scenario 2

Boss: Hey Mr. DevOpsRockStar, do you remember that time you installed Redis really fast? Now we want to do the same for all of our most used packages.

Mr. DevOpsRockStar: Too easy.

---
- hosts: my-servers

  pre_tasks:
    - name: Update apt cache if needed
      become: yes
      apt: update_cache=yes cache_valid_time=86400

  tasks:
  - name: Install system packages.
  - become: yes
  - apt: name={{ item }} state=present
  - with_items:
    - redis-server
    - build-essential
    - python-dev

Scenario 2

Mr. DevOpsRockStar: And now I run my playbook

ansible-playbook playbook.yml -i my-inv

Ansible defines everything on units called plays, group those plays on playbooks and run the playbooks on hosts.

The playbooks define a general state of the system.

I.E. This package should be present, these packages should be absent, these directories should be present with permissions for this user, etc.

Scenario 2

Ansible uses Jinja2, which allows you to define variables for ansible to use inside of your playbooks. That gives you a lot of flexibility.

# playbook.yml
---
- hosts: all
  tasks:
    - name: Copy nginx config file
      become: yes
      template:
        src: my_nginx_config
        dest: /etc/nginx/sites-available/{{ app_name }}
# my_nginx_config

server {
    server_name {{ server_name }};
    listen 80;
    access_log /var/log/nginx/{{ app_name }}.access.log;
    error_log /var/log/nginx/{{ app_name }}.error.log;
    location / {
        uwsgi_pass  unix:///tmp/{{ app_name }}.sock;
        include     uwsgi_params;
    }
}
ansible-playbook playbook.yml -i my-inv --extra-vars "app_name=my_app server_name=myapp.com"

what do i need to run ansible?

Ansible needs to be installed. You can do that with:

pip install ansible

You need to be able to log in to to our hosts via SSH. If you cannot use your default key, you must specify the key to use. Once you can connect, Ansible will take care of the rest.

what about the agent?

With other automation tools you need to install agents on every hosts before being able to perform any tasks. This increases the surface for attackers, from a security viewpoint. From a lazy developer point of view, you have to make sure that an agent is installed and running on every host, which is not good because if something fails you have to work more.

Ansible only needs to be able to connect via SSH. You can create a new DigitalOcean or AWS EC2 instance and run exactly the same playbook with the same outcome.

is ansible limited to installing packages?

Ansible has over 200 core modules, where apt is just one of them.

You can do anything from making sure that a package is installed to creating a new EC2 instance on the fly.

Other examples are:

  • Clone/checkout your repository
  • Create configuration files based on variables
  • Create directories and assign permissions
  • Verify that your services are running
  • Be called Mr. DevOpsRockStar

Going further

At Swapps we use Codeship for Continuous Integration. It runs the tests for our projects and notifies our "ops" server on success if the code checked belongs to one of our main branches.

The ops server then takes the commit id and deploy it to our servers automatically. Normally we use develop for our staging instances and master for production.

In short, we deploy with a git push.

Going further

There are other tools that you may use for the integrations and the setup of a continuous delivery pipeline. As that is a topic for another day, i will leave just a list for now if you are interested on digging deeper:

 

  • Codeship ($40/month)
  • Jenkins (OpenSource, for Integration)
  • Rundeck (OpenSource, can be used to run and monitor ansible tasks)
  • AnsibleTower (Propietary, Expensive as f*** but seems to be the best tool on that market, free trial for up to 10 servers)

shameless advertising

Swapps is hiring! You can find information on https://www.swapps.io/jobs/

Made with Slides.com