Controlling Vcloud with Ruby via Fog

We recently decided that we wanted to automate VM deployment on an internal cloud running VMware’s Vcloud product. Our current tooling is in Ruby using the Fog library. This didn’t support Vcloud 1.0 properly however, so we added this. This post will present a quick rundown on how to use this to deploy & manage VMs using this

0. Installing Fog

The code has been accepted in the upstream project, and is waiting the next release after 0.9.0. For now, we can install the gem either using your projects Gemfile, or build and install the gem from source.

Using a Gemfile:

gem "fog", :git => "https://github.com/geemus/fog.git"

Build and install the Gem:

git clone https://github.com/geemus/fog.git
cd fog
gem build fog.gemspec
gem install fog*.gem

1.  Getting Started

You will need to have a working VCloud environment, and a user to connect to this with. You will also need to create a VApp template to use as the base for new VMs. While VCloud allows composing VApps from multiple VMs to form a ‘templated’ environment, this differs from how EC2 and other cloud environments work (VMs are a singular item) so we keep things simple and consistent. Create a new VApp containing a single VM, then export it to a template. Note the exact name of this template.

2. Interacting with the API

You can run this in an irb session, or create a script utilising it.

First, we’ll require fog and get a connection to the service.

require 'fog'
compute = Fog::Compute.new(:provider => 'vcloud',
                           :vcloud_username => 'user@organization',
                           :vcloud_password => 'password')

Next, let’s list the VDC’s to ensure that one is available.

compute.vdcs

You should see output with a list of VDC’s. From now in we will just use the first in the list, you can adjust code to suit.

Now, we can find the template’s URI, and create an instance of it.

template_href = Vcloud.vdcs.first.catalogs.item_by_name "<name of template we created>"
svr = compute.vdcs.first.server.create :catalog_item_uri => template_href,
                                 :name => 'test vm'

This command starts a job on the server to instantiate the template.  This call will return once the job starts, however our VM won’t be ready to work with yet, so we wait for the creation to complete.

svr.wait_for(1200) { print '.' ; ready? }

This will wait up till 20 minutes for the job to complete and the server to be ready.

Once the server is ready, we can adjust the amount of RAM allocated to the image (it will inherit the amount set in the template), and add a second 4gb disk to the VM. We have to save and wait for the operation to complete for each action, changes can’t be batched.

svr.memory = 768
svr.save
svr.wait_for { ready? }
svr.add_disk(4096)
svr.save
svr.wait_for { ready? }

Now, we can power on the VM, and display some info on it.

svr.power_on
svr.wait_for { on? }
svr.wait_for { ready? }
p svr

Once we are done, we can shut the server down. On Vcloud you also need to undeploy the server – this releases the memory and CPU reservations.

svr.undeploy
svr.wait_for { off? }
svr.wait_for { ready? }

You can always look up the servers by calling

compute.vdcs.first.servers

Lastly, if you want to delete the server, you can call

svr.destroy

3. Conclusion

This covers the basics of the vcloud-specific implementation. More information on fog can be found at http://fog.io . If you have any questions or comments, please let us know. This code is always under improvement as we and others use this in out systems, so keep an eye on the github fog repository for the latest functionality.