Deploying Ubuntu on Rackspace using Fog and Cloud-Init

This post is an amalgamation of Vladimir Vuksan’s Provision to cloud in 5 minutes using fog (EC2-specific) and Jeff Gran’s Bootstrapping an Ubuntu Server on Rackspace Using Cloud-Init and Fog – I contributed little more than (inexpertly) gluing them together.

Assuming you already have the Fog gem installed:

First, as a prerequisite and as Jeff Gran notes, you’ll need to create a Rackspace image with the cloud-init package installed.

Next, similar to what Vladimir Vuksan describes, create a config.rb file, and populate the following values as appropriate for your environment:

#!/usr/bin/env ruby

@flavor_id = 3
@image_id = 1234567

@rackspace_username =  'example'
@rackspace_api_key = '1234....'

@private_key_path = './ssh/id_rsa'
@public_key_path = './ssh/'

The flavor_id values and image_id specify the instance size and the image you built with cloud-init installed (see the “fog” executable’s “Compute[:rackspace].flavors” and “Compute[:rackspace].images”, respectively); the Rackspace username and api_key can be retrieved from within the console under “Your Account: API Access.” The SSH key pair will be what you use to access the new instance as root.

Third, create a cloud-init user_data file ERB template; place it in ./cloud-init/user_data.erb; for example:

apt_upgrade: true
hostname: <%= hostname %>

- emacs
- git
- puppet


#  rsa_private: |
#  rsa_public:
#  dsa_private: |
#  dsa_public:

Finally, the script you launch to deploy Rackspace images is as follows:

#!/usr/bin/env ruby

# Based on:
# as well as:

require 'erb'
require 'optparse'

require 'rubygems'

require 'fog'
require 'mime'

# Parse options:
options = {}

optparse = do|opts|
  opts.banner = 'Usage new_instance.rb [options]'

  options[:name] = ''
  opts.on( '-n', '--name INSTANCE_NAME', 'Instance name (default:' ) do|n|
    options[:name] = n || ''

  options[:user_data] = './cloud-init/user_data.erb'
  opts.on( '-u', '--userdata USER_DATA', 'Path to Cloud-Init user_data ERB template (default: ./cloud-init/user_data.erb)' ) do |u|
    options[:user_data] = u || './cloud-init/user_data.erb'

  opts.on( '-h', '--help', 'Display this help message' ) do
    puts opts


hostname = options[:name] # to facilitate erb cloud-init template

# Create cloud-init data:

f =[:user_data])
e =
user_data =
user_data.add_entity(, 'text/plain'))

# Import Rackspace credentials:
require './config.rb'

# Connect to Rackspace:
connection ={ 
  :provider           => 'Rackspace',
  :rackspace_api_key  => @rackspace_api_key, 
  :rackspace_username => @rackspace_username

# Launch instance:
puts "Launching instance '#{options[:name]}'..."

server = connection.servers.bootstrap({
  :flavor_id        => @flavor_id,
  :image_id         => @image_id,
  :name             => hostname,
  :personality      => [ { 'path'     => '/var/lib/cloud/seed/nocloud-net/user-data',
                           'contents' => user_data.to_s }, 
                         { 'path'     => '/var/lib/cloud/seed/nocloud-net/meta-data',
                           'contents' => ' ' } ],
  :private_key_path => @private_key_path,
  :public_key_path  => @public_key_path

puts "Instance launched at #{server.public_ip_address()}"

Launch it with the “-h” flag to see usage; otherwise, launch it with no arguments to launch an instance with your default options.



  1. Andy

    I actually opened a ticket about this; apparently it’s a “known issue that has been occuring since [Rackspace’s] recent deployment [of] Xen Server technology” but they consider it “an infrastructural problem that isn’t necessarily a show-stopper” with no official estimate of resolution. (I was told it might be “solved or worked-around before January.”)

  2. Pingback: Snake Byte Kit » Looking at Ruby Fog