Eat the elephant
At first sight, you may wonder what is the best automation tool that will be useful for our OpenStack "production day". We have already chosen Git and Jenkins to handle our continuous and delivery code infrastructure. It is time to choose the right tool for automation.
Eventually, it might be difficult to select the right tool. Most likely, you'll have to choose between several of them. Covering all the existing IT automation tools could fill an entire book or even books. Therefore, giving succinct hints on different tools might be helpful in order to distinguish the best outfit for certain particular setups. Of course, we are still talking about large infrastructures with heterogeneous systems, a lot of networking, and distributed services.
Giving the chance for one or more tools to be selected as system management parties can be effective and fast for our deployment. We will use Chef for the next deployment phase.
Preparing the infrastructure code environment
If you are not familiar with the Git command line, do not worry, because we will use an integrated development environment (such as Eclipse), which provides a great Git plugin.
Note
Later, we will need to write and maintain code written in the Ruby programming language. Chef cookbooks are written in Ruby. Feel free to use your best development environment that supports and simplifies code branching and maintenance within your VCS. There are plenty of preferences for development environments and Ruby code editors, such as RubyMine (https://www.jetbrains.com/ruby/) and Komodo (http://komodoide.com/). The Netbeans IDE also comes up with a Ruby plugin (http://plugins.netbeans.org/plugin/38549/ruby-and-rails) and the Sublime text editor (http://www.sublimetext.com/) can be a good candidate for a lightweight text editor for code.
Feel free to use any Linux distribution. The next setup will use CentOS 6.5 64 bit as the standard operating system.
Ensure that Java and its dependencies are installed:
packtpub@dev$ sudo yum install java packtpub@dev$ sudo yum install gcc-c++
You can download Eclipse for CentOS from here:
packtpub@dev$ wget http://mirror.netcologne.de/eclipse/technology/ epp/downloads/ release/juno/SR2/eclipse-automotive-juno-SR2-incubation-linux-gtk-x86_64.tar.gz
Extract the Eclipse to the /opt
directory:
packtpub@dev$ sudo tar -xvzf eclipse-automotive-juno-SR2-incubation-linux-gtk-x86_64.tar.gz -C /opt/
Create a symlink:
packtpub@dev$ sudo ln -s /opt/eclipse/eclipse /usr/bin/eclipse
To install Ruby, you need to go from the Eclipse menu bar and navigate to Help | Install New Software. From the pending list, navigate to Program Languages | Dynamic Languages Toolkit - Ruby Development Tools:
Install Git:
packtpub@dev$ sudo yum install git
Check the correctness of the Git installation:
packtpub@chef$ git --version
Bring the magic EGit plugin into the action link in order to develop with Git in Eclipse. We do this in the same way from the Eclipse update manager by navigating to the Help | Install new Software menu entry. You will need to add the following URL installation to EGit:
http://download.eclipse.org/egit/updates
You will then see the following screen:
If you are not familiar with Chef, the following section will cover the basic setup and the most important parts of a Chef server, and you can see how it looks.
Tip
If you do not have the Ruby plugin installed in your Eclipse environment by default, you can download and install it from SourceForge at http://sourceforge.net/projects/rubyeclipse/files/rdt/0.8.0/org.rubypeople.rdt-0.8.0.604272100PRD.zip/download?use_mirror=freefr&download=.
The Chef environment
When you think about a typical chef, you may think of cookbooks, recipes, and knives! These are what a chef needs in order to make awesome dishes. The taste of the food on a plate depends on the creativity of the chef. We do the same thing in terms of cooking: we use a basic cookbook, from which we derive the right recipes. We refine the recipes till we get what fulfills our needs.
Let's see how Chef defines its awesomeness:
- Cookbook: The grained unit of the configuration in Chef describes the kind of scenario that is there, and how it should be defined in order to deploy an application in a node.
- Recipe: This is the part of a cookbook that is authored in Ruby and defines the configuration of the nodes. Note that a recipe can use or be used by another recipe.
- Node: This is where we can apply the cookbook configurations.
- Role: This can be considered as a logical function for a node. It can be customized within a collection of recipes and cookbooks, in a particular order.
- Attribute files: The attributes are very important in order to change the settings of the nodes.
Note
You should take into consideration the precedence level of the attributes that define what should be applied. Basically, the evaluation of such attributes against the node object will be done during each Chef run.
Keep the previous terms in your mind, but do not be surprised when you start to find much more than these terms during our deployment. We will cover them in a nutshell.
Tip
To read more about Chef, you can refer to the official Opscode website: https://docs.chef.io/.
Prerequisites for settings
Before installing the server, we need to set up the right hostname of our CentOS box, where we can define it as an FQDN with a domain suffix:
- Open the
/etc/sysconfig/network
file and modify theHOSTNAME
value to match your FQDN hostname:packtpub@chef$ sudo nano /etc/sysconfig/network HOSTNAME=chef.packtpub.com
- Change the host that is associated to your IP address for your server found in the
/etc/hosts
file, as follows:packtpub@chef$ sudo nano /etc/hosts 192.168.47.10 chef.packtpub.com chef
- Check your hostname via the following command:
packtpub@chef$ hostname -f chef.packtpub.com
- Make sure that your changes are persistent on reboot:
packtpub@chef$ sudo /etc/init.d/network restart
Note
You will need to adjust the settings, such as the hostname, FQDN, and IP address, to suit your needs.
- As we are using CentOS, it will be much easier for a smooth installation process in order to modify iptables and SELinux. Note that it is not recommended that you entirely disable the
iptables
service in a production environment where you will have to create extra iptables rules and update your SELinux as well. We will need to allow access to the following ports:- TCP ports:
80
,443
for the Chef server web user interface - TCP port:
4000
for the Chef server Knife access
The following commands will update the running iptables rules in your CentOS box:
packtpub@chef$ sudo iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT packtpub@chef$ sudo iptables -A INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT packtpub@chef$ sudo iptables -A INPUT -p tcp --dport 4000 -m state --state NEW,ESTABLISHED -j ACCEPT
- TCP ports:
- Save the new policy update and restart the
iptables
service:packtpub@chef$ sudo service iptables save packtpub@chef$ sudo service iptables restart
- Set SELinux to the permissive mode:
packtpub@chef$ sudo setenforce 0
The Chef server installation
The next setup describes some simple steps to install the Chef server:
- In your local shell, run the following command to download the Chef server:
packtpub@chef$ sudo rpm -ivh https://opscode-omnibus packages.s3.amazonaws.com/el/6/x86_64/chef-server-11.0.8-1.el6.x86_64.rpm
- Configure the Chef server:
packtpub@chef$ sudo chef-server-ctl reconfigure
- Check whether the installation was successful or not:
packtpub@chef$ sudo chef-server-ctl test Finished in 0.11742 seconds 0 examples, 0 failures
- The server should be up and running. You can access the web interface via
https://chef.packtpub.com:443
:
Tip
The Chef server user interface can be accessed using the FQDN edited previously: https://FQDN:443
. You can use https://CHEF_IP_ADDR:443
, where CHEF_IP_ADDR
is the local IP address of your Chef server.
Enter admin
as the username and p@ssw0d1
as the default password.
Workstation installation
We will need additionally one or more Chef workstation(s) as a development toolkit. This node's role is as follows:
- The Chef client is installed and Knife is configured
- It holds the local repository for the Chef server
- It installs Chef on the nodes via the knife bootstrap operation
- It dictates nodes, roles, and infrastructure environments to be uploaded to the Chef server
Our Chef workstation will hold the local repo, and then we can install it on our VCS node, where all the development will be performed and then uploaded to the Chef server.
Note
Knife in Chef refers to a tool which provides a Command-Line Interface (CLI) between a Chef server and the Chef repository. It can be installed in a Chef workstation and used to manage nodes, roles, cookbooks, and environments with the Chef server. To read more about Knife in Chef, refer to this link https://docs.chef.io/knife.html.
Let's install our Chef workstation:
- Get the Chef client installed:
packtpub@workstation$ curl -L https://www.opscode.com/chef/ install.sh | bash
- Verify the installation:
packtpub@workstation$ chef-client -v
- Create your chef-repos for a proper format of the Chef repository from GitHub by cloning the structure in
/home/packtpub/
:packtpub@workstation$ git clone https://github.com/ opscode/chef-repo.git packtpub@workstation$ cd /home/packtpub packtpub@workstation$ mkdir -p /chef-repo/.chef
In order to authenticate against the Chef server, we will need to add some inputs for the key files from the Chef server web interface. Go to the Clients tab and click on Edit with the chef-validator client.
- Copy the value of the Private key field. In your workstation, create a new file for the validator key:
packtpub@workstation$ vi /home/packtpub/chef-repo/.chef/chef-validator.pem
- Paste the content of the copied key and save and close the file.
We perform the same procedure to generate the admin user's key file. In the Users tab, click on Edit, which is associated with the admin user, and check Regenerate Private Key followed by Save User.
After copying the private key, create a new file admin.pem
in /home/packtpub/chef-repo/.chef/
again and paste the content of the admin's private key:
- Create the Knife configuration file:
packtpub@workstation$ knife configure -i Overwrite /root/.chef/knife.rb? (Y/N) y Please enter the chef server URL: [https://test.example.com:443] https://chef-server.packtpub.com:443/ Please enter a name for the new user: [root] packtpub Please enter the existing admin name: [admin] Enter Please enter the location of the existing admin's private key: [/etc/chefserver/admin.pem] /home/packtpub/chef-repo/.chef/admin.pem Please enter the validation clientname: [chef-validator] Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] /home/packtpub/chef-repo/.chef/chef-validator.pem Please enter the path to a chef repository (or leave blank): Creating initial API user... Please enter a password for the new user Created user[pack-knife] Configuration file written to /home/packtpub/chef-repo/.chef/ knife.rb
At the end, you should have the following list of files:
packtpub@workstation$ ls /home/packtpub/chef-repo/.chef/ admin.pem chef-validator.pem knife.rb pack-knife.pem
- Initialize our Git name and e-mail:
packtpub@workstation$ git config --global user.email "masteropenstack@packtpub.com" packtpub@workstation$ git config --global user.name "masteropenstack"
- Clean up the repository by adding the
.chef
line to .gitignore
:packtpub@workstation$ nano /home/packtpub/chef repo/.chef/.gitignore .rake_test_cache .chef/*.pem .chef/encrypted_data_bag_secret .chef
- Add and commit the current repository:
packtpub@workstation$ git add . packtpub@workstation$ git commit -m 'Finish setting up'
- Make sure that you are using the right Ruby version:
packtpub@workstation$ vi .bash_profile packtpub@workstation$ echo 'export PATH="/opt/chef/embedded/bin:$PATH"' >> ~/.bash_profile
- Populate the bash profile settings:
packtpub@workstation$ source ~/.bash_profile
- Test our workstation's Chef server connection:
packtpub@workstation$ knife user list admin packt-knife
Time to cook OpenStack
At this stage, we have a complete Chef environment where the OpenStack code infrastructure will be developed, refined, and released to production.
Let's take a look at the environment topology again. We need nodes and instances to test how our cookbooks will be applied and tested.
For this purpose, we will use a great tool for testing purposes: Vagrant.
Note
Vagrant is open source software used to build virtualized development environments. Vagrant requires virtual machines to test Chef Cookbooks before going to production. VirtualBox is a good candidate which works together with Vagrant to provide a complete test environment. For more information on Vagrant, refer to the following link https://docs.vagrantup.com/v2/getting-started/.
Vagrant can be integrated with Chef. Then, from a Vagrant file, we push the button to make Chef run and get instances up, which makes it the cat's meow.
Where is my kitchen?
Be aware that Vagrant will be used for test purposes. This amazing tool will help you make sure you know how your OpenStack Chef cookbooks work.
This is a suitable test for the virtual machine manager candidate to achieve a clean state from your nodes. Furthermore, it might be possible to reproduce a whole test environment in each Chef run, which creates an initial state that mimics a production environment.
You can manage VMs by means of Vagrant using VirtualBox while using a Chef client as a provisioner. Then, we have our test development environment: the OpenStack kitchen. We will describe the use case of Vagrant later in this chapter.
OpenStack cookbooks
There are always challenges facing DevOps, and no doubt, they will occur after you have conducted your design to be deployed in a real environment. Meeting these challenges will drive you to acquire new skills related to creating a large complicated OpenStack infrastructure with simple code that you never thought you could master.
Several organizations and big companies have been involved in writing cookbooks for OpenStack in different ways. You might be tempted to think how you can use the existing cookbooks in the cookbook market as well as which ones to choose and how to develop them for your own needs.
Let's discuss what we need with the help of a simple, generic overview:
- Controller nodes
- Compute nodes
- Neutron nodes
- Swift as a single cluster
You may note that the controller node, as described in our first design, handles and runs the majority of native OpenStack services. You can derive many recipes from OpenStack cookbooks in GitHub. The Opscode community is also an option. We will base our first cookbooks on StackForge cookbooks. However, before that, we should take care of the cookbook dependencies for a clean setup.
Note
StackForge aims to facilitate the usage of the OpenStack infrastructure by other projects, including continuous integration (Jenkins) and repository mirroring (GitHub). More information on the StackForge project can be found at http://ci.openstack.org/stackforge.html.
Inpidual cookbooks for each OpenStack service have been created in the StackForge GitHub repository, which can be found at https://github.com/stackforge. The cookbooks used by Chef from the StackForge repository are listed and described at https://docs.chef.io/openstack_cookbooks.html.
Resolving OpenStack cookbook dependencies
Without any doubt, the world of dependency is a world of pain! This is when you plan to install a cookbook that another one depends on it. Manual downloading for each one might depend on other cookbooks.
A trick for manual downloading can be to use the knife cookbook site install
command, which is somehow great as it installs all the dependencies. However, the dependencies will be installed in your local repository, and you might not like to see them flapping in your directory. You will be delighted when you find out that there is a tool that can do this for you: Berkshelf.
This amazing cookbook manager downloads all dependencies recursively while keeping your local repository clean. Dependencies will be stored in a different location.
Berkshelf uses Berksfile, in which we commit our dependencies to our repository.
The first successful step to make this tool do the magic, is to ensure a proper installation. Somehow, Ruby versioning can be confusing if you have already installed Chef server or Chef workstation within Ruby version 1.8.7. It is recommended that you upgrade or switch to 1.9.1 or higher. Note that Berkshelf requires Ruby version 1.9.1 or higher.
If you already have 1.8.7, no worries; we will perform a trick without ping into Ruby setup errors.
We can use Ruby Version Manager (rvm) to switch between Ruby versions.
Note
Ruby is a very popular programming language that is used by Chef to write cookbooks. Different versions of Ruby may be necessary for different projects. Installing and running other Ruby gems (RubyGems) might require different Ruby versions. Using the rvm will allow you to easily install multiple, contained versions of Ruby and switch between them. For more information on rvm, refer to this link: https://rvm.io/rvm/basics.
- Install rvm:
packtpub@workstation$ curl -L get.rvm.io | bash -s stable fails
Note
If you get an error issued you will need to specify the
gpg2
key. You will need to run a similar command line from the output shown in the curl command as follows:gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
. - Source the rvm variables:
packtpub@workstation$ source /etc/profile.d/rvm.sh
- Install Ruby 1.9.2:
packtpub@workstation$ rvm install 1.9.2
- Set it as the default Ruby interpreter:
packtpub@workstation$ rvm --default use 1.9.2
- Install gem dependencies:
packtpub@workstation$ sudo yum install rubygems
- Install Berkshelf dependencies:
packtpub@workstation$ sudo yum install gecode-devel gcc-c++ -y
- Install Berkshelf :
packtpub@workstation$ gem install berkshelf Fetching: nio4r-1.0.1.gem (100%) Building native extensions. This could take a while...
Knife's command line will start to complain about the Ruby version when you fire it in your shell. Thus, you can always reset your default Ruby version 1.8.7 using this:
packtpub@workstation$ rvm system
Uploading cookbooks using Berkshelf
Let's create our main Berkshelf file, which will define all the cookbooks needed for our first deployment. We will tell Berkshelf to clone the cookbooks and their dependencies mainly from supermarket.getchef.com:
packtpub@workstation$ nano /home/packtpub/chef-repo/Berksfile source "https://supermarket.getchef.com" cookbook 'apache2', '1.9.6' cookbook 'apt', '2.3.8' cookbook 'aws', '2.1.1' cookbook 'build-essential', '1.4.2' cookbook 'database', '2.2.0' cookbook 'erlang', '1.4.2' cookbook 'memcached', '1.7.2' cookbook 'mysql', '5.4.4' cookbook 'mysql-chef_gem', '0.0.4' cookbook 'openssl', '1.1.0' cookbook 'postgresql', '3.3.4' cookbook 'python', '1.4.6' cookbook 'rabbitmq', '3.0.4' cookbook 'xfs', '1.1.0' cookbook 'yum', '3.1.4' cookbook 'selinux', '0.7.2' cookbook 'yum-epel', '0.3.4' cookbook 'galera', '0.4.1' cookbook 'haproxy', '1.6.6' cookbook 'keepalived', '1.2.0' cookbook 'statsd', github: 'att-cloud/cookbook-statsd' cookbook 'openstack-block-storage', github: 'stackforge/cookbook-openstack-block-storage' cookbook 'openstack-common', github: 'stackforge/cookbook-openstack-common' cookbook 'openstack-compute', github: 'stackforge/cookbook-openstack-compute' cookbook 'openstack-dashboard', github: 'stackforge/cookbook-openstack-dashboard' cookbook 'openstack-identity', github: 'stackforge/cookbook-openstack-identity' cookbook 'openstack-image', github: 'stackforge/cookbook-openstack-image' cookbook 'openstack-network', github: 'stackforge/cookbook-openstack-network' cookbook 'openstack-object-storage', github: 'stackforge/cookbook-openstack-object-storage' cookbook 'openstack-ops-database', github: 'stackforge/cookbook-openstack-ops-database' cookbook 'openstack-ops-messaging', github: 'stackforge/cookbook-openstack-ops-messaging'
Then, you need to just upload cookbooks as the following:
packtpub@workstation/home/packtpub/chef-repo $ berks install Resolving cookbook dependencies... packtpub@workstation/home/packtpub/chef-repo $ berks upload --no-ssl-verify
Defining roles
Chef defines roles as a manner to group nodes, seeking simplicity deployment. From run lists in all nodes, you will just need to assign the node that should be run. Optionally, you will be able to customize them by overriding attribute values within your roles. On the other hand, recipes define roles. Thus, you may notice the running of a list of a bunch of recipes within a role. Besides, it can also include roles from other run lists.
Let's cover a basic example using only recipes in the role run list within OpenStack. In your chef-repo
directory, create a new directory named roles
.
Create the role:
$ nano roles/packtpub-os-base.json
Eventually, the packtpub-os-base
role defines the base role of OpenStack nodes that will be assigned to the majority of servers in our deployment. It provides common attributes and recipes that define the OpenStack deployment, such as setting network interfaces of hosts within the existing endpoints:
{ "name": "packtpub-os-base.json", "description": "PacktPub OpenStack Base Role", "json_class": "Chef::Role", "default_attributes": { }, "override_attributes": { }, "chef_type": "role", "run_list": [ "recipe[openstack-common]", "recipe[openstack-common::logging]", "recipe[openstack-common::set_endpoints_by_interface]", "recipe[openstack-common::sysctl]" ], "env_run_lists": { } }
Let's carry on with the second role using the previous one.
Create a new role named packtpub-os-compute-worker.json
. This role will define our OpenStack compute node:
{ "name": "packtpub-os-compute-worker", "description": "PacktPub OpenStack Compute Role", "json_class": "Chef::Role", "default_attributes": { }, "override_attributes": { }, "chef_type": "role", "run_list": [ "role[packtpub-os-base]", "recipe[openstack-compute::compute]" ], "env_run_lists": { } }
You might notice that we have used the base role, packtpub-os-base
, within the compute recipe that we have uploaded in our Chef.
At this point, feel free to add any role that will fit your design from our basic cookbooks added from supermarket.getchef.com. Distributing roles will depend on your choice and the number of nodes you plan to deploy for a certain service. We can assume that any change to a certain node deployment will be made from the Chef code.
In our custom design, we will need a controller node, which will run a bunch of services. A good practical design of cookbooks is to wisely break down your infrastructure into reusable roles and recipes. For example, our controller node will include networking, imaging, messaging, identity, and database services; going on making a one blob role which includes all the associated recipes might limit your attention and make you think about scaling out the nodes later. Remember that we are expanding and not rolling up the infrastructure.
Before creating our custom controller role, we will proceed by creating a basic one:
packtpub-os-base-controller
{
"name": "packtpub-os-base-controller",
"description": "PacktPub OpenStack Controller Role",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
},
"chef_type": "role",
"run_list": [
"role[packtpub-os-base]",
"role[packtpub-os-ops-database]",
"recipe[openstack-ops-database::openstack-db]",
"role[packtpub-os-ops-messaging]",
"role[packtpub-os-identity]",
"role[packtpub-os-image]",
"role[packtpub-os-compute-setup]",
"role[packtpub-os-compute-conductor]",
"role[packtpub-os-compute-scheduler]",
"role[packtpub-os-compute-api]",
"role[packtpub-os-block-storage]",
"role[packtpub-os-compute-cert]",
"role[packtpub-os-compute-vncproxy]",
"role[packtpub-os-dashboard]"
],
"env_run_lists": {
}
}
To upload all your created roles, you can use the following command:
packtpub@workstation$ knife role from file /home/packtpub/chef-cookbooks/roles/*.rb
Tip
The basic cookbooks for OpenStack have been downloaded from https://github.com/stackforge. It is recommended that before starting your Chef deployment, you have to verify the roles and their names, the number of environments and their names. A good practice while customizing a cookbook or defining an OpenStack environment in Chef is to add as many thin roles as possible. If you face any error-naming convention while running Chef, try to adjust the role names in attribute files to reflect the same names within the defined roles.
Configuring the environment
Now we have a set of cookbooks uploaded to the Chef server and ready to be deployed. An extra step is needed to make them useful: Defining your environments. Note that we define the playground environment using Vagrant, where we will provision our test infrastructure, and the cooking environment, where we define our infrastructure details from one file and let Chef do the rest:
- Playground environment: Until now, we have our basic cookbooks ready to be uploaded within defined roles. They need customization and more development to adjust our infrastructure needs.
Vagrant might be a very cost-effective and the simplest solution to make a full test environment work together with Chef.
We can use a provider for Vagrant as a VirtualBox, where it can be installed as a virtual machine while our provisioner will be Chef.
Note
Provisioning with Vagrant can also be performed using Puppet, and the providers can be VMware and Amazon AWS.
You can download and install Vagrant from http://downloads.vagrantup.com:
packtpub@workstation$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.7.2_x86_64.rpm packtpub@workstation$ rpm –ivh vagrant_1.7.2_x86_64.rpm packtpub@workstation$ vagrant --version Vagrant version 1.7.2
Note
VirtualBox needs to be installed as a Vagrant provider. VMware is also a second alternative to run Vagrant boxes.
- Vagrantfile: The vagrant file will define all our OpenStack nodes and the general configuration, such as networking:
packtpub@workstation$ nano /home/packtpub/chef-repo/Vagrantfile
The contents of the Vagrant file are:
Vagrant.require_version ">= 1.1" Vagrant.configure("2") do |config| # Omnibus plugin configuration config.omnibus.chef_version = :latest # OpenStack settings chef_environment = "vagrant-packtpub" controller_run_list = [ "role[packtpub-os-base-controller]", "recipe[openstack-network::identity_registration]", "role[packtpub-os-network-openvswitch]", "role[packtpub-os-network-dhcp-agent]", "role[packtpub-os-network-metadata-agent]", "role[packtpub-os-network-server]" ] # virtualbox provider settings config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--cpus", 2] vb.customize ["modifyvm", :id, "--memory", 2048] vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"] vb.customize ["modifyvm", :id, "--nicpromisc3", "allow-all"] end # OpenStack Controller config.vm.define :controller1 do |controller1| controller1.vm.hostname = "controller1" controller1.vm.box = "opscode-centos-6.5" controller1.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box" controller1.vm.network "forwarded_port", guest: 443, host: 9443 # forward to dashboard using ssl : dashboard-ssl controller1.vm.network "forwarded_port", guest: 8773, host: 9773 # forward to EC2 api : compute-ec2-api controller1.vm.network "forwarded_port", guest: 8774, host: 9774 # forward to Compute API : compute-api controller1.vm.network "private_network", ip: "192.168.47.10" controller1.vm.network "private_network", ip: "172.16.11.10" controller1.vm.provision :chef_client do |chef| chef.run_list = controller_run_list chef.environment = chef_environment # Where to find our Chef Server by providing the authorization key chef.chef_server_url = "https://chef.packtpub.com:443" chef.validation_key_path = "/home/packtpub/chef repo/.chef/chef-validator.pem" end end # OpenStack Compute config.vm.define :compute1 do |compute1| compute1.vm.hostname = "compute1" compute1.vm.box = "opscode-centos-6.5" compute1.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box" compute1.vm.network "private_network", ip: "192.168.47.11" compute1.vm.network "private_network", ip: "172.16.11.11" compute1.vm.provision :chef_client do |chef| chef.run_list = [ "role[packtpub-os-compute-worker]" ] chef.environment = chef_environment # Where to find our Chef Server by providing the authorization key chef.chef_server_url = "https://chef.packtpub.com:443" chef.validation_key_path = "/home/packtpub/chef-repo/.chef/chef-validator.pem" end end end
- Cooking environment: We need to define our Chef environment to accomplish the environment setup within Vagrant.
Note
Use different environments for development and production to maintain cookbook changes in isolation.
You can create a development environment in many ways; from the Chef server GUI or via the Knife command line, as follows:
# knife environment create vagrant-packtpub -d "PacktPub Testing Environment"
Our Chef environment file looks like the following:
{ "name": "vagrant-packtpub", "description": "PacktPub Testing Environment", "cookbook_versions": { }, "json_class": "Chef::Environment", "chef_type": "environment", "default_attributes": { }, "override_attributes": { "mysql": { "allow_remote_root": true, "root_network_acl": "%" }, "openstack": { "identity": { "bind_interface": "eth1" }, "endpoints": { "host": "192.168.47.10", "mq": { "host": "192.168.47.10" }, "db": { "host": "192.168.47.10" }, "developer_mode": true, "network": { "debug": "True", "dhcp": { "enable_isolated_metadata": "True" }, "metadata": { "nova_metadata_ip": "192.168.47.10" }, "openvswitch": { "network_vlan_ranges": "physnet1:1000:2999", "tenant_network_type": "vlan", "external_network_bridge_interface": "eth2" }, "api": { "bind_interface": "eth1" } }, "image": { "api": { "bind_interface": "eth1" }, "registry": { "bind_interface": "eth1" }, "image_upload": true, "upload_images": [ "centos", "cirros" ], "upload_image": { "centos": "http://cloud.centos.org/centos/7/devel/ CentOS-7-Atomic-CloudDockerHost-20140820_05.qcow2", "cirros": "https://launchpad.net/cirros/trunk/0.3.0/ +download/cirros-0.3.0-x86_64-disk.img" } }, "compute": { "xvpvnc_proxy": { "bind_interface": "eth1" }, "novnc_proxy": { "bind_interface": "eth1" }, "libvirt": { "virt_type": "qemu" }, "network": { "public_interface": "eth1", "service_type": "neutron" }, "config": { "ram_allocation_ratio": 5.0 } } } } } }
As we are using version control, it might be more convenient to create a new directory under
chef-repo
named;environments
, which will hold our environments.Additionally, this will help us test cookbooks in different versions with several specific attributes and bring them from development to staging, finishing with promoting them into production. Under
chef-repo
, create anenvironments
directory, where thevagrant-packtpub.rb
file will be placed:packtpub@workstation:/chef repo$ git add environments/vagrant-packtpub.rb packtpub@workstation:/chef repo$ git commit -a -m "First OpenStack Environment" packtpub@workstation:/chef repo$ git push
Now, you can create the environment on the Chef server from our
vagrant-packtpub.rb
file by the means of the Knife command line:packtpub@workstation:/chef repo$ knife environment from file vagrant-packtpub.rb
- Push the button: At this point, we've done a lot of preparation and configuration to test and deploy OpenStack. Vagrant and Chef work in tandem with each other to bring a test environment with less pain and more simplicity. Everything is in place; what we need to do is to just push the button.
Set an environment file to specify which Vagrantfile to use:
packtpub@workstation $ export VAGRANT_VAGRANTFILE=vagrant-packtpub
Start the nodes:
packtpub@workstation $ vagrant up controller1 packtpub@workstation $ vagrant up compute1