diff --git a/content/ansible-example-role.rst b/content/ansible-example-role.rst new file mode 100644 index 0000000000000000000000000000000000000000..859fbc7cf6ea1a461a0c7c320634c77bc15090d0 --- /dev/null +++ b/content/ansible-example-role.rst @@ -0,0 +1,84 @@ +An example Ansible role +####################### + +:date: 2016-05-19 +:summary: An example Ansible role. + +A few weeks ago I started a new job and a lot of time was spent on refactoring +as well as adding to an existing Ansible automation code base. For me this was a +chance to work more with `Molecule <https://molecule.readthedocs.org/>`_ for +testing. Molecule is a infrastructure-as-code testing tool that is +inspired by Test-kitchen and the tests can be written using `Testinfra +<http://testinfra.readthedocs.io/>`_ which in turn is using `pytest +<http://pytest.org/>`_. The reasons for me to choose this combination is that +the tools are written in Python and that they're focused on Ansible. However I +quickly grew tired of copying files from role to role or making the same +changes to files again and again. So in that spirit I created a new Git repo +with an empty Ansible role (no tasks, variables, handlers etc.) but has all of +my changes and tweaks already applied and working tests out of the box. + +Usage +----- + +To work on the role install VirtualBox and Vagrant (I use the versions in +Debian's repos) and from PyPI Ansible, Molecule and Testinfra. Now, fork the +repo. As you can see there are already README and LICENSE files. If you ever +ran :code:`ansible-galaxy init` or :code:`molecule init` you'll notice that +indeed the repo was created with those tools. + +Dependencies +------------ + +There's an example dependency present in :code:`meta/main.yml` but instead of +the declaring the dependencies in :code:`meta/main.yml` and the sources of the +dependencies in :code:`requirements.yml` which leads to repeating yourself, the +example shows how to declare the source of the dependent role directly in +:code:`meta/main.yml` (which I haven't seen mentioned clearly in the Ansible +documentation. For repositories with playbooks I'd still add a +:code:`requirements.yml` file since there's no meta directory. Pulling the +dependencies took some thought and what I came up with is: + +.. code:: shell + + ansible-galaxy install git+file://$(pwd),$(git rev-parse --abbrev-ref HEAD) + +This is a workaround for installing the dependencies as it actually uses +ansible-galaxy to install the git repo of the role and the dependencies as well. + +Testing +------- + +First of all, I configured `pre-commit <http://pre-commit.com/>`_ hooks that +check, among other things, the validity of the YAML files and the does a syntax +check of the Ansible playbook. + +As for Molecule, the configuration of the test environment is mainly under +:code:`molecule.yml`. That is were you'd go to change the Vagrant box to test. +You can add multiple boxes and specify which box to test like so +:code:`molecule test --platform <BOX_NAME>`. + +Also worth mentioning is the Ansible configuration in :code:`ansible.cfg`. +This is some what of a workaround as well because many of the options can be +configured in :code:`molecule.yml` which is used to generate its own +:code:`ansible.cfg`. However since Testinfra runs the tests over Ansible and +Molecule doesn't pass the configuration along to it, the configuration isn't +honored during testing. This caused me some grief as tests were constantly +failing because Ansible would the host SSH key and fail as it was not known. +The way I did is create an :code:`ansible.cfg` at the root of the repo where +Testinfra would look and passed that as the template to Molecule. + +The playbook that is run in at :code:`tests/playbook.yml` and the tests are +under :code:`tests/` as well. There's an simple example test but the Testinfra +documentation quite good. Just remember to that both the filename and function +name should start with :code:`test_` and you won't have tests that aren't found. + +A word on CI +------------ + +Now you have all of the different pieces and workflow to run complete tests on +roles the next obvious step is setting up a CI pipeline. In my tests and as I +know the various CI services (I personally tried Travis-CI and CircleCI) disable +the option to run any hypervisor. For me it's a deal breaker because I depend on +VirtualBox (I need to test on different OSes, not just Linux). If LXC serves +your needs than you should be able to run Vagrant with the LXC provider and +therefore Molecule. For me it's a deal breaker.