That's what I don't understand about Ansible. It's basically -- literally, actually -- Puppet reinvented with a new syntax based on YAML.
Puppet works so well, Ansible seems like a typical "not invented here" tragedy that frequently occurs in open source. Rather than coalesce around something that works and has years of experience and knowledge and bug fixing sunk into it, people create something from scratch.
Puppet has very little abstraction. But what you do get, which Ansible has not really understood, I think, is a data model. The above results in the graph getting an object File['/etc/memcached.conf'] which can be referred to. I can do this:
service {
'memcached':
require => File['/etc/memcached.conf'];
}
This in turn creates the graph node Service['memcached']. It takes part in a larger graph that looks like this:
Stage[main]/Node[myserver]/Service['memcached']
In fact, manifests are all compiled into a large graph like this, with interdependencies between the nodes. The logic-based, Prolog-type language in the OP's link is precisely what Puppet builds underneath.
Likewise, the graph model is extensible. I can invent a new object like so:
Here, the define public_key() actually defines a new type of object that can be instantiated in scripts. When one is instantiated, other objects can be depend on it. This allows me to encapsulate stuff in my scripts; rather than having other declarations depend on the internal details of how a public key is stored (ie., in a home directory), they depend on my definition.
Ansible may look simpler on the surface, but I think it's all surface. When you have learned to use Puppet, it becomes simple. Ansible looks to me like the product of a person who looked at Puppet, said something like "ugh Ruby, ew syntax" and made his own thing, without looking deeper. Simialrly, Ansible appeals to people who look at Puppet with the same reaction, again without looking deeper. The irony is that they are buying into something that is arguably poorer.
That said, I would argue that part of the problem is Puppet's documentation, which surely must drive people to "poor man's Puppet" solutions. (The cynic in me wonders if Puppet's poor documentation is a deliberate ploy on part of Puppet Labs to boost their consulting business.)
You do know where the author of Ansible came from right? ;-)
Ansible keeps the task and orchestration layer simple so you stay focused on the problem you're solving vs. focusing some complexity of the tool itself, like a hierarchical data model.
If you need complex logic, use the programming language of your choice and write a module, it's simple and your code can be as complex as you need.
If you need more complex data structures, then simply have Ansible query it from a real database or other datasource, with as complex a data structure as you need.
But at the layer you're expressing what needs to be done, it should be simple and easy to read.
> Puppet works so well, Ansible seems like a typical "not invented here" tragedy that frequently occurs in open source.
That is a bit kind of what I get from Ansible.
Ok at first the best thing it had going for it was 'it works over plain SSH and uses YAML'. Basically for those who did everything via SSH and shell scripting. This was an upgrade.
Now once they get into complicated playbooks and transitive dependencies, 0mq daemons, yes it looks like it is just another Puppet but newer (some kids just like newer things because they want to feel like they are at the cutting edge of technology).
There is also Salt. That had the "look really fast and responsive configuration" because it has the 0mq based distribution mechanism. But then Ansible added that too as a feature. Salt looked at and said "ok fine, we'll add SSH only option too". So now they are both basically solving a similar problem along with the older tools (Puppet, Chef etc)
Haven't used Salt much, as I understand it they do take Puppets model. Even if you want that (and I don't) there are still a lot of ways you could do a better job, so I'm somewhat open to Salt.
However, Ansible is significantly different from Puppet. For starters it is push-based rather than pull-based as a lot of Puppet setups are.
The other important difference is that Ansible has top-to-bottom ordering. That's what first attracted me.
Push based SSH models fail pretty badly when you starting talking hundreds or thousands of servers under management. Those models have existed for a log time in tools like rdist, and sitescope tried to sell 'agentless' monitoring which required SSH in order to monitor servers. I've seen deployments of sitescope like that hit scalability walls at a few hundred servers as the ssh client processes on the sitescope server were chewing all the CPU doing SSH session negotiation. And the point here is that 'agentless' is really a lie. You're not agentless, you're using sshd as your agent. And when you dig into that protocol its expensive and not designed for RPC, its designed for interactive logins, and its chatty and chews up resources. It also isn't terribly reliable. It seems reliable when you're using it on your workstation and logging into a few dozen servers a day. You don't remember that time a few months ago when it had a 'derp' and you had to login again. When you're hitting 30,000 servers multiple times a day, you start to see the unreliability of the underlying protocol.
If Ansible is going to survive you're going to see some kind of 'persistent fireball mode' where you ssh into the box and leave the zeromq daemon running and it starts looking a whole lot more like push.
And really you want nodes registering back to your server. It makes discovery so much easier since you just configure your chef/puppet/cfengine/whatever server in whatever bootstrapping scheme you're using (kickstart, custom amis, whatever) and then whenever a server comes up, it registers and starts working. The push method where you have to edit a file on a server which is used to push code just leads to crufty servers getting untracked. The idea isn't really new, its been around for decades, and its always the first baby steps on the road to doing config management.
What Ansible really got that it sells is 1) It is new. Everyone likes a fresh new thing. 2) It suckers people in who just didn't know or wanted to care about configuration management. Tell them about Puppet and declarative syntax and their eyes start rolling. "But I just have 2 servers... I don't need declarative syntax". And, of course, they are doing configuration management, they just do it by hand, one step at a time, via SSH and shell scripting. Ansible comes in and says "we can make that a little better for you", at least that how I got to know it.
It is funny the Salt vs Ansible interplay. As people complained about each other, they implemented each others' feature in response. Salt got SSH mode and Ansible got fireball mode.
Rackspace recently mentioned having tens of thousands of hosts managed with Ansible actually, and it works fine over SSH. Here's some slides on issues they ran into and resolved: http://prezi.com/tyasc3-vj_id/ansible-turbo/
Though one of the core technology decisions behind Ansible is that you don't need much to get it running. You can scale things up as needed, such as fireball mode. And you can boot strap that process using Ansible. You don't even need DNS.
Hosts can register back with Ansible on start up, this works today with their AWX product and cloud-init's phone home feature. Also your inventory of hosts can simply be queried from sources, such as AWS's inventory list, so in that case you can't have a host that's unaccounted for.
> If Ansible is going to survive you're going to see some kind of 'persistent fireball mode' where you ssh into the box and leave the zeromq daemon running and it starts looking a whole lot more like push.
It has this (the previous incarnation was even called "fireball mode"):
With all due respect to lobster_johnson but I think that you are just in love and blinded by the complexity of Puppet.
I have used Puppet in production in my 2 previous jobs and once I found Ansible that was like why puppet could not be as simple as Ansible. With Ansible, you do not have to draw or understand any freaking graphs of dependency and the only logic is the order of tasks you list them in yaml files and the order of how you include yaml files in runbooks. I think that a first grade student will easily be able to understand the order of how tasks are going to be executed. In comparison to Puppet, in order to achieve the right order of executions you will need to write all these require and what not. At the end of the days, a lot of people are going to be so mad at themselves because puppet fails them in the best possible ways.
Don't dismiss something too quickly as poor man's puppet solution where Ansible users are laughing to the banks because we save tons of times with Ansible and finish our works in PREDICTABLE fashions 100% of the times with little sweat. You can go ahead and spend all your times with your fancy graphs of dependency and write puppet modules that you and only you will understand. We, Ansible users, will not face with such problems because a new or veteran Ansible user will be able to understand the exact same things as how the automation of our tasks will be.
And I do not know if puppet's documentation is the problem or not and I do not think that is the case. There have been plenty books and articles written about puppet and people should be able to read them and become better at that. I personally bought 2 books on Puppet, read ways to many articles written on the web about puppet and at the end of the day it is not only because of the DSL, dependency nightmares, complexity in getting a master/slave environment up but because puppet has tried to make something better but on the other hands make other things way more too complicated than needed.
Poor you my friend for only seeing one tree in a forest. I know that a lot of people are reluctant to change because they have invested heavily in the times, money, efforts in something like puppet and they simply do not want to give puppet up. It all boils down to whether you ask yourself if you could do something better and question the norms. It does not mean that something has been around for many years is the best thing and it does not mean because you use it I have to use it too. We all have choices and we all want better things than that shiny thing on the pedestal.
That implicit vs explicit ordering becomes very important in bigger teams (or even when sharing deployment between multiple teams). Everything is fine when you're writing your bit - it works as you wanted. But then someone else takes over, or bugfixes something - and they can do one of two mistakes: silly one - assume some dependency where there is none and write some more-complicated-than-necessary workaround; or a very critical one - fail to spot a dependency and assume they can reorder some steps, or split them into separate modules.
I've seen this a lot of times when working with chef already. Someone moves a very trivial thing to a different place, or adds/moves a notification - current system works, clean deployment works, ... but current system will fail on the next reboot or package update that cascades in an unpredictable series of events. Unless you explicitly list all existing dependencies, the system is very fragile and sensitive to modifications. I agree that most people deploying a single-server webapp will never run into this, notice the problem, or even care about it. When deploying a multi-host, minimal-downtime infrastructure it becomes a problem though.
I can appreciate the simple chef/ansible way of provisioning things, but starting with some size I think that explicit dependencies are the only way to go. Puppet/salt allow me to do things that are quite hard to do in chef.
So Ansible has the disadvantage of unclear, implicit dependencies.
The undeterministic declarative system (Puppet) has the disadvantage of unclear, missing dependencies.
I would prefer a deterministic system, so that I can validate the output by automated acceptance tests. Preferably, these tests also take into account the various upgrade paths (new->head and head^->head)
> I know that a lot of people are reluctant to change because they have invested heavily in the times, money, efforts in something like puppet and they simply do not want to give puppet up
That's not me. Just recently I switched companies and needed to set up a new devops environment from scratch, and before starting I evaluated Ansible, Chef and Salt to determine whether they were superior to Puppet. I decided they were not.
I am not "in love" with Puppet. People who are in love with technology tend to make decisions for the wrong reasons. I have very little loyalty when it comes to choosing software, and will gladly replace any part of my stack if there is a better solution; but I greatly appreciate maturity and stability. Freshly minted, grandly-hyped technology is by definition immature.
I am truly tired of software being unnecessarily reinvented. The "not invented here" (or perhaps "not invented by me") treadmill where young, inexperienced developers throw away older, mature technology simply because it's not fresh and new is something I try to stay away from. Sometimes (Rails, Node.js, Nginx, Go) it brings something genuinely new to the stable, but generally it doesn't.
Lastly, I don't appreciate your condescending tone. And really, I'm not your friend.
Ansible looks to me like the product of a person who looked
at Puppet, said something like "ugh Ruby, ew syntax" and
made his own thing, without looking deeper.
Before he created Ansible, Michael Dehaan was Puppet's product manager.
Puppet works so well, Ansible seems like a typical "not invented here" tragedy that frequently occurs in open source. Rather than coalesce around something that works and has years of experience and knowledge and bug fixing sunk into it, people create something from scratch.
To be specific, this is Ansible:
The same in Puppet: It's literally the same data expressed here.Puppet has very little abstraction. But what you do get, which Ansible has not really understood, I think, is a data model. The above results in the graph getting an object File['/etc/memcached.conf'] which can be referred to. I can do this:
This in turn creates the graph node Service['memcached']. It takes part in a larger graph that looks like this: In fact, manifests are all compiled into a large graph like this, with interdependencies between the nodes. The logic-based, Prolog-type language in the OP's link is precisely what Puppet builds underneath.Likewise, the graph model is extensible. I can invent a new object like so:
Here, the define public_key() actually defines a new type of object that can be instantiated in scripts. When one is instantiated, other objects can be depend on it. This allows me to encapsulate stuff in my scripts; rather than having other declarations depend on the internal details of how a public key is stored (ie., in a home directory), they depend on my definition.Ansible may look simpler on the surface, but I think it's all surface. When you have learned to use Puppet, it becomes simple. Ansible looks to me like the product of a person who looked at Puppet, said something like "ugh Ruby, ew syntax" and made his own thing, without looking deeper. Simialrly, Ansible appeals to people who look at Puppet with the same reaction, again without looking deeper. The irony is that they are buying into something that is arguably poorer.
That said, I would argue that part of the problem is Puppet's documentation, which surely must drive people to "poor man's Puppet" solutions. (The cynic in me wonders if Puppet's poor documentation is a deliberate ploy on part of Puppet Labs to boost their consulting business.)