7 ms·
Not sure how old this post is, 2014 by the looks of it, but modern declarative automation makes this redundant. Ansible, as an example, would abstract away the
by vr46 6y ago
Not sure how old this post is, 2014 by the looks of it, but modern declarative automation makes this redundant. Ansible, as an example, would abstract away the CLI commands and be very readable in very few lines.
The setup described in this post looks fragile, regardless of whether it's literate. I mean, we used to do these things, but we've moved on.
- hakre 6y agoHow do you document how you call ansible within ansible if I may ask?
- leetrout 6y agoNot op but On my teams in the past a lot of it (not to the level of the article) is captured in shell scripts with the invocations. Inspired by https://github.blog/2015-06-30-scripts-to-rule-them-all/ https://github.blog/2015-06-30-scripts-to-rule-them-all/
- zufallsheld 6y agoWe have a convention that the call should be just "ansible-playbook play.yml" and everything else should live inside ansible. This way there's no need to document how to run the playbook.
- hakre 6y agoWould you say that this can be compared to what leetrout commented with the difference that instead of scripts there is only a single command? Is the playbook always called "play.yml"? And how do you handle multiple repositories (or is there only a sinlge one?)?
- zufallsheld 6y agoYes, it's basically the same what leertout does. And no, it is not always called play.yml but according to its function, e.g. "install_foo.yml". We typically have all our code for one customer in one repository.
- hakre 6y agoYes, that clarifies a lot. And yes, one repository per configuration (per customer code). Is it that you have one inventory per customer configuration? Or how do you manage multiple inventories in this setup?
- zufallsheld 6y ago> Is it that you have one inventory per customer configuration? Or how do you manage multiple inventories in this setup? We have different customers with different servers and applications. Every customer has its own repository with one or more inventories.
- hakre 6y agoThanks for your quick feedback. And how do you share the context / documentation which yaml file is intended to be called by which ansible utility with which utility parameters and switches? I ask b/c this is normally the problem I run into when things grow and I found the suggestion in the OP interesting to this regard as it adds the context while implementing, not documenting afterwards (and such documentation often becomes stale). Also documentation is often declarative (like do this, then that etc.) and it does not show the original thoughts/ideas behind a certain utility invocation. I'd be interested to learn a bit more here, so if you could share a bit of context from your end would be nice.
- zufallsheld 6y ago> And how do you share the context / documentation which yaml file is intended to be called by which ansible utility with which utility parameters and switches? Like I said: Ideally there are no switches and parameters - the playbook should work as-is. If there are switches, we document them in our internal confluence. And yes, our docs get stale, too. That is a problem that we did not fix yet. :) Many playbooks also get executed automatically, so there'S no need to remember parameters for them. You just start the CI-job that then runs the playbook.
- k__ 6y agoAlso, how does one SSH into Lambda or AppSync? Current services don't evwn allow for some of the bad practices of the past.
- vr46 6y agoWell, quite. The process doesn't allow it, either - using Ansible with Packer (e.g.) to build immutable images means that contact between build and compute is very limited. Installing software on a production machine? Get outta here.
- codygman 6y ago> Ansible, as an example, would abstract away the CLI commands and be very readable in very few lines. If it's just a few lines can you give an example?
- vr46 6y agoSure: - name: install the latest version of Apache and MariaDB package: name: - httpd - mariadb-server state: latest
- bovermyer 6y agoAnd the same thing in Chef: package %w(httpd mariadb-server)
- geocar 6y agoThat's an ansible task to do something, but it's not the task solved in the article, or in any of the other linked examples. Things that you haven't done before are harder than things you do all the time, and I would've reckoned trying to do them in ansible is much harder than doing it interactively, but I'd be interested in learning. If I find an article like this[1], how do you translate it into the artefact I would want to keep in source control? In org-babel it's this[2], so what would that look like in ansible? [1]: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-iptables-on-ubuntu-14-04 https://www.digitalocean.com/community/tutorials/how-to-set-... [2]: http://www.howardism.org/Technical/Emacs/linux-iptables.org.txt http://www.howardism.org/Technical/Emacs/linux-iptables.org.... Once you've done it and you've documented it, I can see how you might translate that into ansible (or chef or whatever), but that's a different thing.
- xorcist 6y agoModifying iptables rules is such a common operation that all configuration management languages would support them natively. Using an iptables module for Ansible it is straightforward to write the rules as yaml. The documentation has a clear example. However, having used several of these languages for over a decade and realizing this is a contentious issue within the community, I would actually avoid using these tools for individual rules. What I would do is dump the rules to a file, distribute the file, and let Ansible make sure the file matches what is running (by way of a regular rule load when necessary). The idea here is that I am already familiar with iptables rules and how to write them, and would expect any other ops-ish person to be the same. The source file matches the output, and any historical diffs will be much more straightforward to read, as there are no intermediary source formats that can change. Also, there is one less Ansible dependency involved, and less syntax to learn (given that one can already read iptables rules).
- rgoulter 6y agoI don't think "interspersing commands and their output with prose" is meant to provide a robust solution that should replace "automation tool like Puppet or Chef". This looks to be a step-up from just manually tinkering with commands in some shell to figure out or explore what it is you need to declare.
- mst 6y agoThis is for the experimentation phase before you abstract backwards into configuration for whatever system you're using. Sometimes it's a lot easier to stay closer to the metal for figuring out what you actually need, then break out the declarative automation to make it truly reproducible.
- trabant00 6y agoThat's what ansible PR material would have you believe. In reality only very simple things can be translated into ansible/salt and even then you may hit one of their many bugs. If you try to do complex things even bash would be a better choice (although obviously the best). There's one thing ansible/salt are good at: make it easy for cheap replaceable devops to write tons of repetitive boilerplate yaml. Harder for them to shoot themselves in the foot than with a real programming language. But once you descend into jinja hell that's not very true either. Also: newer isn't always better and all that.
- zufallsheld 6y agoI always read that ansible can only be used for very simple things. However I never read what things are too complicated with ansible. Can you share an example?
- Xophmeister 6y agoAnsible is good at putting configuration files in the right place and setting their appropriate values to what you want — provided it’s relatively simple, otherwise prepare yourself for complex templates — or installing software from a package manager, etc., etc. As soon as you go outside what its modules provide, it gets more difficult. Modules themselves are actually easy to write, provided you maintain Ansible’s (completely reasonable) maxim of idempotency. Sometimes, however, idempotency is hard to enforce. The best example I’ve come across is building software from source. When there’s no package, you have to do this. Some may argue that this is not Ansible’s job, but I don’t see how it’s different from `apt install`, nor where else it would fit into the pipeline. Anyway, the way I solved this for example was by pinning the idempotency on the existence of build artefacts. Those are often software-specific, so it’s quite fiddly/non-general to find the right artefact.
- snuxoll 6y agoYou should be building packages for the software, of course. If it’s some random internal app you’re chucking into a container it’s one thing, but if you’re deploying it across VMs or physical hosts you probably should put the effort into writing a rpmspec or whatever the hell Debian does (this is a large reason why I don’t do Debian-based systems, I have never been able to properly wrap my head around dpkg builds - there’s too much magic in debhelper and not enough documentation).
- ljm 6y agoI think this is really cool and I'm tempted to try it out for my own VPS so I can easily set up a fresh one if I need to. Modern declarative automation is great for a lot of things, especially at work and for CI/CD pipelines, but it's no substitute for learning what you need to do to reproduce the same setup by hand.
- peterwwillis 6y agoSome kinds of declarative automation are just bad. Case in point: configuration management. Ansible was written before we realized immutable infrastructure is the best way to go. Configuration Management tools craft system state dynamically like a drunk sculpting a Roman bust with a Louisville Slugger. You can get them to do what you want, but it takes a lot of work, and even then the outcome is uncertain. CM tools are often complex because a system whose state is constantly shifting requires complexity to handle it. If instead you make immutable artifacts, you don't need complexity. A simple series of straight-forward commands in a single version-controlled file does everything you need. Dockerfiles seem immature at first because of how simple they are, but in practice it's much more reliable than Ansible, not to mention easier to support. Thus, non-declarative automation, when used with immutable infrastructure as code, trumps declarative. Ansible is also only optionally declarative, which people miss just because it has that bastardized form of YAML for a config file. The simplest tasks, roles and playbooks work when executed sequentially, but not necessarily when out of sequential order. When you do make it super-duper-declarative, it can involve tons of confusing logic that makes it nearly impossible to understand, and is much more verbose (and complex) than a simple script. As soon as automation is more work and cost than the alternative, it should be ditched.
- hackerm0nkey 6y agodespite being old, I think the value lies in the "principle", you don't have to generate your code out of your markup but at least if you document your thoughts and reflect upon them and what and why certain decisions were made, etc... That invaluable on it's own IMO