One of the lesser discussed things about Ansible is, strangely enough, how to classify it.
It’s often referred to as a “configuration management” system, but is that an accurate-enough description?
Pure Configuration management systems work by describing a rigid model of remote machines. They are largely derived today from CFEngine 2, started some fifteen years ago. Whether used in a pull or push mode, the managed machine typically checks in with variables about itself (most of us call these “facts”), and the model is computed to decide what the server should look like. This process is a “server side compile”. While automation itself is highly exciting to the end user, there’s nothing particularly exciting about configuration management or this architecture — it’s mostly about pushing files out and making sure services are running. While the compilation architecture is fine for configuration management, it is much less flexible when dealing with multi-tier applications that span boxes, web services, and application tiers — particularly the case of deploying modern distributed applications, causing many people to turn to other application deployment tooling and strapping other automation on top. Where classic configuration management got it right, of course, was in having declarative models of resources, such as instead of saying “/sbin/service foo start”, describing a model saying a service should both be running and should start on boot, and abstracting away the underlying service implementation. Ansible has those, and tons of them — over 170 modules, batteries included, in the core distribution. Modules are like the tools in your toolbox, and Ansible is a 6 foot tall NASCAR-garage-worthy toolbox.
By contrast, Application deployment systems (such as Capistrano or Fabric, which are both very popular among users of classic configuration systems), work by providing a script describing what happens to a set of things, and they execute the script. They walk down the script and run it, performing steps in parallel across remote machines, having various features built in to abstract out contacting the remote systems. The ability to react and hop across system and service boundaries, as well as not just compiling a rigid model of the remote system, allows for more easily pushing applications out that cross boundaries between boxes. Typically these tools, however, lack the kinds of declarative abstractions needed in configuration management systems. However, since Ansible does use declarative resource models, it allows you to do both at the same time very easily. It’s also done using a data-driven automation language, so you don’t have to code your automation rules in code, and risk them acquiring the complexity of a software project. To a developer, Ansible probably feels like an application deployment system written by someone who came from a configuration management background, because you can use all the resources from the config system in automating your applications — whether that’s a git repo, a service, a configuration file, or a load balancer. The problem about scripts isn’t that they do what you say — that’s awesome — the problem is that they are software code, and software code takes added effort to write and maintain, and can grow hard to read over time — and that they don’t leverage a resource model to avoid some fragile aspects. Hence while we execute like an application deployment system, Ansible decided you shouldn’t be writing that automation process in, say, Ruby or Python language — and we wanted to give you all of those reliable declarative models and abstractions from the configuration management world.
Now that we’ve talked about them both, let’s bring them back together. We believe the split between Configuration Management and Application Deployment is kind of arbitrary — in the real world, the end goal is to deploy the business application. So we blur the lines. Increasingly everyone’s starting to think this way. We don’t usually have “Configuration Management” user groups, we have DevOps and Automation user groups. It’s all about rolling out the app, and then making sure it’s happy in production. Ansible is a configuration management and application deployment system, because it takes the best of both worlds and gets rid of the historical legacy aspects in arriving at a hybrid solution.
There’s also the concept of “Orchestration“, which is widely used in the industry to mean too many different things, to the point that I think we need new words for it that are less watered-down — but haven’t quite picked them out yet. This can mean any of the following very different things depending on who you are talking to:
- basic ability to blast out commands to remote systems
- basic ability to blast out resource instructions to a remote system
- ability to trigger some configuration management automation to run
- some basic ordering of what system should configure before some other system
- the ability to build a general purpose workflow system, such as a pipeline of dependent steps in an IT process
Ansible rocks at all of these. More specifically, not only does Ansible do all of the above, but Ansible uniquely makes the last type – general purpose workflow – possible from a text-based automation perspective. This is where you’d typically use a graphical IT program like (for example) Cisco Process Orchestrator – powerful tools but historically a ginormous bear to work with and don’t fit into modern DevOps practices of working out of source control with a text editor quite so easily.
Most people mean orchestration to be a concept of ordering an existing thing, like some glue layer on top. To Ansible, orchestration is the heart of everything — conduct your computer resources and services as you would conduct an orchestra. Play the brass section with interlaced violins, let the strings play a variation by themselves, come back and solo the first clarinet. It feels native to describe such things.
For this reason, Ansible happens to excel at continuous deployment tasks like zero time rolling updates – containing many features baked specifically into the language to make these possible and super easy. We get there by having things like “host loops” as native concepts, but also concepts such as “delegation” (run this over here on behalf of that), rolling updates, , etc, all in there as first class language concepts. The very first use case that started Ansible as a project was thinking about an old employer, and how they had to lock everyone in a conference room for a very human powered rolling update process. Ansible can get that rolling update down to one button click in less than a half page of text.
We also can’t forget about Provisioning — while the phrase is also often used to talk about deploying software applications, more commonly it means the idea of requesting compute and hardware resources that don’t exist, or modifying ones that do. The idea that before you can configure a base system or deploy business applications on top of it, you need to deploy that system. Ansible has tons of modules for cloud provisioning. This is hard in a configuration management architecture as those systems like to describe an infrastructure only after it exists. Whereas Ansible is coming from less rigid ground, this is quite possible. As a result, we have about 40 modules currently for managing all kinds of cloud services, from working with s3 or Elastic Load Balancers on Amazon Web Services to creating isolated networks on Rackspace Cloud. It’s not required that you use Ansible for this, but many people do. A large chunk of our users use Ansible as a way to simplify delivery of services into cloud providers.
How’d we get there, building a hybrid solution that encompasses all of the above? — While being a great configuration management system, Ansible was not originally designed to just solve one use case, nor did it arrive there via an evolutionary process. Ansible was built from the beginning as a hybrid architecture, merging concepts from configuration management, application deployment systems, and workflow-based orchestration systems. It was arrived at from deep experience using those systems — having built more than a few automation systems previously for Red Hat – and then seeing, later, in the field, many IT automation problems that were still not being solved. The hybrid approach Ansible takes means most arbitrary scripts can be expressed in Ansible, where as what you can express in a CMS is limited by the model and 1-system-at-a-time compilation architecture. You can take baby-steps working a rough collection of bash scripts into a very nice model of your system topology. You can’t turn a configuration management system into an orchestration system easily. Yes, you can strap something else on top, but that’s not the same thing. What we did was build the orchestrator, and attach everything else to it — automating arbitrary IT workflow is really a part of Ansible’s soul.
That’s not all of it, of course. We mix in the ability to do all of that without agents on top of that — by leveraging a finely tuned network implementation that uses SSH for secure transport and unique features like accelerated mode, which can establish network transports using SSH for secure key exchange. The agentless approach minimizes resource contention on remote nodes, and the secure push-by-default architecture enables protection of sensitive customer data while maximizing resources available for business workloads (managed nodes get access to only what they are given), which is why Ansible is so popular in the Big Data space. The fact that you no longer have to think about maintaining, securing, and upgrading the management architecture is a strong bonus. We have no interest in inventing or managing a crypto or in-house security layer, so we use the most secure and trusted system out there, one that most people already have in production.
Finally, we stepped back further and decided to make automation less computer-sciencey in terms of the automation language and jargon. We felt many users being plagued by complex concepts that held back practical application. We wanted to build an automation tool for busy people. I’m a developer, but the idea of needing to understand a complex deployment system for doing something that should be easy, we thought, was busted. So the language is more inspired by the workflow orchestrators — provide basic building blocks, and lots of them (now over 170 modules included in core) — then provide higher level, extremely easy ways to glue things together (loops, conditionals, roles, role dependencies) into larger building blocks.
Since everything is still text based, you still have that great auditable history of what’s going on, but when working towards an auditable system, it’s import to have an especially clear language — which is why Ansible uses a 100% pure data format that is optimized for reading in line-by-line diffs. The behavior of your infrastructure rises to the top, and even if you aren’t the person writing the automation, chances are you can read it the first time and tell what it says. While the architectural features of Ansible make it all possible, language is the thing we think about most, because it’s the interface you interact with every single day.
Ansible is a general purpose automation pipeline, built not from a pointy-click world, but from a pure, 100% machine parseable, data-driven perspective where your automation lives in source control. Just as we’re creating a hybrid architecture, we’re also bridging the idea of infrastructure-as-code with the needs of busy IT shops who don’t want to be dealing with any more code. I’ll resist calling it “Hybrid DevOps” lest the tweet sphere not get the joke, but that’s my view about infrastructure automation.
My thought is this — Let’s learn from everything, look at things from the cycle of how people use tools day to day, from a team perspective — and then break down those arbitrary divisions between tools and make things pragmatic. It’s not about whether something is “configuration management” or “application deployment”, it’s about getting applications out the door and, dare I say it … automating all the things.