Ever since getting serious in documenting my install process for my developer machine, I've found that while executing the steps themselves is fairly quick, it still takes me hours to get all the other applications I use on a daily basis downloaded and installed. While browsing my Twitter stream, I came across the pivotal_workstation project on GitHub. While I had some experience with automated provisioning systems like Chef and Puppet, it never occured to me that it might be the solution to this exact problem. In this blogpost I will outline all the different components involved, how to setup your computer with these tools and how to contribute to make this project even better.
Chef and soloist
Let's start at the beginning. If you want to install program X, you need some kind of recipe that describes all the steps that need to be taken to do this. For example, download the .dmg from this url, open it and copy the .app to /Applications. This is what cookbooks are for. Cookbooks are a collection of recipes that contain these instructions. I mentioned such a cookbook before, pivotal_workstation is one of these cookbooks. These recipes are written in Ruby so they should be easy to follow. More on them later.
Now the Chef application is the one that takes these recipes and executes them. The Chef application uses a json configuration file that describes what cookbooks and recipes to use. This json file can either come from a Chef server (so you can manage your cookbooks in one location and every computer or server will get the information from that location) or it can run as “Chef Solo” locally without the Chef server. This Chef Solo mode is the one I use since setting up a computer is mostly a one shot business.
There is only one issue with Chef Solo, manually crafting the json configuration is a real pain. But ofcourse there is a solution in the form of a gem called Soloist. Soloist uses a clean and easy to understand configuration file in YAML and uses this to execute and configure Chef Solo. An example soloistrc:
Apart from installing XCode, building these soloistrc's is the only manual work you need to do to install a fully operational developer machine. But even that part is easy since there is a soloistrc-builder webapp available.
Let's setup our brand new computer.
First off, let's install the Command Line Tools to be able to use GIT and compile stuff. You can go for either the Command Line Tools for Xcode that contain just basics, or go for the full Xcode. If you go for the full Xcode, you still need to install the Command Line Tools but it is easy to do under Preferences > Downloads.
Next, all the rest in one fell swoop:
Done… Kind of an anticlimax, but hey, this is why I use this system. Let's go into some details so you understand what is going on.
The bootstrap file
I've included an extract of the bootstrap file below. It does 5 things.
- make sure soloist and it's dependencies (like chef) are installed
- create a cookbooks folder in your homedir
- write a soloistrc file, it is this list that you need to build to create your own perfect environment. This list is way larger in the bootstrap file used in the oneliner above.
- clone and pull all the cookbooks that are needed
- run soloist
Making it your own
The pivotal_workstation cookbook is used by the employees of Pivotal and does what they want it to do. The roderik_workstation cookbook, is my own personal preference. These are not necessarily your perfect settings. To keep it manageable I suggest you fork the pivotal_workstation cookbook (like I've done and I use my own fork in the bootstrap file) and either fork roderik_workstation or create your own _workstation repo where you put your own settings. This will give you all the flexibility to contribute (more later on) and to make your own choices.
There are some useful things you might want to know when you are customising, lots of recipes have a related attributes file. These contain configurable settings that you can override in your own cookbook. For example the Sublime Text packages I want to install, by using node.override and setting my own array, it uses my config over the pivotal one.
Contributing is very easy, the guys at Pivotal are very responsive in approving pull requests and there are so many recipes in this cookbook that 99% of the things can be done with some creative copy pasting (I'm not a Ruby programmer, nor am I very familiar with Chef, and yet I was able to become one of the biggest contributers to this project). The only discipline you need it to never install an app without trying to write it as a recipe first.
At this point I will show some signature recipes, so you can get started immediately and hopefuly skip some trail and error steps I had to take :)
Installing from Homebrew
Just include the
pivotal_workstation::homebrew recipe and use brew_install with the packagename. Easy!
Installing from DMG
Copy the alfred.rb recipe you see below, change all the references to the app, the download location, update the checksum (sha256), messages and you add it to your soloistrc/bootstrap.sh file.
Important, If you use
dmg_package "Alfred" it expects the DMG to be called Alfred.dmg, the mounted volume at /Volumes/Alfred and the app to be called Alfred.app. This is not the case with Alfred, the volume is named Alfred.app so we added the volumes_dir line. Some DMG files have an EULA, you can disable this by using
accept_eula true like in the OmniGraffle recipe Sometimes the dmg name is different, then you use
dmg_name "googlechrome" like in the Google Chrome recipe. You won't need this for most dmg files.
Installing from ZIP
Copy the 1password.rb recipe you see below, change all the references to the app, the download location, update the checksum (sha256), messages and you add it to your soloistrc/bootstrap.sh file.
Using Chef to automate all these tasks for me has been a revalation for me, while i'm sure that there will be many many improvements in the next months, I've found that this system allows me te exactly recreate and configure my developer environment. But as always, some things are still missing. Triggering installs from the App Store, entering licences, configuring Mail.app etc. All things to research in the future. If I find anything of note, be sure to expect followups.