Ansible tips and tricks

I wonder how many people in Vietnam know DevOps. Not everyone even agrees on what the term DevOps even means. There's no Vietnamese ops or devops community and very few people talking about it. But DevOps is something any full stack web developer needs to master nowadays, and it goes beyond being able to set up and sysadmin a Linux server.  Here I'll take devops to mean the procedures for setting up the servers which will run your organizations (web) applications, mostly in the cloud.

Ansible, Puppet, Chef: server orchestration tools using Ruby, except Ansible which is in Python, with configuration-code in Yaml. I like Python more than Ruby so I chose Ansible. (I had good feelings about the future of Ansible at the time, and then RedHat bought them at $100 million and now I'm not so sure.)

Using Ansible
- Intro: Server provisioning tools like Chef, Puppet, or Ansible, help sysadmins (or developers who are now taking over responsibility as part of "devops") but this hasn't erased the need to understand how software is installed on servers. A lot of what I've done using Ansible was deciding how to configure a service and then encapsulating it in an Ansible "role". What I would like to do is plug in best practices for each of number compatible services and only need to tweak what I know I need. The Ansible community is big but not quite that mature yet. As recipes and roles mature, hopefully more of us can use off-the-shelf server configurations with less intimate server knowledge required. This is where things are headed, but slowly. Even when one can take some service configuration (Ansible role) off GitHub and plug it into one's personal playbook one still needs to understand the way the author of the role set up any exposed variables, and this can vary from author to author (although there is a proper /vars/ subdirectory where such variables should go).

config.vm.provision "ansible" do |ansible|

-Use with Vagrant. Vagrant supports "provisioners" which set up the software on Vagrant boxes after bringing them up. So Ansible plugs right in. It stays in a separate directory, but ansible.cfg can use hosts specified in Vagrant-created files, and so Vagrant knows what host to connect to when running "vagrant provision". At first, don't worry about the coupling between Vagrant and Ansible, as you can run either independently - Vagrant to build the box, Ansible to install all the software that didn't come with the OS image. If you do use the "provider" config then you can run 'vagrant provision' which will automatically run your main Ansible playbook on your Vagrant hosts.

- Clone roles from GitHub links which you can find at Ansible Galaxy. I like to just clone the role's repository into my own Ansible roles tree directly rather than having the Galaxy tool download to your system first and then your code be dependent on your system's installed roles. It's just simpler for me to think of them as a handful of files which I have a snapshot of. Role naming, if from another user, is <user>.<role> for the directory in ./ansible/ and you might need to rename roles cloned from GitHub. There's probably 1 or a few user-contributed roles for any service/daemon you want. Beware some have dependencies on other roles (which should always be available in Galaxy) and some roles are very opinionated. The advantage to using ansible-galaxy to install locally is you have it in a cental place on your laptop and can easily copy it into a new playbook.

- There's no command to just run a single role that you may be testing. So create a secondary test playbook and run ansible-playbook on that, and just put your one role in it. 

- Your roles depend a bit on the machine they are running on. Not all Vagrant boxes are alike even if they are running the same version of Ubuntu, as there are different Ubuntu 14.04 Vagrant images (e.g. one for VirtualBox and one for DigitalOcean). You may only have a root user and run everything as root. You may have another (e.g. vagrant user) and your role could run only certain commands with the sudo arg, if Vagrant is connecting to the box as the vagrant user.

Some Ansible tips and tricks:
- If repeating a role (during development) is slow, figure out if testing for existence of a file could let you skip a step and use the stat module and register a state of that file, then later you can add 'when:' on that registered value.

- Some web-based configuration tools to generate ansible playbooks for specific stacks. E.g. phansible.
- Also check out vlad for a Drupal stack. Personally, I needed different versions of too many pieces, but still took some roles from vlad. 

- Inside your role:
- files: any files you want to copy (using the copy module) over
- handlers: like tasks that get run when required by other tasks, like restaring services
- tasks: all roles will at least have this directory
- templates: configuration files to copy over with some variable substition
- vars: usually default variables to define

Vagrant tips
- boxes are downloaded to ~/.vagrant.d/tmp and then saved to boxes when download is successful
- you can manually download a box and then vagrant box add it