I can do anything. I can’t do everything. –Me
Anything worth doing is worth doing in a way you can check in to git. To recall what I did from the command line, I should turn those actions into a persist-able document. Do I? Not often enough. Often I rely on bash history to remind me of what I did last time. Since the machines I work on are out of a global pool, I have been burned by not recording commands before relinquishing a machine.
For complex series of tasks, it makes sense to execute a bash script to perform those tasks, and I have many of these. Shell scripting excels in doing command line tasks. Where it does not do so well is on tasks that are split over multiple machines. While curl is great for pulling and pushing files to webservers, the majority of my remote work requires ssh and scp to set things up. This is where Ansible comes in: If I can make a playbook that records the commands I use to perform that action, I can repeat it on another machine.
Here is what my workflow looks like as I try to get better at it:
- Fetch machine access data from lab scheduler
- Generate inventory file
- Run Shell Script that specifies usecase specific variables to call…
- an Ansible playbook which does the following
- ssh key management
- pass Usecase specific configuration
- Git clones work repository
- Runs script
- Reports result
So the question often comes up: when should something be done as a bash script, and when should it be done via Ansible? My take is that Ansible is neither the first thing nor the last thing that you hit: it is the shipping company in the middle of the move. Lets work backwards.
So, write your script. Check it in to git. Push it to a remote server. Then use Ansible to provision that script on the next machine.
I find that I often have a 1-to-1 relationship between scripts I want to run and an Ansible module that does the calling of that code. I make these into modules so I can then mix and match them in playbooks later. This can be done via a refactoring, effort, so I often start with them in playbooks, and refactor them when I want to reuse the same logic in another playbook.