The article does a great job of exampling chef here, but if you want to play around with it, I highly recommend checking out Vagrant too. Vagrant is an absolutely awesome way to play around with configuration management solutions via the provisioners mechanism [1]. You can easily test and learn puppet/chef/ansible/cfengine/docker/salt/etc. I've done a screencast on Vagrant [2], Learning puppet with Vagrant [3], but you could easily apply this to Chef too.
This is a good start but where Chef ends up sucking a bit is when you want to deploy a bunch of different apps in a SOA type of arrangement and don't want to duplicate code. I.e to deploy another ruby app you have to basically copy and paste this cookbook or you can try to switch to the 'application' cookbook which is chock full of magic and wonder and doesn't really look like any other chef code.
Chef really needs some dependency injection type stuff like what juju has going on. So something can provide a 'load balancer' and your app can optionally use a 'load balancer' but your app doesn't need to hardcode that it's using nginx, or ha proxy, or elb, or whatever in it's cookbook.
If you have a very similar apps, write a "library" cookbook that does the work that's common to deploying those apps. Any values that differ across the apps should be set by attributes. Next write "wrapper" cookbooks for each app that set those attributes and include the "library" cookbook.
The configuration management landscape is full of good ideas but there are too many of them and most of them end up being the equivalent of C++ for infrastructure automation. You can do anything and everything in 10 different ways that are all equally complex. Chef for example has 9+ levels of attribute overrides ranging from X different cookbook attributes to Y different role attributes. I ask why are there so many override levels and there is no good answer because I've never needed more than 3 levels of attribute overrides. There's more but the override levels on their own are already enough headache. Then there are the ones that use a custom configuration language. I enjoy writing and using DSLs as much as the next guy but the whole point of DSLs is to keep them away from the Turing completeness threshold. As soon as you cross it there is no point in having one. All of the tools commit this sin except for Chef which just embeds the DSL in Ruby.
There is also the fact that none of these tools actually address cloud provisioning. They all work really well once you have your entire topology mapped out but do nothing to actually help with building that topology. That's why I'm hoping Terra takes over because it addresses this aspect of configuration management and I rather use something from Hashicorp than some other vendor.
What are all the cloud resource types that salt can provision? All I can find are computer instances and volumes, which is not nearly enough to meet my needs. When bring up a new application on AWS, off the top of my head I need to create an autoscaling group, launch config, load balancer, cloudwatch alarms, dns entries, and ec2 instances.
Since we've been seeing a lot of traffic from this article, I'd be happy to also answer questions here that HN folks might have about how Practicing Ruby works!
[1] https://docs.vagrantup.com/v2/provisioning/index.html
[2] https://sysadmincasts.com/episodes/4-vagrant
[3] https://sysadmincasts.com/episodes/8-learning-puppet-with-va...