Tag Archives: list

Getting Image and Flavor information from the Rackspace API

At Gamevy we’re lucky enough to have been accepted onto the Rackspace UK Startup Programme. In combination with that, we’ve been using Ansible to deploy new servers, and perform application deployments.

When you create a new server at Rackspace using Ansible rax module there are two pieces of information you’ll need from Rackspace. One of those is the flavor, this defines the instance type (the configuration of the instance – e.g. how much RAM it is given). The second is the id of the image (operating system) you wish to use to create the server.

To date, we’ve not found an easy way to get this information. Our current method is to use cUrl, get an Access Token, and to then make further requests to the API to get the required information.

Given this is an infrequent task, I normally forget the necessary steps. I thought that by noting them down I might save myself, and others, some time in the future. This post assumes that you already have a Rackspace account, and that you have API access via a key which is associated with your account. If that’s not the case, Sign Up here, and then follow these steps to get your API key.

It’s worth noting that this post focuses on accessing functionality provided by Rackspace UK. If you’re accessing from the US, the steps are the same, but  you’ll need to change the URLs that are accessed. Full information about Rackspace’s API can be found at their documentation site.

Getting An Auth Token

First things first, let’s get an Auth Token. To do this, you’ll need a few pieces of information from your Rackspace account: your username, your API Key and your account number.

Login to your Cloud Control Panel, and in the top right hand corner of the screen you’ll see your username with an arrow pointing down next to it. Clicking on that will reveal a menu at the top of which will be your account number, note that down, you’ll need when you make calls to the API, later.

From the menu, select Account Settings. On the resulting screen, access your API secret and note that too.

Create a file, call it whatever you want, I called mine rackspace-creds.json on your machine (I put mine in my home directory, for ease of access). The file should contain the following:

{
    "auth":
    {
        "RAX-KSKEY:apiKeyCredentials":
        {
            "username": "YOUR_RACKSPACE_USERNAME",
            "apiKey": "YOUR_RACKSPACE_API_KEY"
        }
    }
}

To get your Auth Token, open up a terminal and issue the following command

curl https://identity.api.rackspacecloud.com/v2.0/tokens -X 'POST' \
-d @rackspace-creds.json -H "Content-Type: application/json" | python -m json.tool

I’ve piped the output of the cUrl command through python’s json tool to prettify it. In the response you receive, you’ll need to grab your :

"token": {
            "RAX-AUTH:authenticatedBy": [
                "APIKEY"
            ],
            "expires": "",
            "id": "YOUR_AUTH_TOKEN",
            "tenant": {
                "id": "",
                "name": ""
            }
}

List The Flavors And Images Available To You

Now that you’ve got an Auth Token, you can go ahead and make calls to the API endpoints for Flavors and Images. I’ve pasted the corresponding examples below:

Flavors

curl https://lon.servers.api.rackspacecloud.com/v2/YOUR_ACCOUNT_ID/flavors \
> -H "X-Auth-Token: YOUR_AUTH_TOKEN" | python -m json.tool

Images

curl https://lon.servers.api.rackspacecloud.com/v2/YOUR_ACCOUNT_ID/flavors \
> -H "X-Auth-Token: YOUR_AUTH_TOKEN" | python -m json.tool

 

Tagged , , , , , , , ,

Iterating an ansible task using a dictionary object of variables

Recently we have been writing ansible scripts to deploy one of our applications. In doing so, we came across the need to configure 3 node processes as services. All of these node processes used a similar init script but required different values writing into the script.

We chose to use the template task thinking that with the 4 variables we needed to populate on each occasion we should be able to use the with_items method on the task to do what we wanted. We did plenty of Googling and couldn’t find a way forward and so were all set to revert to writing three separate implementations of the template task, and three associated templates.

Asking a question on the ansible IRC channel eventually yielded an answer and I thought I would share our implementation.

We start with a generic template, service_init_script.j2. The script itself is not important to this blog post, you should note that way in which the ansible ( / jinja2) variables refer to item.foo – this is important, and was our initial stumbling block. Each time the task is iterated upon the items within the with_items block are referred to as an item:

#!/bin/bash
### BEGIN INIT INFO
 # Provides: {{ item.service_name }}
 # Required-Start: $all
 # Required-Stop: $all
 # Default-Start: 2 3 4 5
 # Default-Stop: 0 1 6
 # Short-Description: {{ item.service_description }}
 ### END INIT INFO
# Taken loosely from https://gist.github.com/tilfin/5004848
 prgcmd={{ item.service_exec }} # What gets executed?
 prgname={{ item.service_name }} # What's the name (used to ensure only one instance is running)
 prguser={{ item.service_user }} # Which user should be used
 pidfile=/var/run/{{ item.service_name }}.pid # Where should the pid file be stored?
 logfile=/var/log/{{ item.service_name }}.log
export BJA_CONFIG={{ bja_config }}
start() {
 if [ -f $pidfile ]; then
 pid=`cat $pidfile`
 kill -0 $pid >& /dev/null
 if [ $? -eq 0 ]; then
 echo "{{ item.service_name }} has already been started."
 return 1
 fi
 fi
echo -n "Starting {{ item.service_name }}"
nohup start-stop-daemon -c $prguser -n $prgname -p $pidfile -m --exec /usr/bin/env --start $prgcmd >> $logfile 2>&1 &
if [ $? -eq 0 ]; then
 echo "."
 return 0
 else
 echo "Failed to start {{ item.service_name }}."
 return 1
 fi
 }
stop() {
if [ ! -f $pidfile ]; then
 echo "{{ item.service_name }} not started."
 return 1
 fi
echo -n "Stopping {{ item.service_name }}."
start-stop-daemon -p $pidfile --stop
if [ $? -ne 0 ]; then
 echo "Failed to stop {{ item.service_name }}."
 return 1
 fi
rm $pidfile
 echo "."
 }
status() {
if [ -f $pidfile ]; then
 pid=`cat $pidfile`
 kill -0 $pid >& /dev/null
 if [ $? -eq 0 ]; then
 echo "{{ item.service_name }} running. (PID: ${pid})"
 return 0
 else
 echo "{{ item.service_name }} might have crashed. (PID: ${pid} file remains)"
 return 1
 fi
 else
 echo "{{ item.service_name }} not started."
 return 0
 fi
 }
restart() {
 stop
 if [ $? -ne 0 ]; then
 return 1
 fi
sleep 2
start
 return $?
 }
case "$1" in
 start | stop | status | restart)
 $1
 ;;
 *)
 echo "Usage: $0 {start|stop|status|restart}"
 exit 2
 esac
exit $?

We then wrote our ansible script and call the template task thus:

- name: Create the service init scripts
template: src=service_init_script.j2 dest=/etc/init.d/{{ item.service_name }} owner=root group=root mode=755
with_items:
- { service_name: paymentHandler, service_description: 'Handles payments', service_user: blackjack_attack, service_exec: "{{ application_directory }}/apps/paymentHandler.js" }
- { service_name: tablePool, service_description: 'The pool of tables available', service_user: blackjack_attack, service_exec: "{{ application_directory }}/apps/tablePool.js" }
- { service_name: userManager, service_description: 'Manages users', service_user: blackjack_attack, service_exec: "{{ application_directory }}/apps/userManager.js" }
sudo: yes

So, we are calling the same template task, which in turn refers to the same jinja2 template, passing in a collection of dictionary objects.

The key point to understand here is that when the playbook is run ansible enumerates the items specified referring to each object as ‘item’. This is the reason why we had to prefix the variable names in the template with item.*

I’ve exposed both of these pieces of code as gists here, and here.

Tagged , , , , , , , ,