Chef and Product versions- provisioning environments for different product versions


I am new to chef and am currently getting my head around it. We are currently using chef solo in a windows environment. We have product releases every 3 months. Chef is used in our organisation to setup production build environments, developer machines etc. The setup of these environments involves installing a bunch of developer tools such as Visual Studio, 3rd party software etc. This list of tools/software required to setup the environment can keep on changing across releases. For example: If product release 1.0 requires Visual Studio 2015 to be setup, product release 2.0 might require Visual Studio 2015 Update 1 and so on.
The way we make use of chef is as follows:
-End user logs on to the server and launches a Powershell console with admin privileges.
-A Powershell script is executed. This script first installs chef solo on the client machine and copies all the chef scripts locally.
-The chef scripts are then executed to setup the developer build environment.

Here is my requirement: I did like to make use of chef to recreate the production build environment/developer build environment for a particular release.
For example:
A developer would like to create the build environment for Product release 1.0. The chef scripts should handle this requirement. If the developer should like to create the developer environment for product release 2.0, the chef scripts should handle this as well.

Is this possible using Chef? I assume this is possible since Chef scripts can be versioned. If so, what is the way to achieve this using Chef? Any help would be very much appreciated. Please guide me towards a best practice.

One way i was thinking is that, we could label the chef scripts for every product version in our source control(Perforce). This way, whenever we want to set up the developer environment for a particular product version, we pull the associated scripts for that product version by making use of the label and setup the environment.
However, this doesn’t seem like a good enough approach.
So, i am looking for help here.



I’m sure there are several practices that would work here but here is how I have done this in the past and would likely repeat again. I would create a single wrapper cookbook that leverages all of the cookbooks you use to configure your environments. I would version this cookbook in lock step to your application versions. Both production and developer environments could converge the correct version of this cookbook to produce the desired environment.

For the development environment cases I would take this a step further and create a vagrantfile that provisions a VM from the cookbook.This way developers simply need to vagrant up from the correct Vagrantfile and the environment will be provisioned for them. Here is an example vagrantfile that I used to use to provision boxes from a chef recipie:


Hello Matt,

@Matt_Wrock: Thanks for responding back.
I have a couple of more questions:
-We use Perforce as our source control systems.
-We are using Chef Solo.

I understand your idea of making use of a wrapper cookbook and versioning it in sync with my application versions.

However what i don’t understand is that, how do i get the correct version of the cookbook from the source control system(Perforce), when the user wants to create a development environment for a particular product version?

I expect the user to just execute a Powershell script with a parameter. This parameter would very likely be the product version for which he wants the development environment to be created. This powershell script can be executed just about anywhere: on a VM or a workstation etc. Also, the assumption here is that a VM or a workstation already exists where this powershell script would be executed to create the development environment by installing the necessary tools.

Also, since we use Chef Solo, how do i go about enforcing such cookbook version constraints? I believe with Chef Solo we don’t have the luxury of a database server where the cookbook version meta data is saved.

I have been suggested a wide variety of choices such as environments, Policy files etc. However, i am not sure if these approaches are feasible given that i use chef solo.



I have not used perforce, but I imagine you can check out a tag or branch representing a version of your cookbook. As for dependent cookbooks and their versoins, you can lock down your dependencies with policy files of berkshelf using chef solo and pull down those dependent cookbooks locally using those mechanisms.

I personally like using vagrant if I want to guarantee the state of a dev environment. Converging over an existing environment leaves alot of room for failure. However, you know your environment best. Any way you do it, you can wrap up everything inside of powershell.