A good source of examples are the scenario functional tests.


Molecule can be executed via an Alpine Linux container by leveraging dind (Docker in Docker). Currently, we only build images for the latest version of Ansible and Molecule. In the future we may break this out into Molecule/ Ansible versioned pairs. The images are located on Docker Hub.

To test a role, change directory into the role to test, and execute Molecule as follows.

docker run --rm -it \
    -v '$(pwd)':/tmp/$(basename "${PWD}"):ro \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -w /tmp/$(basename "${PWD}") \
    retr0h/molecule:latest \
    sudo molecule test

Monolith Repo

Molecule is generally used to test roles in isolation. However, it can also test roles from a monolith repo.

$ tree monolith-repo -L 3 --prune
├── library
│   └── foo.py
├── plugins
│   └── filters
│       └── foo.py
└── roles
    ├── bar
    │   └── README.md
    ├── baz
    │   └── README.md
    └── foo
        └── README.md

The role initialized with Molecule (baz in this case) would simply reference the dependant roles via it’s playbook.yml or meta dependencies.

Molecule can test complex scenarios leveraging this technique.

$ cd monolith-repo/roles/baz
$ molecule test

Molecule is simply setting the ANSIBLE_* environment variables. To view the environment variables set during a Molecule operation pass the --debug flag.

$ molecule --debug test

ANSIBLE_CONFIG: /private/tmp/monolith-repo/roles/baz/molecule/default/.molecule/ansible.cfg
ANSIBLE_FILTER_PLUGINS: /Users/jodewey/.pyenv/versions/2.7.13/lib/python2.7/site-packages/molecule/provisioner/ansible/plugins/filters:/private/tmp/monolith-repo/roles/baz/plugins/filters:/private/tmp/monolith-repo/roles/baz/molecule/default/.molecule/plugins/filters
ANSIBLE_LIBRARY: /Users/jodewey/.pyenv/versions/2.7.13/lib/python2.7/site-packages/molecule/provisioner/ansible/plugins/libraries:/private/tmp/monolith-repo/roles/baz/library:/private/tmp/monolith-repo/roles/baz/molecule/default/.molecule/library
ANSIBLE_ROLES_PATH: /private/tmp/monolith-repo/roles:/private/tmp/monolith-repo/roles/baz/molecule/default/.molecule/roles

Molecule can be customized any number of ways. Updating the provisioner’s env section in molecule.yml to suit the needs of the developer and layout of the project.

  name: ansible

Systemd Container

The docker daemon was designed to provide a simple means of starting, stopping and managing containers. It was not originally designed to bring up an entire Linux system or manage services for such things as start-up order, dependency checking, and failed service recovery. [1]

To start a service which requires systemd, configure molecule.yml with a systemd compliant image, capabilities, volumes, and command as follows.

  - name: instance
    image: solita/ubuntu-systemd:latest
    command: /sbin/init
      - SYS_ADMIN
      - /sys/fs/cgroup:/sys/fs/cgroup:ro

The developer can also opt to start the container with extended privileges.


Use caution when using privileged mode. [2] [3]

  - name: instance
    image: solita/ubuntu-systemd:latest
    privileged: True
    command: /sbin/init

Vagrant Proxy Settings

One way of passing in proxy settings to the Vagrant provider is using the vagrant-proxyconf plugin and adding the vagrant-proxyconf configurations to ~/.vagrant.d/Vagrantfile.

To install the plugin run:

$ vagrant plugin install vagrant-proxyconf

On linux add the following Vagrantfile to ~/.vagrant.d/Vagrantfile.

Vagrant.configure("2") do |config|
  if Vagrant.has_plugin?("vagrant-proxyconf")
    config.proxy.http     = ENV['HTTP_PROXY']
    config.proxy.https    = ENV['HTTP_PROXY']
    config.proxy.no_proxy = ENV['NO_PROXY']

Sharing Across Scenarios

Playbooks and tests can be shared across scenarios.

$ tree shared-tests
├── molecule
│   ├── centos
│   │   └── molecule.yml
│   ├── resources
│   │   ├── playbooks
│   │   │   ├── Dockerfile.j2
│   │   │   ├── create.yml
│   │   │   ├── destroy.yml
│   │   │   ├── playbook.yml
│   │   │   └── prepare.yml
│   │   └── tests
│   │       └── test_default.py
│   ├── ubuntu
│   │   └── molecule.yml
│   └── ubuntu-upstart
│       └── molecule.yml

Tests can be shared across scenarios. In this example the tests directory lives in a shared location and molecule.yml is points to the shared tests.

name: testinfra
directory: ../resources/tests/
  name: flake8