Molecule Framework
Overview¶
Solti-Monitoring uses Molecule for automated testing of Ansible roles across multiple platforms and scenarios.
What is Molecule?¶
Molecule is a testing framework for Ansible roles that provides:
- Automated testing: Test roles in isolated environments
- Multiple platforms: Test on different OS distributions
- Scenario-based testing: Different test configurations per scenario
- CI/CD integration: Works with GitHub Actions, GitLab CI, etc.
- Verification tasks: Confirm functionality after deployment
Molecule Structure¶
roles/influxdb/
├── molecule/
│ ├── default/ # Default test scenario
│ │ ├── molecule.yml # Scenario configuration
│ │ ├── converge.yml # Playbook to test
│ │ ├── verify.yml # Verification tasks
│ │ └── prepare.yml # Setup before testing
│ ├── podman/ # Podman-specific scenario
│ └── proxmox/ # Proxmox VM scenario
├── tasks/
├── templates/
└── README.md
Molecule Configuration¶
molecule.yml¶
---
dependency:
name: galaxy
driver:
name: podman # or delegated, docker
platforms:
- name: instance
image: debian:12
pre_build_image: true
systemd: true
provisioner:
name: ansible
inventory:
host_vars:
instance:
secure_logging: false # Show credentials in test logs
verifier:
name: ansible
Key Settings¶
Driver:
- podman - Local container testing (fast)
- delegated - Use external infrastructure (Proxmox, EC2)
- docker - Docker container testing
Platforms: - Define test environments - OS image, networking, volumes - Systemd support for service testing
Provisioner: - Ansible configuration - Inventory variables - Connection settings
Verifier: - How to verify role execution - Usually Ansible tasks in verify.yml
Testing Workflow¶
Full Test Cycle¶
# Complete test: create, converge, verify, destroy
molecule test
# Equivalent to:
molecule create # Create test instance
molecule converge # Run role
molecule verify # Run verification tasks
molecule destroy # Clean up
Development Cycle¶
# Create instance once
molecule create
# Iteratively test changes
molecule converge # Apply role
molecule verify # Check results
# Manual inspection
molecule login # SSH to test instance
# Cleanup when done
molecule destroy
Specific Scenarios¶
# Test specific scenario
molecule test -s podman
molecule test -s proxmox
# List available scenarios
molecule list
Test Scenarios¶
Default Scenario¶
Purpose: Quick local testing using containers
Platform: Podman/Docker containers Speed: Fast (2-3 minutes) Use case: Development, quick validation
# molecule/default/molecule.yml
platforms:
- name: debian12
image: debian:12
systemd: true
- name: rocky9
image: rockylinux:9
systemd: true
Podman Scenario¶
Purpose: Container-based testing with Podman
Platform: Podman containers Speed: Fast Use case: Local development without root
# molecule/podman/molecule.yml
driver:
name: podman
platforms:
- name: instance
image: debian:12
systemd: true
command: /lib/systemd/systemd
pre_build_image: true
Proxmox Scenario¶
Purpose: Full VM testing on Proxmox hypervisor
Platform: Proxmox VMs Speed: Slow (10-15 minutes) Use case: Integration testing, production validation
# molecule/proxmox/molecule.yml
driver:
name: delegated
platforms:
- name: test-vm
groups:
- molecule
provisioner:
inventory:
group_vars:
molecule:
ansible_user: root
ansible_host: 192.168.1.100
GitHub Scenario¶
Purpose: CI testing in GitHub Actions
Platform: Ubuntu containers in GitHub Speed: Medium (5-10 minutes) Use case: Automated testing on PR
# molecule/github/molecule.yml
driver:
name: podman
platforms:
- name: ubuntu24
image: ubuntu:24.04
systemd: true
Writing Tests¶
Converge Playbook¶
# molecule/default/converge.yml
---
- name: Converge
hosts: all
become: true
vars:
# Override defaults for testing
influxdb_org: "test_org"
influxdb_bucket: "test_bucket"
secure_logging: false # Show credentials in logs
tasks:
- name: Include role
include_role:
name: influxdb
Verify Tasks¶
# molecule/default/verify.yml
---
- name: Verify
hosts: all
become: true
gather_facts: false
tasks:
- name: Check InfluxDB service
systemd:
name: influxdb
state: started
check_mode: true
register: service_check
failed_when: service_check.changed
- name: Verify InfluxDB API responds
uri:
url: "http://localhost:8086/health"
status_code: 200
register: health_check
until: health_check.status == 200
retries: 10
delay: 5
- name: Verify InfluxDB bucket exists
command: >
podman exec influxdb
influx bucket list --name test_bucket
register: bucket_check
failed_when: "'test_bucket' not in bucket_check.stdout"
Prepare Tasks¶
# molecule/default/prepare.yml
---
- name: Prepare
hosts: all
become: true
tasks:
- name: Update apt cache
apt:
update_cache: true
when: ansible_os_family == 'Debian'
- name: Install required packages
package:
name:
- curl
- podman
state: present
Platform-Specific Testing¶
Testing Matrix¶
Test each role on multiple platforms:
| Platform | Debian 12 | Rocky 9 | Ubuntu 24 |
|---|---|---|---|
| Podman | ✅ | ✅ | ✅ |
| GitHub | ✅ | ✅ | ✅ |
| Proxmox | ✅ | ✅ | ⏭️ |
Platform Variables¶
# molecule/default/molecule.yml
provisioner:
inventory:
host_vars:
debian12:
ansible_python_interpreter: /usr/bin/python3
rocky9:
ansible_python_interpreter: /usr/bin/python3.9
Debugging Tests¶
Verbose Output¶
# Show all Ansible output
molecule test --debug
# Show Ansible task output
molecule converge -- -vvv
Keep Instance Running¶
# Don't destroy on failure
molecule test --destroy=never
# Login to inspect
molecule login
# Cleanup manually
molecule destroy
Check Logs¶
# View molecule logs
cat ~/.cache/molecule/*/*/molecule.log
# View Ansible logs
export ANSIBLE_LOG_PATH=./ansible.log
molecule converge
cat ansible.log
CI/CD Integration¶
GitHub Actions¶
# .github/workflows/test.yml
name: Molecule Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
distro:
- debian:12
- rockylinux:9
- ubuntu:24.04
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install molecule molecule-plugins[podman] ansible-core
- name: Run Molecule
run: molecule test
env:
MOLECULE_DISTRO: ${{ matrix.distro }}
GitLab CI¶
# .gitlab-ci.yml
test:
image: python:3.11
before_script:
- pip install molecule molecule-plugins[docker] ansible-core
script:
- molecule test
only:
- merge_requests
- main
Performance Optimization¶
Parallel Testing¶
Caching¶
# molecule.yml - cache package downloads
provisioner:
env:
ANSIBLE_FORCE_COLOR: "1"
PY_COLORS: "1"
options:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule_facts
Skip Unnecessary Steps¶
# Skip dependency installation if already cached
molecule test --skip-dependency
# Only run converge (no verify)
molecule converge
Best Practices¶
1. Keep Tests Fast¶
- Use containers for quick feedback
- Only use VMs for integration tests
- Cache package downloads
- Parallel testing when possible
2. Test Real Scenarios¶
- Use realistic variable values
- Test both success and failure cases
- Include idempotency tests
- Verify actual functionality, not just service status
3. Maintain Test Code¶
- Keep tests in sync with role changes
- Document test requirements
- Use consistent naming
- Clean up after tests
4. Isolate Tests¶
- Each test should be independent
- Don't depend on previous test state
- Clean up resources in destroy
- Use unique resource names
5. Secure Credentials¶
# Use environment variables for secrets
provisioner:
inventory:
host_vars:
instance:
influxdb_admin_token: "{{ lookup('env', 'INFLUXDB_TOKEN') }}"
secure_logging: "{{ lookup('env', 'MOLECULE_SECURE_LOGGING') | default('true') | bool }}"
Common Issues¶
Issue: Systemd not working in container¶
Solution: Enable systemd in platform config
platforms:
- name: instance
image: debian:12
command: /lib/systemd/systemd
systemd: true
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
Issue: Network connectivity problems¶
Solution: Use host network mode
Issue: Permission denied errors¶
Solution: Run with correct privileges
Molecule Commands Reference¶
# Lifecycle
molecule create # Create test instance
molecule converge # Apply role
molecule verify # Run verification
molecule destroy # Remove instance
molecule test # Full cycle
# Development
molecule login # SSH to instance
molecule list # Show instances
molecule check # Dry run
molecule idempotence # Test idempotency
# Cleanup
molecule cleanup # Remove side effects
molecule reset # Reset scenario state
Next Steps¶
- Test Scenarios: Learn about available test scenarios
- Platform Matrix: Testing across multiple distributions
- CI/CD Integration: Automating tests
- Verification Tasks: Writing effective verification