For example:
Package 'libapache2-mod-php' should be installed. File '/etc/apache2/sites-available/customersite' should be the contents of this file we have on the master server. File '/etc/apache2/sites-enabled/customersite' should be a symlink to above. Directory '/var/www/customersite' should be the contents of this git repository. Command 'apache2ctl graceful' should be run if any of the above change.
With these five rules, you can turn a default install of Ubuntu into a webserver providing client files in a matter of seconds.
Once you have those rules written, you then apply them. You can wildcard, so that hosts matching 'www*.yourhostingco.com' get these rules.
Now, when you want to add a new webserver to your cluster, you install a new Ubuntu instance, you register it with the Salt master server, and then trigger a state update, and you're done. No SCP'ing files, no manual git checkouts, no copy-paste-edit configuration management.
Then, once you've got all that, you can get into templating. You can do templating both on the contents of files (e.g. for memcached config, insert the machine's internal IP address instead of having one config per server) as well as the rules themselves to avoid having a ton of boilerplate (for module in 'list','of','python','modules', install the module via pip with these rules).
One of my favourite benefits of something like Salt is that if you use Salt to do all of your configuration, then just back up your salt config to github or wherever, then you always have a record of how you did things. You don't get the incomplete documentation or missing steps that happen with most approaches.
As a sysadmin managing a cluster of systems, it can be life-changing.
In combination with service.running you can require that, for example, package x is installed, and its service is running, before service y is started.
Meanwhile, a disciplined system of designing and documenting tests and rollback procedures before committing changes will accomplish this without the need for additional software.
My guess is that if you are not disciplined enough to design tests and rollback procedures on your own, then you are probably going to just switch off or work around those features if they are built into the software.
Vagrant actually works with Chef, Puppet, CFEngine, Ansible, Salt, and more.
From http://www.vagrantup.com: "Create a single file for your project to describe the type of machine you want, the software that needs to be installed, and the way you want to access the machine. Store this file with your project code"
That, and http://docs.vagrantup.com/v2/why-vagrant/, sounds quite similar to a configuration management tool to me (I believe you that it's not, I'm just saying I wouldn't have understood that). Seems geared to launching instances/VMs too perhaps. Maybe it's my lack of domain knowledge and maybe I have unfair expectations but I think that the sales pitch should be accessible to a developer who's not solely in the "DevOps space".
Accessibility is good because I'm sure it is incredibly awesome and may well be useful to a broader set of people who aren't yet in the loop.
I can then use "vagrant up". This creates a new VM using Virtualbox, VMware, or whatever I have installed (I think there's even EC2 providers now!). It configures that VMs hardware as above.
Then, vagrant can use one of many tools in the configuration space -- Chef, Puppet, Salt -- to configure the software in the VM.
I guess the distinction lies there: vagrant configures hardware. Salt et all configure the software.
I agree that we should be evangelizing DevOps and bringing more people into the loop. I was simply saying that Vagrant itself doesn't really need any marketing. It's hard to read much of anything about the field without seeing it mentioned.
Vagrant doesn't need more marketing, but it -- and the other tools -- do need to explain clearly what it does (and does not) do in a way that non-DevOps folks can understand. Perhaps the easiest way to do that is with a simple use case.
The most important thing about it is that you describe the state of the server. And puppet applies it for you. It's idempotent (you might know this term from REST). You can run puppet multiple times and the end result would be the same.
Normally (without config management) you would write scripts that do the configuration. If you ran them twice, things could go wrong, or they would overwrite the stuff from last time. Scripts are descriptions of what steps to take. Puppet manifests are descriptions of what state you want the server to be in.
1: Stop Service
2: Upgrade
3: Start Service
Right now I have just made three non-declarative statements about my tomcat server. I am describing a process that runs through a series of steps to reach a new conclusion.So puppet has these beautiful (sounding) properties. But declaratively describing the state of my servers isn't a real problem I have.
I need to deal with the way that my servers change. I need to upgrade services, including starting and stopping. Puppet absolutely fails at this. Any attempt to describe a process is antagonistic to puppet at a fundamental level.
Whenever people seek a solution to these problems they always get fed that line. That puppet is declarative and idempotent, which is fine. But we should be _very_ clear that puppet does a spectacularly bad job of solving a very ordinary problem that I have, and which I would expect almost everyone else working with large numbers of servers to have too.
If you're interested in trying out Chef - which seems like a good fit from your comment - read on.
For tomcat you could take a look at this community-provided cookbook, which contains resources that make it simple:
https://github.com/opscode-cookbooks/application_java
If you explicitly need to stop/start tomcat beforehand (I believe this resource does a restart after deploying your app) you can do that with the "service" resource built into Chef - though doing so may mean that you're restarting every time you converge the node, which is probably not what you're looking for.
You WANT to stop the service? Really? Stopping the service is an actual headline-level goal, and not a behind-the-scenes detail?
Personally I tell puppet "make sure that the latest version of X is running", because that's what I actually want, and I don't care how it does it...
Maybe puppet has hooks to integrate with the rest of your setup, I don't know - either way, caring about how things are restarted isn't that crazy imo.
There are numerous dependencies to that task - one of which may be stopping the service before upgrading. There are dependencies to stopping the service - maybe telling the load-balancers or your monitoring system. When the service has been upgraded, you can trigger notifications that other items within your config can depend upon (for example, when an upgrade is complete, restart the service, when the service restarts, add it back to the monitoring system etc).
All of these can be modelled in these config-management tools, as explicit dependencies within your manifest file - as opposed to implicit and ad-hoc dependencies within your script.
Specify the service declaratively, and subscribe it to the package that provides the payload.
service { 'myservice':
ensure => running,
enable => true,
subscribe => Package['myservice'],
}
Then when you upgrade the package on that node, either by using ensure => latest, or by manually specifying the new version, Puppet will automatically restart the service.Perhaps I'm missing some obvious detail but I would think you would just update your repository with the new version of your application and/or Tomcat package and that would cause the service to restart on the next Puppet run, after the new version has been installed.
The app was already documented, source-controlled, version-controlled, and tested by developers and QA. There wasn't much benefit to adding anything to the configuration management repository unless there were platform/infrastructure changes.
At this point, the only thing that could save ordinary users from the melee of competing Open Source configuration management frameworks is an illustration by Randall Munroe.
(My hacker senses are tingling. If you listen very carefully, you can just barely hear a new eponymous law being born.)
When you want to change the state, you edit the file - say, to add a package.
At any point you can set up an entirely new server from scratch using that same code.
You can't do that easily with bash scripts.
(you could if they worked like virtualenv requirements files but that only works for python's virtualenv...)
The benefit of Salt, which it has over Ansible, is that it doesn't have to use SSH (which, as mentioned in the article, doesn't scale well to large deploys), and it can do a great deal more things than just 'run shell scripts from a file'.
If someone were to read only your comment they wouldn't see the benefit of these systems at all, which is unfortunate.
Jesus, and I thought the CDCs "big vault full of things that will kill you" was a terrible idea...
After having used it for a while, I adore it. One minute and one command to go from a new project to a full deployment, what more can you ask.
Checkout fabric.py and cuisine.py, both are small, simple, elegant approaches.
Combined with a native package manager (like apt), fabric+cuisine is nearly as powerful as puppet or chef.
The actual configuration of your system will drift further and further away from that templated AMI, leaving you to constantly have to build a new template every time you deploy a new machine, or manually make all of those differential changes to your new system.
Config management can be tailored to rapidly update the configurations of certain classes of systems at a greater interval than the constant cycle of blowing away machines, updating templates, redeploying, etc , etc.
If AMIs are your deployment method of choice, you still need to build a repeatable process for applying updates and changes to your previous base AMI, testing that it still works under all your realistic configurations, and then gracefully deploying it to your production infrastructure.
Which is all doable, but not trivial. And the processes you build will be very Amazon-centric.
Provisioning tools let you create it, and incrementally update your image in a way that lets you redo it from scratch at any time.
That alone is the reason why I like the idea, not necessarily the resulting applications that have been created so far for the task.
Shell scripts could do the same and have for years if your only interested in from scratch setups.
1. Write a script to configure an instance and run it when the instance starts.
2. Clone the instance to an image
3. Run instances based on the image.
It's quite straightforward to do. See http://github.com/gyepisam/fcc-textify for more details.
SuSE Studio lets you do exactly that. (Though exporting to AMIs is just a feature, not the main objective.)
However, there are some common sense tiers:
3rd party dependencies that changes infrequently = put in ami Common ops daemons and boot scripts = put in ami your application code and your configs = deploy via python/ssh client side
Also, one simply has to use ec2 instance tags to name things.
Result, you can have bit-for-bit identical instances fired up in no time with high confidence without need for a full OS package mirror. Without, of course, a ridiculously over-engineered configuration server framework, DSL, SPOF, security holes...
I asked myself this same question several years ago. The basic advantages chef and puppet (and salt, etc.) offer over client-side python alone are:
A thin abstraction layer for basic system/platform information (facter/ohai). System information that you'd obtain using various tools like dmidecode, uname, df, /proc, ip, are all gathered and made available in a single data structure. Overkill? Maybe, but makes for much cleaner scripts.
A library for performing common tasks: package installation/upgrade, directories, files and templates, services, and shell execution. A full list: http://docs.opscode.com/chef/resources.html#resources.
Finally, a framework for organizing your configuration in a standardized way, with most of it in one place. With chef, for example, the idea is to put all the configuration for a single application in one "cookbook" and then if you have two different servers that both use that application in different ways, you define two different roles that pass different parameters to the basic recipes. Obviously the extent to which this one a benefit depends somewhat on your needs and personal preferences.
But I do agree that both chef and puppet are over-engineered. Puppet's DSL and chef's server are mostly overkill that I don't have much use for. But the DSL can be dealt with and the chef server is optional. There doesn't have to be a single point of failure.
I know that I should be doing this in a more robust way but whenever I try and read up on configuration management tools like Puppet and Chef, they're all described in comparative terms - Puppet does X better than Vagrant which does Y better than Chef, etc. I quickly lose patience and get back to digging myself into a deeper technical hole.
Is there a non-recursive explanation of what these tools are able to do and where someone like me should start?
Edit: Thanks for the helpful responses!