Delightful Local Development Environments with Chef and Vagrant - Part 2
This series of articles was written to support the development efforts of Kasasa LTD in Austin, TX. Though your tech stack may differ, you should be able to used this series as a way to set up your own teams’ development environment in your organization.
The goal of the series is to have a fully functional development environment with a basic understanding of the concepts of virtualization and configuration management with Chef .
Table of Contents
- Hello Vagrant!
- Provisioner Basics
- ChefDK and the Chef Provisioner
- Launching EC2 Instances with Knife
- Cookbook Authoring
- Using Community Cookbooks and Berkshelf
- Testing Infrastrucutre with Test Kitchen
- Team Coding with Chef
- Multiple Guests with Vagrant
Goals for this Article
At the end of this article you should have acomplished the following tasks:
- Demonstrate the disposability of this environment
- Use the Vagrant SHELL provisioner to configure the guest machine
- Use Vagrant networking to have a simple Hello World! applicaiton respond in our browser.
- Show that you can develop locally and have your changes show up via the guest runtime environment.
- Show that you can onboard to a new project in minutes.
First Princples
For this article it will be important to keep these definitions straight:
- A “provisioner” is a Vagrant construct that allows access to the guest for a set of headless commands to run. This is how a guest gets automatically configured
- A “provider” is the software (Virtualbox) used to provide the hypervisor for Vagrant to launch machine in.
In reality the above is quite a jump in implementation. Nobody uses a base Ubuntu install. We have to install our runtime, monitoring agents, logging paradigm, etc.
Hello Again Vagrant
Before we get to configuring our guest, let’s justify the work we just did and are about to do.
In our last article we created the directory ~/kumbaya
and initialized Vagrant there. Move back to this directory and make sure you are in the same state as this article.
What Happened?
Since we were in an unknown state, it was a good idea to check on the status of the guest. Your results will vary, but they will be descriptive. Take the time to read the output.
Regardless of the state of the guest we took the decsion to destroy it. In the case above there was no guest running to Vagrant tells me this is the case.
Finally we start a new guest.
You have just completely trashed and recreated your runtime environment. Consider how long it would take to do this on the bespoke set up most developers have on their workstations (rather than guest).
–
If you were to share this repo with me, I could easily clone it, start the guest and add value. Consider this on a team of five developers. An update to the runtime environment is a simple pull. The guest can be destroyed at any time without losing a single line of code!
Wait, that is not true. Right now we would have to log in and configure the machine at the CLI. This would be manual, error prone and generally not useful.
Let’s make it true.
Sharing Configuration
Let’s set up this guest to run a Python applicaiton. The Flask Mega Tutorial is some of the best writing out there, so we will leverage it.
First lets’s update our Vagrantfile to do a bit more.
Paste the above into your ~/kumbaya/Vagrantfile
and issue a vagrant provision
command. This time things take much longer and there 100’s of lines of green output.
What Happened?
When Vagrant launches the guest, it assigns it a private IP adderss of 10.42.42.10. This will help with local development. Scroll up into the white output and find where the IP assignment happens.
After Vagrant launched the guest, it executed the shell commands found in the provisioner section of the file.
–
Gotcha!
This is a powerful demonstration, but its a very blunt instrument. You should not attempt to re-run the SHELL provisioner because there is no guarentee that any shell command will have the expected effect a second time through. Better to destroy the machine and vagrant up
again for now.
Destroying and “upping” gets to be time consuming. In a future article, Chef will replace the generic shell provider to address this very problem.
–
It should now be clear that you are able to install a run time - Python’s Flask in this case - and work with anyone on your team to contribute to the run time. This exact shell script can be used to configure the production application servers. Envrionment parity for the win!
Hello Flask
Let’s create a simple “Hello World” application with Flask. First we need to lay down three python files:
~/kumbaya/run.py
~/kumbaya/app/__init__.py
~/kumbaya/app/views.py
If you were running the Flask application on your workstation, you would have to visit the address 127.0.0.1:5000
, but we have configure Vagrant to explicitly use the IP address 10.42.42.10.
In order to see the results you should start up the app from the guest:
behemphi:~/kumbaya 21:42:53 > vagrant ssh
vagrant@vagrant-ubuntu-trusty-64:~$ export FLASK_APP=/vagrant/run.py
vagrant@vagrant-ubuntu-trusty-64:~$ export FLASK_DEBUG=1
vagrant@vagrant-ubuntu-trusty-64:~$ python -m flask run --host=0.0.0.0
* Serving Flask app "run"
* Forcing debug mode on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 311-149-961
What Happened?
From inside the guest you started the application.
Verify it is running by browsing to [http://10.42.42.10:5000/](http://10.42.42.10:5000)
–
Develop Local Run Virtual
With the flask application running, open the file ~/kumbaya/app/views.py
and change the “Hello World!” text to “Hello Vagrant, would you like a Flask?” and save.
You will see output like the following:
* Detected change in '/vagrant/app/views.py', reloading
* Restarting with stat
* Debugger is active!
* Debugger pin code: 311-149-961
Refresh the browser and your new message will appear.
What Happened?
The Flask process saw the files change on the guest even though you changed them on the workstation. This is because Vagrant mounted the workstation location ~/kumbaya/
to the guest location /vagrant
.
–
New Developer Workflow
Let’s move you personal version of kumbaya
out of the way with mv ~/kumbaya ~/kumbyebye
.
Let’s assume for a moment you are a new hire on the kumbaya project. As a team we have agreed to keep our projects in our home directory. To get started developing on the Project Kumbaya:
As an exercise, move in to the kumbaya
directory, start the guest and change the, “Hello world!” message as we did above.
What Happened!
With Vagrant set up, you just onboarded yourself to a project in less than 5 minutes.
–
Wrapping Up
You have thrown the environment away then restored it in moments. Using the SHELL provisioner, you updated the OS and added a python runtime environment. To ensure it is easy to find the machine, you assigned it a private IP on your local machine.
With a production-like machine running, you ran the code mounted from your workstation via the guest. You manipulated the text of a message and saw the result in the browser.
Finally, to prove it all over again, you threw away not just the runtime environment, but the application as well. You cloned my repo and performed the same set of actions, thus proving you are truly able to onboard yourself to a new project in minutes.
Looking Forward
In the next article we will install the Chef Development Kit (ChefDK) and wire it in to Vagrant. This will allow us to become more sophisticated in how we configure our runtime environment.