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.
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).