Ansible 2.0 released
ansible.com
ansible.com
I've been using pre-releases of 2.0 for a few months now, mainly for its improved support for AWS services like dynamodb and IAM policies. I've had nothing but good experience with the new version, which cleans up the code and brings more consistency. Working with AWS, ansible shows its strengths by exposing to the developer a simplified API which gets you 95% percent of the way -- pretty much what you wish you'd get from Amazon. I feel that ansible does cloud provisioning not just easier but better than most other tools, including Amazon's Cloud Formation.
Ansible's playbooks (recipes for provisioning servers or infrastructure) read like pseudo-code, and although it's sometime not obvious how to write an idempotent playbook for a piece of software, it is always obvious what an ansible YAML file does (despite the obvious shortcomings of YAML for this job). This is important in the devops world: all knowledge about the infrastructure is codified in version-controlled ansible code and doesn't get lost when the job passes to a new hire.
This also means that you can often find a playbook for software you want to deploy already written on github (search with "language:yaml"). Often you won't be able to copy and paste it verbatim, but looking at how someone else has solved a problem (install java, configure apache, etc.), it will be obvious how to replicate it.
Every time I finish a piece ansible code, I smile -- about how many other tools can you say that? Congratulations to the team and all contributors for the new major release (and to the company for its well-deserved recent acquisition)!
There is little effort in getting started, since it runs over ssh without any daemons or agents required on the managed hosts.
For finding playbooks, you can also look at https://galaxy.ansible.com
I don't mind that there's a panoply of bash scripts to configure docker builds. It's simple and it works and nearly every engineer worth anything knows how to read and write them.
A good bash script never goes out of style.
I use a Dockerfile for any long running tasks like installing dependencies so I can take advantage of docker's cache. I then use ansible for fast running configuration like using a template file for filling out user specific configuration.
The biggest disadvantage to this is that you have to add ansible as a dependency in all of your containers, which stinks. I feel like it produces easier-to-read configuration.
Don't get me wrong, bash scripting is a great tool. I just try to avoid it whenever I can because I personally don't like writing bash scripts.
I think in the future there might be a best of both worlds approach if docker adds a caching api to where ansible could interact with it directly. There is also a docker connection plugin added in this release that could add some possibilities.
I find that if I keep things in bash the images become more "dumb" and therefore more portable.
In lieu of a caching API you might find a package cache (apt-cacher-ng, squid, etc) will help speed up installs a lot. I found one image that was pulling down almost 5 GB with every build!
[1] https://github.com/sstephenson/bats [2] https://github.com/koalaman/shellcheck
https://raw.githubusercontent.com/ansible/ansible/stable-2.0...
- Given the dynamic includes, you can use variables in some places you couldn't before , which allows you to pass items in on an include.
- Error handling now uses a try/catch structure with block/rescue/always, which is much clearer than capturing a 'register' variable and handling it later
- It has a new 'free running' mode, where operations can be run on remote hosts as fast as they can be processed, rather than at the speed of the slowest host
- Lots more cloud-oriented modules
I wish there was a clear migration path of exactly what needs to be changed to port things from 1.x -> 2.0, rather than just many cycles of "try it and patch".
[ssh_connection] pipelining = True
Ansible 2 is extremely fast for me.
But, is this a good idea? As the first six comments here are starting that discussion, what are the pros and cons?
The API may be rich but it feels a second class citizen. But DSLs are really hard to get right and often lack ... Everything.
However, sometimes you may want to mix local actions (say, spin up ec2 instances) and remote actions (provision said ec2 instances). In these cases, a simple wrapper bash or python script to combine these has proven helpful.
Ansible 2 changes a lot of that, so a followup for how-to in Ansible 2 is in order eventually.
https://github.com/seantis/suitable
We use Puppet mainly, but depend on Ansible for updates, migrations and other things where we want to control the transition, not just the end state.
The different cascading layers of variables can be hard to reason about, but it does lead to a good amount of DRY.
Almost all the frustrations I have had with ansible haven't been from individual modules, but from the mini-language in playbooks defining what modules gets run when with what input variables. Almost pushed me to do away with playbooks entirely and just call ansible modules from a python script directly.
To me, it still seems like a win compared to over-engineered solutions like chef.
Do you know that some people use jinja2 templates to generate their YAML playbooks? Do you know what could have helped them? A real programming language.
https://news.ycombinator.com/item?id=10567408 -> http://lukeplant.me.uk/blog/posts/less-powerful-languages/
I think it is relevant to this discussion. Having used Puppet before ansible, I tend to agree with it.
Turing complete code turns into an unreadable mess far more easily.
It has variables, control structures, loops and exceptions.
"You need some form of dynamic allocation construct (malloc ornew or cons will do) and either recursive functions or some other way of writing an infinite loop. If you have those and can do anything at all interesting, you're almost certainly Turing-complete." -- http://stackoverflow.com/a/449170
Which satisfies the infinite loop issue.
Have not looked carefully at the dynamic allocation, but I am guessing (hand waving here....) that it could be accomplished.
Besides, it's really easy to write your own Ansible module (in Python), which seems to solve the issue for any use case I can think of?
my_list | unique
I think this is what you're looking for. Any transformation of data that can't be done with the standard filters can be done with a simple filter plugin written in python.No, I'm talking about any atbitrary list processing operation. Some combination of map, fold, and filter, for example.
So, in order to do that in an Ansible playbook, I need to write a Python function to do it and use it in the YAML file as a filter because the DSL isn't expressive enough to do it on its own. So... why wouldn't I want to just use Python again?
Here we install Jenkins jobs....
- name: create the job config.xml files
sudo: true
template:
src={{ item }}
dest={{ conf_jenkins_home }}/jobs/{{ item | basename | replace(".xml.j2", "") }}/config.xml
owner=jenkins
group=jenkins
mode=0600
with_fileglob:
- ../templates/jobs/*
notify: restart Jenkins
And install SonarQube plugins... - name: install sonar plugins
sudo: true
get_url:
url={{ item.value.url }}
dest=/opt/sonarqube/extensions/plugins
owner={{ ansible_ssh_user }}
group={{ ansible_ssh_user }}
mode=0755
with_dict: "{{ sonarqube_plugins }}"Have to say that things are a lot better than when they weren't consistently using jinja2 to parse the strings.
I think the choice of YAML is because Ansible is supposed to be declarative and a serialization format makes sense there, but some of the "metaprogramming" features they've layered on top like loops can feel a bit strange. Like I said I still like it, but I do feel occasionally that it might be nice to have another frontend that is more like a proper programming language.
There's plenty of this stuff all over.
Every time a new configuration management utility comes out, everyone loves it because of it's simplicity or some arbitrary measure of "lightweight," but once Systems Engineers need to solve real automation problems in the real world, they start adopting features to work around the illusion of being "lightweight."
I like Ansible for automating my home network where I have simple problems and no need for environment separation. For professional work, I stick with Chef or Puppet.
And the server uses its own versioning, because what I really need is something competing with my DVCS
Too many things to count, really
The Chef Server stack is somewhat complicated, though with an omnibus install you will rarely have to interact with it at that level. These days, it scales well up to thousands of client nodes with no meaningful effort.
I'm not sure what you mean by the server using its own versioning. Cookbooks are versioned, as they are deployable artifacts. Environments then define which versions of all the cookbooks exist, so you have an easy promotion strategy. The challenge with Chef Server and DVCS is that you have to centralize the uploading of Chef artifacts (roles, environments, data bags, cookbooks) to Chef Server if you have a team with more than 1 person. That challenge is not unique to Chef, however. Hopefully, a team of Ansible users are not running Ansible playbooks directly from their workstations. If you try to upload a version of a cookbook that is older than the current version, it yells at you, so it makes certain bad behaviors more difficult.
There is plenty I don't like about Chef. And Puppet. And Ansible...I've worked with all of them, but I still haven't seen a valid argument to support the phrase "over-engineered" when used on Chef. Of all the configuration management products out there, Chef is still the most flexible and the most powerful.
Omnibus is the worst thing to happen to packaging. It bundles its own copy of everything.
Is anyone that's not an Opscode employee capable of building Chef Server from source? I tried and failed. Software that can't reasonably be built from source is proprietary in practice. I want to run Chef Server on Debian but I can't because its seemingly impossible to build, so I can only use a platform that Opscode provides a pre-built binary for. It's a terrible situation to be in.
Ideally, the playbook should describe the state you want the system to be in.
This is 'almost' the case for most modules and I think this was a very good design decision.
Having said that, the ghastly YAML format was almost a deal-breaker for me too.
[edit: fix broken english]
This is the real reason.
The playbook is the final state. How it gets there is of no interest to you. All you need to be concerned with is the final result - the state described by the playbook. All the extra complexity is handled by the software.
http://www.gnu.org/software/guix/manual/html_node/System-Con...
I guess I've never really considered playbooks declarative. They are written like and feel like a script I'd write in a language like, I don't know, Python. Now, Salt state files I would consider declarative. They are simply Jinja templated dictionaries (Ansible is YAML that tries to find values templated with Jinja; BIG difference as I've discovered using Ansible for the last 6 months) that actually describe a set of states the host should be in. Ansible's playbooks encode a set of function calls that should be applied in a particular order. Don't get me wrong, playbooks ARE powerful in their ability to describe processes that span multiple hosts and I recognize that, but I'd really like to use a real programming language rather than some half-baked one that is encoded in YAML.
I agree with the GP that I wish the Python API was a bit more robust. Currently we have several tools that generate playbooks on the fly, write them to temporary files and then run them with ansible-playbook to ensure we don't lose some functionality that makes playbooks as powerful as they are. Now, it appears the API has significantly changed in 2.0 and it looks like they expose (read: recommend using) more of it making it easier to script with Ansible.
Dependencies are expressed by the sequence of the code blocks in the playbooks and roles, and I see them as implicit. In contrast, Puppet makes the dependency tree explicit with the "requires" language construct.
The thing is, Ansible works well enough for 85% of the cases, where the additional complexity that Puppet brings is not needed.
Do you have a link that references this?
Or, if you are interested in what we did I could probably put it into a gist
After looking more closely it seems like it's just used to pull data from Vault. I'm currently using Ansible for Docker deployments and have been planning on using it to push data to Vault during deployments so this won't really suffice.
Here, to make up for the above comment:
I've found that Ansible combined with Rundeck makes a powerful automation engine, and can replace more complex systems like Jenkins pretty easily.