An Introduction to Ansible

I would encourage you to read the excellent Ansible Documentation rather than my rather condensed (and possibly inaccurate) notes below: these are intended primarily as a reminder to me.

Setup

  • the default hosts file for Ansible is /etc/ansible/hosts ... which I don't usually use as I keep playbooks in a git repo and the hosts file should stay in the repo too ... which means using -i hosts all the time (haven't found a workaround for that yet, although I'm considering a soft link)
  • accessing remote hosts without ssh keys can be done ... but is no fun at all, and is STRONGLY discouraged (it's a serious pain, as you have to log into every host, sometimes more than once ...)
  • for a host to be accessible to Ansible, it needs a) an ssh key, and b) the sudo command (this may not be essential, but is highly recommended). What the remote host does NOT need is Ansible!

Ad Hoc Commands

Ansible is mostly meant to be used for playbooks, sometimes quite complex, that change a remote machine's state significantly (commonly to equip it with web server software and then duplicate a code repository onto it, but there are many, many other uses for it). But it can also run "ad hoc" commands, running a single command on a small set of hosts. And if you're just learning, this is definitely where to start.

First, a hosts file:

[test]
ansy

[webservers]
apachea
apacheb

A broken command to point out a significant pitfall: ansible all -a "/bin/echo ${HOSTNAME}" . The problem here is that ${HOSTNAME} will be interpreted by your local machine before it ever gets to the remote machine. In this case, an effective replacement is ansible all -a '/bin/hostname' . A little experimentation showed the local environment variables, or anything that looks like one, is a bad idea to use (or try to access within Ansible). There's a specific module for running stuff in the shell: ansible all -m shell -a 'echo $SHELL' - note the single quotes to protect the $SHELL from local shell interpretation. I haven't experimented with this much, but it didn't seem to work terribly well.

The previous commands could be run by any user. Now consider one that has to be an administrator: ansible test -a '/sbin/reboot' -u root , where "test" selects the group of computers from the hosts file and -u root says to become root on the remote machine. Another option is to modify the hosts file to something like this:

[test]
ansy ansible_ssh_user=root

But I think I prefer to set the user in playbooks, not by host.

File Handling

To copy a file: ansible all -m copy -a "src=gemcheck dest=/root/" . Without explicit instructions, this arrives on the remote machine with the default permissions of the remote user. That can be changed by adding details like mode=600, owner=sound, or group=sys. You can also create directories, delete full trees, etc.

Package Handling

Ansible understands both apt and yum by default, and they'd like you to believe it supports many others. Someone has even written one to support OpenWRT's opkg (ansible-module-extras), but as I write SliTaz's tazpkg doesn't appear to be supported. Too bad, considering how much I've been playing with SliTaz recently. But then, most people wouldn't look on it as an option for a server OS, and Ansible is mostly about servers. ansible all -m apt -a "name=vim state=present will either confirm that vim is present on all hosts or install it. "state" can also be "latest" or "absent". In an ad hoc context I'm not sure that "latest" always works: it implies the need for an apt-get update on the remote host. In a playbook this seems to work, but in ad hoc I think it doesn't bother with the "update". You can add update_cache=yes to force the update.