Molecule aids in the development and testing of Ansible roles
—
The Molecule driver system provides an extensible architecture for provisioning and managing test infrastructure across different platforms and environments. Drivers handle the creation, configuration, and destruction of test instances.
Abstract base class that all drivers must inherit from, defining the interface for infrastructure management.
class Driver:
"""Base class for all drivers."""
@property
def name(self):
"""
Name of the driver.
Returns:
str: Driver name identifier
"""
@property
def login_cmd_template(self):
"""
Login command template.
Returns:
str: Template string for generating login commands
"""
@property
def default_ssh_connection_options(self):
"""
SSH client options.
Returns:
list[str]: Default SSH connection options
"""
@property
def default_safe_files(self):
"""
Generate files to be preserved.
Returns:
list[str]: List of files that should not be deleted
"""
def login_options(self, instance_name):
"""
Options used in login command.
Args:
instance_name (str): Name of the instance
Returns:
dict: Options for login command generation
"""
def ansible_connection_options(self, instance_name):
"""
Ansible connection options.
Args:
instance_name (str): Name of the instance
Returns:
dict: Ansible connection configuration
"""
def sanity_checks(self):
"""
Confirm that driver is usable.
Raises:
MoleculeError: If driver prerequisites are not met
"""Concrete properties and methods available to all drivers for managing instances and configuration.
class Driver:
@property
def testinfra_options(self):
"""
Testinfra specific options.
Returns:
dict: Configuration options for testinfra integration
"""
@property
def options(self):
"""
Driver options.
Returns:
dict: Driver-specific configuration options
"""
@property
def instance_config(self):
"""
Instance config file location.
Returns:
str: Path to instance configuration file
"""
@property
def ssh_connection_options(self):
"""
SSH connection options.
Returns:
list[str]: SSH connection configuration
"""
@property
def safe_files(self):
"""
Safe files list.
Returns:
list[str]: Files that should be preserved during cleanup
"""
@property
def delegated(self):
"""
Is the driver delegated.
Returns:
bool: True if driver delegates instance management
"""
@property
def managed(self):
"""
Is the driver managed.
Returns:
bool: True if driver manages infrastructure lifecycle
"""
def status(self):
"""
Collect instances state.
Returns:
list[Status]: List of instance status information
"""
def get_playbook(self, step):
"""
Return embedded playbook location.
Args:
step (str): Lifecycle step name
Returns:
str: Path to playbook file for the specified step
"""
def modules_dir(self):
"""
Return path to ansible modules included with driver.
Returns:
str: Path to driver-specific Ansible modules
"""
def reset(self):
"""Release all resources owned by molecule."""
@property
def required_collections(self):
"""
Return required collections dict.
Returns:
dict[str, str]: Required Ansible collections and their versions
"""The default delegated driver implementation where developers provide their own create/destroy playbooks.
class Delegated(Driver):
"""
Default driver implementation for delegated infrastructure management.
This driver delegates instance creation and destruction to user-provided
Ansible playbooks, allowing maximum flexibility in infrastructure setup.
"""
@property
def name(self):
"""Returns 'default'."""
@property
def login_cmd_template(self):
"""Template for SSH login commands."""
def sanity_checks(self):
"""Validates that required playbooks exist."""Type definitions for driver configuration and options.
class DriverOptions:
"""Config options for molecule drivers."""
ansible_connection_options: dict[str, str]
login_cmd_template: str
managed: bool
class DriverData:
"""Molecule driver configuration."""
name: str
provider: dict[str, Any]
options: DriverOptions
ssh_connection_options: list[str]
safe_files: list[str]from molecule.driver.base import Driver
from molecule.exceptions import MoleculeError
class CustomDriver(Driver):
def __init__(self, config=None):
super().__init__(config)
self._name = "custom"
@property
def name(self):
return self._name
@property
def login_cmd_template(self):
return "ssh {address}"
@property
def default_ssh_connection_options(self):
return ["-o", "StrictHostKeyChecking=no"]
@property
def default_safe_files(self):
return []
def login_options(self, instance_name):
return {"address": f"user@{instance_name}"}
def ansible_connection_options(self, instance_name):
return {"ansible_host": instance_name}
def sanity_checks(self):
# Check driver prerequisites
passfrom molecule.api import drivers
from molecule.config import Config
# Get available drivers
available_drivers = drivers()
default_driver = available_drivers.get("default")
if default_driver:
print(f"Driver: {default_driver.name}")
print(f"Managed: {default_driver.managed}")
print(f"Required collections: {default_driver.required_collections}")
# Check driver status
instances = default_driver.status()
for instance in instances:
print(f"Instance: {instance.instance_name}")
print(f"Created: {instance.created}")
print(f"Converged: {instance.converged}")# molecule.yml
driver:
name: default
options:
managed: false
login_cmd_template: 'ssh -i {identity_file} {user}@{address}'
ansible_connection_options:
ansible_ssh_user: root
ansible_ssh_private_key_file: ~/.ssh/id_rsa
safe_files:
- .ssh/
- inventory/molecule.driverdelegated) is included with MoleculeDriver base classInstall with Tessl CLI
npx tessl i tessl/pypi-molecule