For professional reasons, I'm working my way through the O'Reilly book Ansible: Up & Running. The book is pretty good, explaining the basics of Ansible so far as well as running me through a couple of exercises. The book uses Vagrant as its target container, which is fine by me. As is my wont, I made my life harder by changing things up: rather than using Ubuntu as my target OS, I chose to use Alpine, for which the base Vagrant image has no instance of Python. I also chose to automate my generation of Ansible's hosts file.

The only secret to using Alpine over Ubuntu is simple: Alpine doesn't ship with Python, and Ansible requires Python. Ansible has a work-around, though: RAW mode.

#!/usr/bin/env ansible-playbook

- name: Install Python on Alpine
  hosts: servers
  become: True
  gather_facts: False
    - name: update apk
      raw: apk update
    - name: install python
      raw: apk add python

Commands delivered raw will be fed directly to the shell, and so don't require Python. They're treated almost, but not quite, like -m command style commands. The latter still run through Python, which still seems odd to me, but Ansible is an okay tool and I'm not about to try and re-write it to my satisfaction.  become is still necessary, as installation commands still need to be run through sudo, and gather_facts must be False for this pass as fact-gathering is performed with Python.

Automating the translation of Vagrant's auto-generated SSH configuration to something resembling Ansible's host file output was trickier. My first thought was to use Perl, but then I remembered that when it comes to multi-line patterns, Awk is still the master of the game. I use Gawk here, but that shouldn't make a difference.

vagrant ssh-config | \
    gawk 'BEGIN { RS="\n\n"; FS=" " } \
          /Host / { print $2 " ansible_host=" $4 " ansible_port=" $8 }'

Alpine's layout of nginx, which is the server used in the tutorials, is different from that of Ubuntu. I'll leave it up to the reader to figure out those differences. That shouldn't be too hard.