alwaysInBeta Stable software is for the weak

ansible-playbook shebang

2019-09-14

So this is probably a bad idea, but it’s pretty fun, so figured I’d share…

A shebang (#!) tells the system that a file should be executed by a provided interpreter. It’s most commonly used by shell scripts (#!/bin/sh), but it can let you feed any file to an “interpreter”. (The interpreter does have to support being invoked as interpreter $FILE, and needs to allow lines starting with #, of course.)

Ansible playbooks are run something like this: ansible-playbook local-workstation-user.yml --diff.

See where this is going?

$ cat local-workstation-user.yml
#!/usr/bin/env -S ansible-playbook --diff
---

- name: apply user-level configuration to localhost on a workstation
  hosts: local
  become: no
  gather_facts: no
  roles:
    - workstation-user

$ ./local-workstation-user.yml
 [WARNING]: A duplicate localhost-like entry was found (127.0.0.1). First found localhost was localhost


PLAY [apply user-level configuration to localhost on a workstation] **************************************************

TASK [workstation-user : create various directories] *****************************************************************
--- snip ---

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=14   changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

It even takes arguments correctly; ex. ./local-workstation-user.yml --check will run without actually applying changes. All you need is the magical line, #!/usr/bin/env -S ansible-playbook --diff (where --diff is just an option that I always want applied), do a quick chmod +x playbook.yml, and you’re set.

I can’t actually think of any concrete reason that this is a bad idea; I think it mostly makes me nervous because it significantly lowers the barrier to accidentally running a playbook with the wrong options (say, if you make heavy use of --extra-vars or --skip-tags) or at all (although if you have, I dunno, a “destroy-prod.yml” playbook laying around, then you have bigger problems). But it’s not like ansible-playbook requires any sort of confirmation before running in the normal case (although you could hack it in with prompts), so this might not be anything but a perfectly reasonable convenience.