"Everything should be made as simple as possible, but no simpler"

-- Albert Einstein

Ansible is a configuration management, provisioning and work flow automation tool that is written in python. I've been playing around with for a little while and it's a rather refreshing change from the other configuration management tools I've spent time with (Puppet & Chef). Ansible is extremely simple to use and understand, so I thought it was time to write up some of my notes to help anyone getting to grips with using it on the Rackspace Public Cloud.


Firstly, you need to install it. You can use your own distributions package manager or alternatively just pull it with the python package manager - pip:

pip install ansible

Create an inventory file, which lists the servers you will be managing. We're going to add the local system first as we are calling the Rackspace API remotely, so this is carried out from our local machine.

mkdir -p /etc/ansible
cat <<EOF >/etc/ansible/hosts
localhost ansible_connection=local

This simple inventory file just adds the local system and sets the connection type to local so that Ansible knows it doesn't need to SSH to the server.

Let's test it!

ansible -m ping local

This 'ping' test simply runs an Ansible connection ping (not a TCP ping) to test the connection to the server, in most cases this would SSH into the server to test the connection but as this is local it's a lot more simple.

You should see something like this:

root@ansible-bastion:~# ansible -m ping local 
localhost | success >> {
    "changed": false,
    "ping": "pong"

See Getting Started for more info.

Spinning up a Rackspace cloud server

Ansible is not just a configuration management tool, in fact if you use it only for configuration, you are missing a trick.

There are hundreds of pre-built modules and some of these modules can enable you to provision and orchestrate servers in many of the well known public cloud platforms such as AWS and Rackspace Public Cloud. By linking Configuration Management and Provisioning together, you can achieve a very powerful deployment model for your applications.

In this example, we'll use a playbook to spin up a Rackspace Cloud server. A playbook is a YAML file written in Ansible's own configuration management language and the way you orchestrate multiple tasks, much like a Chef cookbook or Puppet module/recipe, it contains 'plays' and underneath a play you also have a tasks and actions.

Setting up the Rackspace SDK

First we need to install pyrax, the Rackspace Cloud Python SDK. This allows Ansible to use native python modules to control Rackspace cloud resources. Why a Rackspace specific SDK and not the Python OpenStack/nova-client equivilent? Well, underneath it uses similar API calls but at the same time there are quite a few Rackspace cloud specific items that are not part of OpenStack either due to API differences or augmented services that were around before OpenStack equivalents (for example ). The SDK bundles the common bits but then all the additional extras required for other Rackspace services.

Install pyrax:

pip install pyrax

Setup your "~/.rackspace_cloud_credentials" file, all of these details are available from the Cloud Control Panel:

username=<your username>
api_key=<your API key>
region=<your region>

Now to create the playbook, here's one I made earlier which I've added a ton of comments to:

- name: Build a Cloud Server # The name of this play
  hosts: localhost # Target local host
  connection: local # No remote connections, run actions locally
  gather_facts: False # This gathers useful facts from remote hosts, not required on localhost
  tasks: # All of the separate tasks we are going to carry out, in this case just one
    - name: Server build request # The name of the task
      local_action: # Always run this on the local machine not a remote machine
        module: rax # Rackspace Cloud module which is part of ansible core
        credentials: ~/creds # Rackspace cloud credentials file we created above
        name: test-server # Name of the cloud server 
        flavor: general1-1 # 1GB server - see for a list of flavors
        image: 892b9bab-a11e-4d16-b4bd-ab9494ed7b78 # Image ID for Debian Sid, pulled from 'nova image-list'
        region: LON # London Region
        key_name: ansible-bastion # SSH Keypair, use 'nova keypair-add' to upload one to RS Cloud
        wait: no # Do not wait for server to build, return immediately
        state: present # Create the server
        networks: # These are the two different default networks on Rackspace cloud
          - private # Rackspace service net
          - public # Rackspace public net
      register: rax # Save the result of the command in the rax variable for use in a later tasks

To run the playbook, we use the ansible-playbook command, not the Ansible command:

ansible-playbook launch-server.yaml

The output should look something like:

root@ansible-bastion:~# ansible-playbook launch-server.yaml

PLAY [Build a Cloud Server] ***************************************************

TASK: [Server build request] **************************************************
changed: [localhost ->]

PLAY RECAP ********************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0


Whoo! We launched our first instance with Ansible! However, we don't have the IP of the server, so this isn't particularly useful yet.

If you login to the Rackspace Cloud Control Panel, you should be able to see that it has successfully been launched.

In my next post I'll tie it all together to configure a simple service on the instance.

In the meantime, a ton of information is covered in the Ansible Rackspace Guide.


comments powered by Disqus