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/id_rsa.pub'
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:
#cloud-config apt_upgrade: true hostname: <%= hostname %> packages: - emacs - git - puppet #runcmd: #ssh_keys: # 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: # http://blog.vuksan.com/2010/07/20/provision-to-cloud-in-5-minutes-using-fog/ # as well as: # http://jeffgran.com/276/blog/ubuntu-cloud-init-rackspace-fog-ruby require 'erb' require 'optparse' require 'rubygems' require 'fog' require 'mime' # Parse options: options = {} optparse = OptionParser.new do|opts| opts.banner = 'Usage new_instance.rb [options]' options[:name] = 'rax.example.com' opts.on( '-n', '--name INSTANCE_NAME', 'Instance name (default: rax.example.com)' ) do|n| options[:name] = n || 'rax.example.com' end 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' end opts.on( '-h', '--help', 'Display this help message' ) do puts opts exit end end optparse.parse! hostname = options[:name] # to facilitate erb cloud-init template # Create cloud-init data: f = File.new(options[:user_data]) e = ERB.new(f.read) user_data = MIME::MultipartMedia::Mixed.new user_data.add_entity(MIME::TextMedia.new(e.result, 'text/plain')) # Import Rackspace credentials: require './config.rb' # Connect to Rackspace: connection = Fog::Compute.new({ :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.
Have you tried this with Lucid? After installing cloud-init on my base image, it takes 20 minutes or more to provision a new instance.
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.”)