Ansible is a configuration management tool much like Chef and Puppet. The main difference is that Ansible pushes all configuration over SSH, whereas Chef/Puppet/Salt pull configuration using clients installed on the targets. Ansible has only two requirements:

  1. SSH

  2. Python needs to be installed on the targets

To install Ansible on FreeBSD 10:

yes | pkg install ansible

The above will also install Python as a requirement. Check what version was actually installed:

ansible --version

You should get something like this:

ansible 1.6.2

On FreeBSD Ansible expects to find it's host database (known as the inventory) under /usr/local/etc/ansible/hosts - however that directory doesn't exist so we'll go ahead and create it:

mkdir /usr/local/etc/ansible

Now create /usr/local/etc/ansible/hosts with any editor and add a single line for each machine you want to use as a target, in our case the target will be an Ubuntu 14 LTS system which is at 192.168.2.8

This is what my /usr/local/etc/ansible/hosts file now looks like:

cat /usr/local/etc/ansible/hosts

Output:

192.168.2.8

Before we go ahead and do anything fancy let's see if Ansible can reach the host. Ansible uses SSH for all communications so we'll need to either set up an SSH key or a password to login. In this case I'll go ahead and copy my id_rsa.pub to Ubuntu so we won't be bothered by passwords:

1. Start the ssh-agent for the C Shell:

exec ssh-agent csh

2. Add your SSH key to the agent:

ssh-add

You should get something like this:

Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

3. Now use the ssh-copy-id command to copy the key across:

ssh-copy-id -o StrictHostKeyChecking=no lampros@192.168.2.8

In the above:

-o StrictHostKeyChecking=no = disables strict host checking (the famous: "The authenticity of host '192.168.2.15 (192.168.2.15)' can't be established." message) - this is naturally not recommended for production environments

lampros = the username I used in this case, replace with yours

Now that we can SSH into the target, let's run an ad-hoc command with Ansible:

ansible all -m ping -u lampros

Explanation of the above:

all = run the command on all hosts in the inventory

-m ping = use the ping module, this performs an SSH "ping", basically just tries to connect over SSH

-u lampros = the remote user to connect as

Running the above I got:

192.168.2.8 | FAILED >> {
    "failed": true,
    "msg": "/bin/sh: 1: /usr/local/bin/python: not foundrn",
    "parsed": false
}

What happened here? Ansible has one requirement on target hosts and that is that Python is installed - in this case Python IS installed, but where is Python on the target? Let's ask!

ssh lampros@192.168.2.8 which python

Output:

/usr/bin/python

So this proves that Python is installed on the target but it's on a different directory than where FreeBSD expects it to be which is /usr/local/bin/python - how do we solve this?

Edit the hosts file /usr/local/etc/ansible/hosts again and add this next to the IP address:

ansible_python_interpreter=/usr/bin/python

So now the line looks like this:

192.168.2.15 ansible_python_interpreter=/usr/bin/python

Re-run the ansible command:

ansible all -m ping -u lampros

Output:

192.168.2.8 | success >> {
    "changed": false,
    "ping": "pong"
}

Much better! Now try sending a command over Ansible, for example let's ask for the output of 'uptime':

ansible all -u lampros -m command -a "uptime"

Output:

192.168.2.8 | success | rc=0 >>
 19:20:15 up 3 min,  2 users,  load average: 0.21, 0.35, 0.17