Not too long ago, it was common for an internet company’s dedicated operations staff to manually provision non-virtualized hosts, by following formalized instructions maintained in runbooks. Things changed at a glacial pace by today’s standards, and developers frequently encountered resistance to deploying anything with new provisioning requirements. These days, startups and other kinds of small companies are flocking to virtualized environments, and Amazon EC2 in particular. All too commonly, non-technical management actually believes (or prefers to pretend) that there is no longer any need for operations effort and budget in these environments.
A dirty little secret is that the majority of these companies are not currently using any provisioning automation and many are not even using any application deployment automation.2 That’s not really surprising given no time or budget for learning projects, classes, paid support, a dedicated “expert” consultant, or hire.
Without automation, hosts are manually maintained. Some manage to adopt a modicum of discipline in maintaining virtual machine images. While images are better than nothing, as an approach this is essentially cut-and-paste reuse, with very similar limitations.3 Ultimately:
Images end up collecting and propagating cruft, abandoned modifications and additions
Hosts are not reproducible, say for staging or testing, at least not without down time for imaging
Hosts can not be reproduced if unexpectedly lost
Fear, loathing, and practical inability to perform general maintenance and updates (i.e. closing security holes, updating to the latest base-OS, experimental disk storage optimization)
Silos of host ownership and access (often driven by the same fears)
Failed and abandoned attempts to document the manual provisioning/deployment process (runbook style); where the document is never quite accurate and up-to-date.
Anyone who has experienced well maintained and fully automated provisioning and deployment knows what its worth in avoiding the above described problems and as a general enabler to rapid system and application improvements.
The provisioning system needs to take us from the current Linux distribution base image to hosts ready for deployment as any of the numerous different roles we need: database servers, web application servers, etc. As provisioning requirements change (i.e new developers need access, ruby needs an upgrade) the provisioning system needs to be able to (1) reliably update existings hosts; and/or (2) enable us to quickly build replacement hosts, test them, rotate them in, and eventually shutdown the old. We need to be able to trust running it repeatable on our most critical production hosts.
The deployment system needs to support continuous release while not adversely impacting current users and stability of the applications. It may need to orchestrate incremental or rolling updates to achieve this.
Its questionable if provisioning vs. deployment is more historic artifact than useful distinction. At the very least, its often quite useful to provision and deploy in a single step within a unified system.
Current commercially-backed provisioning tools Chef and Puppet are too complex and abstract to enable the majority of small projects/companies to even start automating provisioning, and are frequently found cumbersome or inadequate for deployment.
SyncWrap aims to provide a unified provisioning and deployment tool in plain Ruby, with minimal learning curve for Ruby programmers. See Provision Programming for some examples of style. The following conditions might also help to distinguish SyncWrap:
If you already have Chef or Puppet working, and are happy with it for both provisioning and deployment, then kudos for achieving full automation. You have most certainly made a significant investment and will not likely want to abandon those efforts.
If you are an engineer, have Ruby and a little Bash scripting ability, and want to automate quickly, with minimal learning curve.
If you expect the first provisioning task to go nearly as fast as the manual alternative. Otherwise you won’t be able to justify automation with yourself or management.
If you can’t afford to learn and maintain two different tools for each of provisioning and deployment, and can’t accept the lack of speed or fine grain control with the alternatives for deployment.
If for that one hour you had to try and automate provisioning, you bounced off the abstraction envelope of Chef or Puppet.
While I don’t wish to single out Puppet, they did recently provide some material which offers some useful points for comparison:
From Puppet is Executable Documentation (January 7, 2014 Puppet Labs Blog):
Don’t Re-Invent bash in Puppet: If you have a series of exec resources chained together, you’re Doing It Wrong. While you may be used to thinking of things as iterative steps, that’s thinking like a programmer instead of like a documenter.
The author has apparently observed a programmer committing certain crimes of programming with Puppet. Perhaps from the programmer’s perspective, a series of Bash commands was more straightforward than using Puppet’s DSL and declarative features? Later in the same post:
Don’t be afraid to write a little Ruby to create a custom function for that logic. Even if you don’t know Ruby, you’ll find that — 99 percent of the time — googling how to do what you want doesn’t require any previous knowledge of the language. Also, check to make sure the function doesn’t already exist in the stdlib module. There are currently 84 functions available in stdlib alone. For example, the pick function in stdlib allows you take a series of variables and select the first one that has a valid value. The strip function in stdlib will take an array of strings and remove any leading and trailing spaces from each string.
Puppet, or at the very least this post, is not targeting a Ruby
developer who would naturally use Ruby core
blinking or looking for the matching Puppet “stdlib” function. There
is an implicit tension to the idea of programming here.
Ultimately, Puppet’s modules and Chef’s cookbooks designs show their roots in the runbook style. In an environment where there is a whole other team doing the programming, it may have been a practical or tactical necessity to abstract out and declare as much as possible. Both Puppet and Chef seem more geared for a classic system administrator role, than for engineers who prefer to directly program.
Applicability. We’ve always maintained that Capistrano is a terrible tool for system provisioning, and that more often than not servers are better being setup with Chef, Puppet or similar, whilst we still agree with that, the new features in Capistrano really lend themselves to integrating with these kinds of tools.
Despite the author’s position, we’ve seen numerous attempts to use Capistrano for provisioning, many of which have been generally successful at providing some reasonable degree of automation. However, Capistrano also seems to suffer from over-abstraction, framework, and barriers to using basic Ruby language features like classes, methods, inheritance and overrides. V3 attempts to hide all command shell invocation behind another new DSL, embedded in the Rake DSL.
In a blog post from the same month, Using Capistrano v3 With Chef the same author demonstrates using Capistrano to deploy (or is it provision?) Chef Solo (the free version of Chef) which in turn provisions the host, before Capistrano deploys to it.
We’ve been working really hard to push Capistrano v3, after years of languishing behind the cutting edge, and in an environment where Chef and Puppet (which should really restrict themselves to working on infrastructure) encroaching on deploying applications, as well; I’ve been really happy to have had the chance to code a really nice way bridge the gaps, and make Capistrano work better with Chef for deployments where repeatable infrastructure is important, but fast deployments of application code are essential…
SyncWrap takes a different approach and enables clean, direct programming of the low-level details in Bash, which effectively is the Domain Specific Language for low-level remote interaction.
From my own recent experience and an informal survey of colleagues. ↩
This is not to say that there isn’t still an important role and utility for images; more later. ↩
“Most Vagrant baseboxes install Ruby for use by Chef and Puppet, but the latest ones do this into /opt/ruby rather than using the system packages.” Stackoverflow: Installing Ruby 1.9.2 on Ubuntu using Chef and Vagrant ↩
“Changing the system ruby when you depend on Chef is always a bootstrappy web of emotion and anti-gravity, and moving to Ruby 2 was even more scary given how many dependencies are assumed on Chef’s end.” StatusPage.io: Moving to ruby-2.0.0-p0 on Mac+RVM and Ubuntu 12.04 ↩