Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Stupid question, but why are Ansible playbooks supposed to be "more idempotent" than plain shell scripts?

Due to taking over a project I had to deep dive into it pretty quickly and to me it feels like shell in yaml syntax.



You might be on the same idempotency level with very disciplined shell scripts, but you won't have reporting out of the box. If I deploy something with ansible, I can see which changes were applied. This way, I can see whether I just changed something I didn't want to change. Other than that, yes, much discipline makes the difference. I know exactly what a core module does, but I have to read the entire shell script of "that colleague" to understand what it really does.


> This way, I can see whether I just changed something I didn't want to change.

Or with --check, before you make the change :)


As you get into more complicated setups, it certainly requires discipline, eg:

https://ryaneschinger.com/blog/ensuring-command-module-task-...

But as long as you're careful about coupling operations like lineinfile with checks for the line already being there and so on, you can achieve it (and Ansible certainly makes this much easier than shells scripts do).


Sometimes the way you achieve idempotency feels like hacks, like when you have to ignore errors, always consider a task unchanged, stat files then test if the stat found anything, etc. But in the end I look at what I've accomplished, and if I'd done it in shell scripts most of the code would be boilerplate and it would be unmaintainable. Which makes the times when it's less than good totally worth it.


The answer is, they're simply not. Ansible is just as easy if not moreso to shoot yourself in the foot, only there's some smoke and mirrors (like their 'lineinfile' module) that make you think you're idempotent but actually just create race-conditions and reduce version control.

There are a few tricks that Ansible uses that are non-obvious uses of shell - For example, files should be replaced by copying the new version to the target directory, then unlinking the original file and linking in the new version in it's place, finally unlinking the temporary file. This functionality has been implemented in the 'install' utility in gnu and bsd coreutils since the 80s (though it's not in POSIX, so it's not exactly guaranteed; You'd be hard-pressed to find a machine outside of busybox docker images that does not support it)


Race-conditions? As in, if you're running the same Ansible script concurrently on the same machine? Yeah, definitively don't do that. But why would you?

I agree that modules like lineinfile are tricky and should be avoided (better to copy a full file), but it's hardly just as easy to shoot yourself than the equivalent sed command, in my opinion, if nothing else because they're more restricted.


Thanks for your answer! Actually a colleague of mine that got even more quickly frustrated with Ansible, claimed that Ansible is like Shell, but the latter but be more simple with less abstraction layers. I'll try the shell stuff at home. (In fact I'm also looking forward to check out Terraform, but it seems still a bit beta...)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: