Over the last few years I have written a number of Ansible roles that I have published on Galaxy. When I wrote them, I followed the Jeff Geerling’s pattern for testing ansible roles with Travis CI so that I could put a badge in Galaxy that they were working. When I was introduced to Molecule earlier this year, I decided to migrate my current roles to use molecule as the testing framework. It has a lot more features available to it, including being able to actually test it before you check it in, not afterwards like with the Travis CI setup.
Initialize the Scenario
Since the role already exists, we need to initialize a scenario with Molecule, rather than a role (which does essentially the same think as
ansible-galaxy init does). So the first step is to check out the role from source control.
git clone firstname.lastname@example.org:austincloudguru/ansible-role-splunk-forwarder.git
Once the code is checked out, you need to change directories into the role and run the
molecule init scenario command to create the molecule scenario.
cd ansible-role-splunk-forwarder molecule init scenario —scenario-name default —role-name ansible-role-splunk-forwarder -d docker
This will create the scaffolding for molecule inside the role using docker as the default driver. There are multiple drivers and you can have multiple scenarios. I have one set of roles that includes docker as the default, but also can be tested in scenarios configured with AWS and GCP (this can be useful since each cloud provider image can have different packages and settings).
For all the roles that I create, I make some changes to the default Molecule files. I add a yamllint.yml file that contains the following to make some changes to the default yamllint settings.
--- extends: default rules: line-length: max: 120 level: warning truthy: disable
I also update the dockerfile.j2 file and add some additional packages (iproute2 systemd unzip) to the apt-get blocks. This allows me to pull down base images directly from providers (ubuntu, centos) instead of building my own base images and then having molecule build on top of them.
#ubuntu RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd unzip && apt-get clean; \
Finally, I update the molecule.yml file to use the yamllint.yml file and configure the docker containers (platforms) that I want to run the molecule tests against.
--- dependency: name: galaxy driver: name: docker lint: name: yamllint options: config-file: molecule/default/yamllint.yml platforms: - name: ubuntu-18.04 image: ubuntu:18.04 privileged: True command: /sbin/init - name: centos-7 image: centos:7 privileged: True command: /sbin/init provisioner: name: ansible lint: name: ansible-lint scenario: name: default verifier: name: testinfra lint: name: flake8
Before you run your first full test of the role, I suggest you run
molecule lint to make sure everything passes. This will allow you to quickly see the issues without having to scroll back up. Once you have validated that the linting is good, you can run `molecule test</code> and see if you have any other errors or issues around idempotence.
You can also add some additional tests in the test_default.py file that you can run after the ansible is complete. The following validates that the user and group is setup and that the service is enabled and running.
import os import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') def test_splunk_group_exists(host): splunk_group = host.group("splunk") assert splunk_group.exists def test_splunk_user_exists(host): splunk_user = host.user("splunk") assert splunk_user.exists def test_splunk_is_running(host): splunk_service = host.service('splunkd') assert splunk_service.is_running assert splunk_service.is_enabled
If you would like to still test the role with TravisCI or be able to post back to Ansible Galaxy that the build is passing, you can run the Molecule tests via TravisCI by replacing your current .travis.yml file with the following.
--- sudo: required language: python cache: pip branches: only: - master services: - docker before_install: - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" - sudo apt-get update - sudo apt-get -y install docker-ce install: - pip install molecule docker script: - molecule test notifications: webhooks: https://galaxy.ansible.com/api/v1/notifications/
That’s all there is to it. Now you can run the
molecule test command locally prior to checking in your code to validate that it works properly as well as have it run in TravisCI so that it can update the status on Ansible Galaxy.