Home > Blogs > OpenStack Blog for VMware


Vagrant Up with VMware Integrated OpenStack, Part 3

In Part 1, we discussed how to get Vagrant working with VMware Integrated OpenStack. In Part 2, we discussed how to setup multiple nova instances with Vagrant. In today’s article, we’ll discuss a couple useful tips and tricks to have a more productive test environment deployment, namely:

How do I specify different settings per instance?
How do I automate the configuration of my instances?

These tasks are relatively simple to achieve with Vagrant!

Instance Settings Selection

Remember in Part 2 that we discussed the ability to leverage Ruby constructs in Vagrant? Well, this applies to If-Then-Else statements too! I can use the instance’s name in my conditional statement to determine how to change the characteristics (i.e. image, flavor, etc.) for each instance.

In the example that follows, I choose the instance flavor based on the name. The master instance will most likely run software that requires increased resources. So, I specify the medium flavor (4 GB RAM and 2 vCPU) for it. For any other instances, I stick with the small flavor (2 GB RAM and 1 vCPU). See the If-Then-Else statement in the Vagrantfile sample that follows


puts "\nHave you sourced your OpenStack creds today???\n"
nodes = ['master','node1']

Vagrant.configure("2") do |config|
  config.vm.box = "openstack"
  config.ssh.private_key_path = "~/.ssh/id_rsa"
  nodes.each do |server|
    config.vm.define "#{server}" do |box|
      config.vm.provider :openstack do |os|
        os.endpoint     = "#{ENV['OS_AUTH_URL']}/tokens"      # e.g. "#{ENV['OS_AUTH_URL']}/tokens"   
        os.username     = "#{ENV['OS_USERNAME']}"          # e.g. "#{ENV['OS_USERNAME']}"
        os.tenant_name = "#{ENV['OS_TENANT_NAME']}"
        os.api_key      = "#{ENV['OS_PASSWORD']}"          # e.g. "#{ENV['OS_PASSWORD']}"
        if server == 'master'
          os.flavor = /m1.medium/ # Resource allocation for the master node
        else
          os.flavor = /m1.small/ # Resource allocation for all other nodes
        end
        os.image        = /ubuntu/                 # Regex or String
        os.keypair_name = "demo-keypair"      # as stored in Nova
        os.ssh_username = "ubuntu"           # login for the VM
        os.networks = ["demo-network"]
        os.floating_ip = :auto
        os.floating_ip_pool = "EXTNET"
      end
    end
  end
end

The next time I run the vagrant up command, I’ll see that my master and node1 instances have different resource allocations. I can verify this with the nova show command.

Vagrant Provisioners

Vagrant includes support for instance customization via provisioners such as shell scripts and popular configuration management tools like Puppet, Chef, Ansible, and Salt. In the example that follows, I use a simple shell script for each instance. I use the vm.provision command and specify the path to the shell script (it resides in the same directory as my Vagrantfile).

If you want to use a configuration management solution, you have two options:

  1. Create a custom image that contains the required binary for the tool of choice.
  2. In the Vagrantfile, specify a shell script provisioner first to install the binary, and then specify the appropriate provisioner (puppet, chef, ansible, etc.) afterwards in the Vagrantfile.

Yes, you can use a shell script AND a puppet manifest in the same Vagrantfile, and they will be executed in the order that you specify them. You can read more about provisioners on the Vagrant site. I recommend option 2 from the list above since you can avoid keeping track of an additional binary as you version control your images.

The Vagrantfile that contains the shell script provisioner is included below with the provision command highlighted in bold.


puts "\nHave you sourced your OpenStack creds today???\n"
nodes = ['master','node1']

Vagrant.configure("2") do |config|
  config.vm.box = "openstack"
  config.ssh.private_key_path = "~/.ssh/id_rsa"
  nodes.each do |server|
    config.vm.define "#{server}" do |box|
      config.vm.provider :openstack do |os|
        os.endpoint     = "#{ENV['OS_AUTH_URL']}/tokens"      # e.g. "#{ENV['OS_AUTH_URL']}/tokens"   
        os.username     = "#{ENV['OS_USERNAME']}"          # e.g. "#{ENV['OS_USERNAME']}"
        os.tenant_name = "#{ENV['OS_TENANT_NAME']}"
        os.api_key      = "#{ENV['OS_PASSWORD']}"          # e.g. "#{ENV['OS_PASSWORD']}"
        if server == 'master'
          os.flavor = /m1.medium/ # Resource allocation for the master node
        else
          os.flavor = /m1.small/ # Resource allocation for all other nodes
        end
        os.image        = /ubuntu/                 # Regex or String
        os.keypair_name = "demo-keypair"      # as stored in Nova
        os.ssh_username = "ubuntu"           # login for the VM
        os.networks = ["demo-network"]
        os.floating_ip = :auto
        os.floating_ip_pool = "EXTNET"
      end
      box.vm.provision :shell, :path => "#{server}.sh"
    end
  end
end

I use the server variable to specify individual shell scripts for each instance. So, I created master.sh and node1.sh script files. Alternatively, I could have a single file for both instances and give it a name like common.sh, for example.

When Vagrant finishes creating the instances, it rsync’s the directory containing the Vagrantfile and the shell scripts to the instances. Finally, Vagrant executes the appropriate script on each instance.

Since the script execution is automated, you want to make sure that you specify answers to any prompts that your instructions may require. For example, if I’m installing a package on Ubuntu, I use the “-y” option (ex: apt-get install -y curl). If the package that I am installing has advanced options that force a response (ex: mysql), I could use the debconf-set-selections command as well to handle this. One thing that I recommend to speed up shell provisioner execution is to decrease output to standard out using the “-q” switch (ex: apt-get install -qy curl).

Are you using Vagrant or some other automation tool with your VMware Integrated OpenStack cloud? Feel free to share your own tips and tricks in the comments section!

You can learn more about VMware Integrated OpenStack on the VMware Product Walkthrough site and on the VMware Integrated OpenStack product page.

This entry was posted in OpenStack Consumption and tagged , , , , on by .
Trevor Roberts Jr.

About Trevor Roberts Jr.

Trevor Roberts, Jr. is the Senior Technical Marketing Manager for OpenStack at VMware and the lead author of the VMware Press title, “DevOps for VMware Administrators". He enjoys speaking to customers and partners about the benefits of using OpenStack with VMware technologies. In his spare time, Trevor shares his insights on data center technologies via the VMware Blogs and on Twitter (@VMTrooper). His contributions to the IT community have garnered recognition by his designation as a VMware vExpert, Cisco Data Center Champion, and EMC Elect.

Leave a Reply

Your email address will not be published. Required fields are marked *

*