The tips mentioned in the article are helpful, but still beyond the initial development of roles, maintaining roles is a pain no one can alleviate. It is the perl of automation. I wish people would stop using it. I've yet to start a job where people haven't regretted going towards ansible.
I dislike yaml, but I like Ansible. I think it hits the sweet spot for small and medium size enterprises, who are looking for a middle point between manually provisioning servers and containerisation.
Neither of those of idempotent.
It seems likely you are coming at this from the perspective of "when I find an ansible playbook on github its hard to follow whats going on".
There is a certain truth to that, but much of its complexity is probably related to said playbook developers trying to abstract away specifics and create a playbook that works on a variety of distributions / configuration options.
Ansible can be as simple as a single file that proceeds sequentially like a bash script.
Even with the standard library of predefined task, most devs don't put in the effort to learn them since "ifconfig | grep" and other commands are baked into their muscle memory, they would rather make a quick and dirty bash-step than figure out what is the best practice ansible-equivalent. In the end the result is a sequential shell script written in yaml with no guard rails keeping it idempotent, plus riddled with jinja template-substitutions making it a nightmare to follow.
A truly declarative system would be designed more like makefiles, really enforcing idempotence. With steps in playbooks being executed in sequence it's too easy to fall back to script-thinking and side-effects. Sadly i'm not aware of any.
> Neither of those of idempotent.
There is nothing magical about Ansible that makes it idempotent by default either.
The simple stuff like having specific versions of a package installed that you might be thinking of is just using Python under the hood. If you get into more complicated stuff, especially around custom infrastructure abstractions you use internally, guess what, you will have to write a bunch of Python and effectively call it from Ansible. And you will have to put in extra effort to make sure it's idempotent.
At which point you start thinking...why not just write a Python script instead? At least that gives you all of the flexibility.
No, I've worked with ansible over 3 jobs, for the past 4 years. It hasn't been hard to convince colleagues to move away from Ansible once I show the competition. Sadly the migration process is rarely easy.
Most of the time (i.e. if your Bash script generates a known file), Ansible also gives you idempotency for free, thanks to the ’creates’ parameter.
We have playbooks installing and managing our databases, web servers, VoIP PBX, DNS servers, backend services, and on and on. All completely idempotent and safe to run at any time against any host. No special effort whatsoever was required to make that safe to do.
I suggest looking into the alternative, such as chef, puppet, saltstack etc. They allow for declarative configurations and make it a lot easier to make your configurations idempotent. On top of that, do the infrastructure itself (aws, gcp etc) in terraform (or pulumi if you want it in a programming language). Terraform has its issues, but it is certainly a lot better at managing infrastructure than ansible.
You want to use tools like Puppet and Terraform to define the state of your systems, and Ansible to run operations on those systems, because not everything is stateless; trying to upgrade a database with Puppet or Terraform will be painful, but Ansible won't have trouble.
I do wish it had static typing (Puppet took 4 major releases to finally get it and its type system is its best feature over alternatives) and less YAML, but it is what it is...
I've found Ansible good for quick one-liners across multiple nodes :)
Having used Puppet, Chef, Ansible, custom shell and Python scripts, and Terraform provisioners, I'll say there aren't really any "good" automation tools.
They each have their pros and a long list of cons.
The good thing is that a lot of garbage that I used to do with those tools has been replaced with K8s. Some Terraform and Ansible still survive for self-managed VMs, but that's about it.
Having said that, in an ideal scenario, you use auto scaling combined with cloud init to avoid having to manage live servers. Cattle, not pets. That way you can provision images using chef/puppet, and then have them deploy and be automatically deployed. It gives also gives you the opportunity to create self healing architecture that requires less baby sitting.
K8s certainly forces you to think closer to that architecture and that is good.
Don't look at kubernetes then...
Whoever prefers configuration files over environment variables can get the same effect by adding to their ~/.ansible.cfg:
stdout_callback = yaml
In my case I workaround it by _merging_ all potential config files into one at runtime using `crudini` as demonstrated by rsguhr .
I integrated it to the repo, where I store my code and it just runs all the test cases for my code. It saved me a bunch of hours of investigation in test environments before I even released the code. Highly recommend to try it even for a small project.
Apart of that play with ansible strategies if you have more than one server to apply the role. It really might save you some minutes of a runtime.
No. F that. Back to shell scripts. Git clone and run "./install.sh". Most of the things I do are containerized anyway, and the heavy lifting is done by Dockerfile not Ansible, so the install.sh isn't actually that involved.
Hey Ansible if you're reading this, head over to https://google.com/chrome/. Make your front page look like that with a big obvious download button and no popups.
PS. Just out of curiosity I just tried "ansible install" in google and ddg and the very first link is pointing to an installation guide . The guide gives a very complete installation instructions with multiple options for various systems. You literally can choose whatever fits your environment more.
FWIW: Works just fine here on Debian (using it since Debian 8, now on Debian 11).
Also if I have to use Google to search within your website, you fail at website design, or your in-site search engine is crap.
* Ansible installation guide (https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installation-guide)
* Ansible Getting Started (https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html)
* the extensive Ansible core module docs (https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html)
Oh and on a default Ubuntu install I have nejither pip nor docker.
If I have to do that much, I might as well not use Ansible and just use my existing bash scripts, which take care of installing pip and docker as well as absolutely everything else. All my existing system setups are just
curl https://something/something | bash
As an aside, I feel such crusty syseng vibes right now. These young folk want it all point and click, apt-get, spotify me. Are you seriously a grown ass human person in the same industry as me and expecting a huge single button install of a configuration management framework? Ever consider you'd have to build a custom image (whether EC2 or docker or whatever) to support your specific environment? If you want to learn Ansible, learn it. Don't think you can just apt-get and accept defaults here. Asserting right now this is an instance where trying a little harder is required.
That is literally the problem. The WHOLE POINT of Ansible is to make things easier. With my bash scripts I don't have to read documentation, so Ansible should beat that, by perhaps making it easier to write the scripts, but HELL NO not by making me have to read documentation. At worst it should be smack dab on the front of the website (like Chrome); at best it should be apt-get/yum/brew install <the obvious name of your product>.
Asking me to Google for and dig through docs is a massive product management fail.
> These young folk want it all point and click, apt-get, spotify me.
Yes, I do. It's because young people wanted to fly and not be stuck on horses that we have planes today. It's because young people wanted to get to the moon that we have so much space tech today. This is 2021, and I want level 5 autonomous software. We're trying to build level 5 autonomus cars, which I don't think we'll get to (we'll get to level 4), but I think a computer should be able to solve dependencies, search for include dirs, and figure out how to run an arbitrary piece of software by now. I think level 5 software installation on vanilla installs of the ten most popular OSes is very achievable.
> expecting a huge single button install of a configuration management framework
Yes, or zero-button. This is 2021, not 1980. Hell, when I had my first computer in the mid 1990s I had single button installs other than having to swap floppies, and any MORE buttons than that is a step backward.
> Ever consider you'd have to build a custom image (whether EC2 or docker or whatever) to support your specific environment?
The computer should be able to figure that out by now. I'm serious. This is 2021 and I have 100 teraflops of compute, 32GB of GPU RAM, 64GB of DDR4 RAM, 1.4 Gbps uplink to the wealth of knowledge on the internet, don't tell me this isn't possible for an advanced installation system to figure out how to fetch and run some software and automatically deal with 95% of the errors that come up in the process.
Well. Actually you do need to read the documentation. It might just coincide that you already did it in the past.
Given a fresh system I can get a non-interactive installation started in 40 seconds flat. If Ansible wants to be competent they need to strive to beat that metric.
Again, I would assert that Ansible is not the tool for you. You want a comprehensive, dependency-mapping, auto everything detection, autoremediation tool. That doesn't exist right now, for various reasons. I don't disagree with your general direction in the least bit, in fact I appreciate your enthusiasm. However, expecting a cow when you don't see a salt lick is a tad foolhardy. I'll explain below.
> Yes, or zero-button
As someone who has been doing this shit a long, long time, I have to say when I hear someone complaining about something not being in apt I immediately note that this person has not once even dipped their toe in isolated package dependencies and versioning. Even with "teraflops of compute" at their disposal.
> Hell, when I had my first computer in the mid 1990s I had single button installs other than having to swap floppies
MS Word is not a configuration management framework.
> We're trying to build level 5 autonomus cars, which I don't think we'll get to (we'll get to level 4), but I think a computer should be able to solve dependencies, search for include dirs, and figure out how to run an arbitrary piece of software by now.
Software exists that can do this, and you most certainly could in Ansible with some fancy lookups and dynamic group_vars, but you would not know how accomplish this without reading the manual, nor do I believe that you should be able to. I believe that understanding the systems you are configuring and dictating precisely how they should be configured, in code, and automating the regular application of those configurations is exactly the best of what's available right now. That goes for Terraform + Ansible, Docker, k8s, whatever.
But while we're on the topic of autonomy, I take extreme umbrage with your analogy of cars to you, as a systems operator, wanting to consume Ansible as a configuration manager. Ansible isn't the car and you're not the driver here. Maybe somewhere between operator and driver. But the notion that you should be able to simply install this and expect it to magically detect everything that you want it to do is a gross misunderstanding of what this tool is and what exactly it does.
Again, something you would have understood if you had read just a little.
curl http://somescriptthisdudehasnocontrolof.sh | bash
curl https://github.com/... | bash
Ansible and Puppet claim to be declarative but it's a lie. Configuration management really needs a rethink. I know Nix exists but that has a huge barrier to entry and companies don't want to use something that isn't battle tested. In my view, the ideal config management tool would be fast, testable, and provably idempotent. It would also be as far away as possible from the Python/Ruby swamp that Ansible and Puppet are stuck in.
Ansible is not declarative at all though, and it's not even funny how almost every fan says it is. It's just a sequence of actions.
I don't think Ansible even tries to hide the fact that it's just imperative sequence of actions. I wonder where the people saying opposite are coming from. It's just retarded imperative language.
I can think of another horrifying example. We extract archives on to the machine to a specific target directory, and all files in that directory should have a specific owner and group. So we have a File resource that states the target directory exists which is ordered before the Archive resource. But we need to recursively chown after extraction too because tarballs preserve the original owner and group on extraction. We can't add a File resource with the same path that states the owner and group after extraction because duplicate resources aren't allowed. The only solution in this case is a hacky Exec. And that isn't declarative either because you'd have to check the owner/group of all files recursively to know whether it's in the right state or not. We just have this Exec run if the Archive resource refreshes. What if something else adds a file to this directory with the wrong owner/group? It wouldn't be corrected. Again, not declarative.
And god help you if a machine in the fleet runs out of disk space and resources only partially apply. The state will be completely fucked up and you'll have to manually nuke directories to correct it. Because Puppet only pretends to be declarative.
The documentation sucks though imo, every different guide you find will show a completely different way of doing it
My one tip I'll add is to use the `--diff` argument when running a playbook to print out the specific changes made for each step. For debugging, use `--diff --check` to see all the changes that will be made - useful if it's been a while since you last run your playbook over a host.
How so? Do you mean you had trouble remembering what arguments to pass to the copy module? (I'm not sure what other options there are to be a pain)
Using the "state" parameter for files and directories is also rather odd. You specify "state: absent" to delete, "state: directory" to create a directory. It makes sense considering the declarative nature of Ansible, but it's unfamiliar to those used to writing shell scripts.
Another trick I use routinely is this, to display a given variable across all hosts:
ANSIBLE_STDOUT_CALLBACK=json poetry run ansible all -m debug -a var=vault_ssl_cert | jq ".plays.tasks.hosts"
I still lack something that will tell me where a variable is sourced from.
What is the best way to couple Ansible with some git repository to automatically apply changes while still being able to trace and debug?
It’s a good tool to set up a server from scratch to a desired state, but not to go between two versions of desired state. So a git-based deployment workflow is doomed for failure as soon as you start actually using the history (or removing config).
In that case, say you are using Ansible to set up a daemon A on a server. Now you want to remove the setup for daemon A and move to daemon B. Just changing the configuration is not enough (since nothing stops daemon A and cleans up it’s configuration). And after you’re in the new state (let’s say daemon B was just an experiment), if you decide to revert the commit that added daemon B and push, nothing will stop daemon B.
In the end it's also usually just easier to use Ansible to bake a new VM or container configuration and deploy that instead of mutating an existing one over and over again.
I don’t think reversing what you just did is as trivial as it should be. For a git-based workflow to work well, it should be as simple as reverting a commit.
Setting up a VM from scratch is where Ansible is great. A CI/CD that recreates the VM and applies the config would work really well with automatic git deployment, but that’s generally not how people use it.
Tooling can assist process, provide guard rails and reminders, but it's never going to replace remembering some important things. Having layers of process that mean that a single person forgetting is not going to cause disaster are necessary no matter what. Maybe when general AI exists we won't have to worry about remembering things, but then at best most of us will be out of jobs, at worst we'll be running from kill bots.
Don't get me wrong, there are plenty of design decisions in Ansible that regularly annoy me, but I've never expected it to make me less forgetful or substitute for people cooperating and communicating, and I think expecting any tool to do that is a road to disappointment.
For more than a few servers, other answers are probably better
AKA ansible-pull, which can greatly simplify the auth story since the machine only needs outbound access and auth to the repo (if required): https://docs.ansible.com/ansible/2.10/cli/ansible-pull.html