{"id":3555,"library":"molecule","title":"Molecule (Ansible Testing Framework)","description":"Molecule is an Ansible testing framework designed for developing and testing Ansible collections, playbooks, and roles. It provides support for testing with multiple instances, operating systems, distributions, virtualization providers, test frameworks, and testing scenarios. Molecule encourages an approach that results in consistently developed Ansible content that is well-written, easily understood, and maintained. The current version is 26.4.0, and releases generally align with Ansible development, with major versions introducing significant changes.","status":"active","version":"26.4.0","language":"en","source_language":"en","source_url":"https://github.com/ansible/molecule","tags":["Ansible","testing","DevOps","automation","CI/CD","infrastructure-as-code","Python","Docker","Podman"],"install":[{"cmd":"pip install molecule","lang":"bash","label":"Base installation"},{"cmd":"pip install 'molecule[docker]'  # For Docker driver","lang":"bash","label":"With Docker driver (most common)"},{"cmd":"pip install ansible-dev-tools","lang":"bash","label":"Recommended (includes Ansible and other dev tools)"}],"dependencies":[{"reason":"Molecule is an Ansible testing framework and relies on Ansible for provisioning and execution. It supports only the latest two major versions of Ansible (N/N-1).","package":"ansible-core","optional":false},{"reason":"Contains various drivers (e.g., Docker, Podman, Vagrant) for creating test instances.","package":"molecule-plugins","optional":true},{"reason":"Used by the 'lint' stage for checking Ansible-specific best practices and syntax.","package":"ansible-lint","optional":true},{"reason":"Used by the 'lint' stage for checking YAML formatting and syntax.","package":"yamllint","optional":true},{"reason":"A common Python testing framework used for writing verification tests in Molecule scenarios.","package":"testinfra","optional":true}],"imports":[{"note":"Molecule is primarily a CLI tool; direct programmatic API for scenario execution is not the main interaction pattern.","symbol":"molecule CLI (via subprocess)","correct":"import subprocess\nsubprocess.run(['molecule', 'test'])"},{"note":"Alternative CLI invocation that explicitly uses a specific Python interpreter.","symbol":"molecule CLI (as a Python module)","correct":"import subprocess\nsubprocess.run(['python3', '-m', 'molecule', 'test'])"},{"note":"Direct `import molecule` does not expose high-level scenario execution functions for general use. The `AnsibleRunner` is for writing verifier tests (often `verify.yml`'s Python file), not for orchestrating Molecule itself.","wrong":"import molecule","symbol":"testinfra.utils.ansible_runner","correct":"from testinfra.utils.ansible_runner import AnsibleRunner"}],"quickstart":{"code":"import os\nimport subprocess\n\n# Create a dummy Ansible role directory\nrole_name = \"my_test_role\"\nif not os.path.exists(role_name):\n    os.makedirs(os.path.join(role_name, \"tasks\"))\n    with open(os.path.join(role_name, \"tasks\", \"main.yml\"), \"w\") as f:\n        f.write(\"---\\n- name: Example task\\n  ansible.builtin.debug:\\n    msg: 'Hello from Molecule!'\")\n\n# Change into the role directory\nos.chdir(role_name)\n\n# Initialize a Molecule scenario (using the default Docker driver)\n# This will create the molecule/default directory and its files\nprint(\"Initializing Molecule scenario...\")\nsubprocess.run([\"molecule\", \"init\", \"scenario\", \"--driver-name\", \"docker\", \"--scenario-name\", \"default\"], check=True)\n\n# Define a simple verify.yml (optional, but good practice)\nverify_yml_content = '''---\n- name: Verify role execution\n  hosts: all\n  gather_facts: false\n  tasks:\n    - name: Check if message was in logs (example)\n      ansible.builtin.command: cat /var/log/ansible_messages.log # Replace with actual verification\n      changed_when: false\n      failed_when: false\n      register: log_output\n    - name: Assert message content\n      ansible.builtin.assert:\n        that:\n          - \"'Hello from Molecule!' in log_output.stdout\"\n        fail_msg: \"Expected message not found in logs.\"\n'''\nwith open(os.path.join(\"molecule\", \"default\", \"verify.yml\"), \"w\") as f:\n    f.write(verify_yml_content)\n\n# Run the full Molecule test sequence\nprint(\"Running full Molecule test sequence...\")\ntry:\n    subprocess.run([\"molecule\", \"test\"], check=True)\n    print(\"Molecule test completed successfully.\")\nexcept subprocess.CalledProcessError as e:\n    print(f\"Molecule test failed: {e}\")\nfinally:\n    # Clean up (optional, but good for quickstart)\n    print(\"Cleaning up Molecule resources...\")\n    subprocess.run([\"molecule\", \"destroy\"], check=False) # destroy if it failed earlier\n    os.chdir(\"..\")\n    # Optionally remove the role directory: shutil.rmtree(role_name)\n","lang":"python","description":"This quickstart demonstrates the standard command-line workflow for Molecule, creating a minimal Ansible role, initializing a default Molecule scenario with a Docker driver, and running the full test lifecycle. It includes a basic 'verify.yml' example for illustration. The primary interaction with Molecule is via its command-line interface, even when invoked from Python."},"warnings":[{"fix":"Ensure `ansible-core` is installed, and install specific driver plugins (e.g., `pip install 'molecule[docker]'` or `pip install molecule-docker`) if using them. Review release notes for specific driver changes.","message":"Molecule v3.1 decoupled its binary dependency on Ansible itself. Docker and Podman drivers became standalone projects, requiring explicit installation (e.g., `pip install molecule-docker`). Users upgrading from pre-3.1 might encounter errors about missing Ansible or drivers if not explicitly installed.","severity":"breaking","affected_versions":">=3.1.0"},{"fix":"Use `ansible-galaxy role init` first to create the role structure, then navigate into the role and use `molecule init scenario` to add Molecule testing. Adapt `molecule.yml` to the 'delegated' driver paradigm if not using explicit driver plugins. Existing `molecule.yml` files for other drivers may need updates or replacement with corresponding driver plugins.","message":"Molecule v6.0.0 (Ansible Automation Platform preview) refocused the project to primarily use Ansible itself as the provisioner (delegated driver). It removed the `molecule role init` command in favor of `ansible-galaxy role init` followed by `molecule init scenario`. Support for multiple built-in drivers like Docker/Podman was streamlined, with the delegated driver becoming the default and often the only one present in certain distributions.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Ensure Ansible tasks are idempotent. Use Ansible's `changed_when: false` or `check_mode: true` where appropriate, or tag tasks with `molecule-idempotence-notest` to skip them during the idempotence check if they are intentionally not idempotent for testing purposes.","message":"Molecule's idempotence checks (`molecule idempotence` or during `molecule test`) rely on Ansible's standard output. If Ansible reports 'changed' tasks, Molecule will report an idempotence failure. This is often due to the underlying Ansible tasks not being truly idempotent, not a Molecule issue directly.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use a linter (like `yamllint` and `ansible-lint`) regularly as part of your Molecule workflow (`molecule lint`). Configure your editor to use spaces for indentation and highlight YAML syntax issues.","message":"YAML syntax errors (e.g., incorrect indentation, mixing tabs and spaces, missing quotes for special characters) are a frequent cause of Molecule failures, as its configuration and playbooks are YAML-based. These can result in cryptic error messages from Ansible or Molecule's parsers.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always verify that the chosen driver is installed and running correctly. Check the `molecule --debug` output for more verbose information on how Molecule interacts with external commands. Use `molecule create`, `molecule converge`, `molecule verify`, `molecule login` individually for debugging specific stages. Always ensure Ansible and driver dependencies are correctly installed, preferably in a Python virtual environment.","message":"Molecule relies on external tools (e.g., Docker, Podman, Vagrant, Ansible). Issues with these underlying tools (e.g., Docker daemon not running, incorrect Ansible version, missing Python dependencies for drivers) can manifest as Molecule failures, sometimes with vague error messages.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}