Problem scenario
You want to use Molecule to test Ansible roles. How do you install Molecule on Ubuntu 18.x with Python 3?
Solution
Prerequisites
i. You must have Docker installed. If you need assistance see this posting.
ii. You must have pip3 installed on the Docker host. sudo apt-get install -y python3-pip
Procedures
1. Run these commands:
python3 -m pip install virtualenv
python3 -m virtualenv my_env
source my_env/bin/activate
python3 -m pip install molecule docker
molecule init role -r ansible-apache -d docker
cd ansible-apache
molecule test
2.a. Run this command: vi tasks/main.yml
2.b. Delete what is there. Put this there instead:
---
- name: "Ensure required packages are present"
yum:
name: "{{ pkg_list }}"
state: present
- name: "Ensure latest index.html is present"
template:
src: index.html.j2
dest: /var/www/html/index.html
- name: "Ensure httpd service is started and enabled"
service:
name: "{{ item }}"
state: started
enabled: true
with_items: "{{ svc_list }}"
- name: "Whitelist http in firewalld"
firewalld:
service: http
state: enabled
permanent: true
immediate: true
3. Run this command: mkdir templates
4.a. Run this command: vi templates/index.html.j2
4.b. Put these three lines in it and save it:
<div style="text-align: center">
<h2>Managed by Ansible</h2>
</div>
5.a. Run this command: vi vars/main.yml
5.b. Delete what is there. Place this code starting at the first non-blank line:
---
pkg_list:
- httpd
- firewalld
svc_list:
- httpd
- firewalld
6.a. Run this command: vi molecule/default/tests/test_default.py
6.b. Eliminate the content. Place these lines in the place of the old content:
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
@pytest.mark.parametrize('pkg', [
'httpd',
'firewalld'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
@pytest.mark.parametrize('svc', [
'httpd',
'firewalld'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
@pytest.mark.parametrize('file, content', [
("/etc/firewalld/zones/public.xml", "<service name=\"http\"/>"),
("/var/www/html/index.html", "Managed by Ansible")
])
def test_files(host, file, content):
file = host.file(file)
assert file.exists
assert file.contains(content)
7. Run this: molecule test
8. You are done. The above directions were adapted from a DigitalOcean tutorial here.