The Chef documentation
assumes you have an entire server farm to manage, so it hits you with a lot of
complexity. If all you want is to set up and maintain a single VM, this
tutorial will help.
This is the cloud
We will be creating “throwaway” VMs that we can recreate with a single call. If you need to have a single server system persist for years across all changes, you should perhaps check out Puppet for a less cloudy solution.
Using Amazon EC2?
Any fresh instance of an Ubuntu AMI will do, for example
ami-06ad526f (11.04, 32-bit EBS in us-east-1).
Hint: The EC2 API tools are (by nature) complex and error-prone, so I recommend you stay with the point-and-click web interface for as long as possible, instead of trying to automate launching new instances.
Hint 2: Create a separate EBS volume as a data partition to hold your databases, etc.
Hint 3: Use Elastic IPs for all your instances.
All you need is
- a laptop with Bash and SSH (no need to even install Chef), and
- any vanilla Linux server that you can SSH into.
Why do we run against vanilla servers? In my opinion, the system your
deployment scripts run against should be as minimal possible, essentially
straight from the vendor. So instead of manually installing packages like Chef
and then creating a snapshot to instantiate our VMs from, we will use a freshly
installed system and make the entire process scripted. On the downside, we need
some bootstrapping code (~30 LOC), but on the upside we get more repeatability
and less maintenance overhead, and we stay independent from any specific cloud
or virtualization provider.
Since we only have one server to manage, using Chef Server and Chef Clients is
clearly overkill. We will use Chef Solo instead. In a newly created directory
on our laptop, we will have the following files (all under version control if
1 2 3 4 5 6
That’s all we need to turn any bare-bones Linux system into a fully equipped
server. Let’s now take a look at the contents of each file. You can copy and
paste freely (everything was written by me, and it’s in the public domain).
Some of it assumes Ubuntu – adjust accordingly.
deploy.sh script is the one you run on your laptop every time you
want to (re-)apply your Chef recipe to your server. It only copies the tree to
the server and runs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
(Remember to change the default host name to match yours.)
install.sh is responsible for bootstrapping the system if necessary
(installing Chef), and then calling the
chef-solo binary. (You don’t
ever need to run it manually. Keep it mode 644 as a precaution against wrecking
your development machine.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
solo.rb only sets two paths for Chef Solo. You should go with this:
1 2 3 4
solo.json holds a pointer to the recipe(s) we want to run (that’s only
one recipe for now). My cookbook is called “op” (for Opinionated
Programmer) – you should name yours after your server or your site.
1 2 3
I like to just have a single “default” recipe that holds all the server
configuration. If it gets out of hand, you can always split it up, but for
small sites, a single recipe file should be easiest to deal with.
A recipe is simply a list of resources. The Resources
page on the Chef wiki is probably the one piece of documentation you will be
consulting a lot.
I will give you a few examples of things you might want to do in your recipe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
Note that all dependencies are implicitly given by the ordering of the
This should be enough examples to get you going. Again, all of these resources
(and many more) are documented on the Resources
- As you write your recipe, re-run
./deploy.shfrequently, like you would recompile a piece of software.
- When you are done, tear down your VM and redeploy on a fresh system, just to make sure everything is working OK. Sometimes subtle dependency/ordering issues creep in that are only revealed by applying the entire recipe on a vanilla system. You don’t want to be left with a non-working recipe when your server goes down and you need to re-deploy afresh.
All code was written by me and is licensed under CC0 (public domain).
Read more at the source