Ansible is one of the best tools in DevOps that I like, he just need a simply configuration and can help you with a lot of tasks in your day by day on your infrastructure, today I will show to you how to configure him to work with a lot of servers and how to automate some simple tasks.

Advantages of Ansible

  • Easy to use and fast response
  • Highly configurable to almost every task you need to do
  • SSH based, just use ssh-keygen, ssh-copy-id and ssh-add
  • Free software sponsored by Red Hat
  • Playbooks to make complex tasks

So how we begin use this tool?

The very first thing you need to do is obviously install Ansible on your system. You can do this by typing on linux

# yum install ansible # (redhat)
# apt-get install ansible # (debian/ubuntu)

Or on your OSX:

$ /usr/bin/ruby -e "$(curl -fsSL \
https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install ansible

The inventory file

Ansible needs a file to specify all servers you want to control, you can use a tag name to make an group  to all servers you want by category, below we set two groups: appservers and databases, note that you don’t need to specify one by one in a line, you can use regex to simplify (this is awesome!)

[appservers]
staging1.dev.yourcompany.com
staging2.dev.yourcompany.com
staging3.dev.yourcompany.com

[databases]
db[1:5].dev.yourcompany.com

After that, or perhaps before that, as told before Ansible needs a SSH master key that need to be added on /.ssh/authorize_keys file into each of your slave servers, to do that you just need to proceed like this:

$ ssh-keygen -t rsa # (to generate your key, enter until finish)

And you will get a ~/.ssh/id_rsa.pub public key file in your $HOME directory; So now you need to distribute your public-key to all servers you need control, this can be easy if you have only ten servers to administer or a pain if you have to do this in more than 100+ servers, so here’s a tip:

  • Create a file with all your servers like this:

      root@server1.dev.company.com
      root@server2.dev.company.com
    

    (I will not show to you how to make this with inventory file as input, but you can!)

  • Use this command-line to copy your keys to each server and insert root-password

      $ while read LINE; do ssh-copy-id $LINE; done < /tmp/servers
    
  • Using Ansible in command-line

All set? So lets try do something really cool here. This is the most basic syntax of ansible:

$ ansible :target: -i inventory-file :actions:

Where :target: is the group of servers in your inventory file or just an string all to contemplate all servers in your inventory, the :actions: can be a simply command like below or a more complex command-line using ansible modules.

Get all kernel versions of our servers

$ ansible all -i yourcompany.conf -u root -a “uname -a”

staging1.dev.yourcompany.com | SUCCESS | rc=0 >>
Linux staging1.dev 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

staging3.dev.yourcompany.com | SUCCESS | rc=0 >>
Linux staging3.dev 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

db2.dev.yourcompany.com | SUCCESS | rc=0 >>
Linux db2.dev 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

staging2.dev.yourcompany.com | SUCCESS | rc=0 >>
Linux staging2.dev.yourcompany.com 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
(Note that all servers responded with your kernel)

Use a default module ping to check if databases are alive

$ ansible databases -i yourcompany.conf -m ping

db1.dev.yourcompany.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
db2.dev.yourcompany.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
....

Use a default module apt to install a mysql database

$ ansible databases -i yourcompany.conf \ -m apt -a “name=mysql-server state=latest”

So how can I know what modules are available?

They are listed here -> http://docs.ansible.com/ansible/list_of_all_modules.html

Playbooks: The real thing

Okay, now you know that you can send commands and use modules to process in all your servers with just one command line, thats cool! But what really amazing in Ansible are the playbooks! A playbook is just a file with a template engine called YAML and Jinja to apply some filters, variables and others, with that you can do a lot of automate complex tasks in your servers. Lets take a look into a sample file called ‘install_apache.yml’:

---
- hosts: appservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: install or upgrade apache to latest version
    yum: name=httpd state=latest
  - name: write the apache config file
    template: src=./httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running (and enable it at boot)
    service: name=httpd state=started enabled=yes
  handlers:
    - name: restart apache
      service: name=httpd state=restarted
  • hosts -> means that all these tasks will only be executed in the group defined after the word, here appservers, defined by our inventory file in the begin of this post.
  • vars -> are variables you define to process tasks with it, note that variables are defined line by line.
  • remote_user -> another way to use -u root without need to put in cmd.
  • name -> is just a name you define to implement a task
  • template -> in this case is just a way to say, copy my source file defined as ./httpd.j2 to destination server on /etc/httpd.conf
  • notify -> is a tag that call a job (restart apache) in handlers block at the end of execution of the current block

Or, to resume this playbook will:

  • Install the latest version of httpd apache on all your appservers *Copy your local httpd.j2 file to remote server on /etc/httpd.conf
  • Put your variables where you set in httpd.j2 file
  • Restart apache after that
  • Set apache to run automatically after a boot/reboot

As you see you can do a lot with this, without this you would need to enter in each server and make these tasks one by one without any human mistake, with ansible you just need to type this:

$ ansible-playbook -i yourcompany.conf install_apache.yml

On next time we will show to you how to do more complex examples, best practices and directory structure to help on your day tasks.

Thats it for now! What are you waiting for? Use ansible to automate your tasks now!! :)