CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-ansible-runner

Consistent Ansible Python API and CLI with container and process isolation runtime capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

playbook-execution.mddocs/

Playbook Execution

Execute Ansible playbooks with comprehensive configuration options, event handling, and artifact collection. Supports both synchronous and asynchronous execution modes with full callback support for monitoring progress and handling results.

Capabilities

Synchronous Playbook Execution

Execute a playbook and wait for completion. Returns a Runner instance with results, artifacts, and event data.

def run(
    private_data_dir: str = None,
    playbook: str = None,
    inventory: str = None,
    roles_path: str = None,
    verbosity: int = None,
    quiet: bool = False,
    rotate_artifacts: int = 0,
    artifact_dir: str = None,
    project_dir: str = None,
    ident: str = None,
    json_mode: bool = False,
    check: bool = False,
    tags: str = None,
    skip_tags: str = None,
    limit: str = None,
    module_path: str = None,
    forks: int = None,
    vault_ids: list = None,
    vault_password_file: str = None,
    extravars: dict = None,
    suppress_ansible_output: bool = False,
    ssh_key: str = None,
    process_isolation: bool = False,
    process_isolation_executable: str = None,
    process_isolation_path: str = None,
    process_isolation_hide_paths: list = None,
    process_isolation_show_paths: list = None,
    process_isolation_ro_paths: list = None,
    container_image: str = None,
    container_volume_mounts: list = None,
    container_options: list = None,
    directory_isolation_base_path: str = None,
    envvars: dict = None,
    passwords: dict = None,
    timeout: int = None,
    job_timeout: int = None,
    idle_timeout: int = None,
    pexpect_timeout: int = None,
    pexpect_use_poll: bool = True,
    runner_mode: str = 'pexpect',
    host_cwd: str = None,
    fact_cache: str = None,
    fact_cache_type: str = None,
    project: str = None,
    cmdline: str = None,
    start_at_task: str = None,
    step: bool = False,
    cancel_callback: callable = None,
    finished_callback: callable = None,
    status_handler: callable = None,
    event_handler: callable = None,
    artifacts_handler: callable = None,
    ignore_logging: bool = True,
    debug: bool = None,
    logfile: str = None
) -> Runner

Parameters:

  • private_data_dir (str): Directory containing playbook files and artifacts
  • playbook (str): Path to playbook file relative to project_dir
  • inventory (str): Path to inventory file or directory
  • extravars (dict): Extra variables to pass to the playbook
  • verbosity (int): Ansible verbosity level (0-4)
  • timeout (int): Maximum execution time in seconds
  • event_handler (callable): Function to handle playbook events
  • status_handler (callable): Function to handle status changes
  • process_isolation (bool): Enable process isolation using containers

Usage example:

import ansible_runner

# Basic playbook execution
result = ansible_runner.run(
    private_data_dir='/path/to/private_data',
    playbook='site.yml',
    inventory='hosts',
    extravars={'env': 'production'}
)

# With event handling
def handle_event(event):
    if event['event'] == 'playbook_on_task_start':
        print(f"Starting task: {event['event_data']['task']}")
    return True

result = ansible_runner.run(
    private_data_dir='/path/to/private_data',
    playbook='site.yml',
    inventory='hosts',
    event_handler=handle_event,
    verbosity=2
)

print(f"Playbook finished with status: {result.status}")
print(f"Return code: {result.rc}")

Asynchronous Playbook Execution

Execute a playbook asynchronously, allowing for non-blocking execution with callback-based progress monitoring.

def run_async(
    private_data_dir: str = None,
    playbook: str = None,
    inventory: str = None,
    roles_path: str = None,
    verbosity: int = None,
    quiet: bool = False,
    rotate_artifacts: int = 0,
    artifact_dir: str = None,
    project_dir: str = None,
    ident: str = None,
    json_mode: bool = False,
    check: bool = False,
    tags: str = None,
    skip_tags: str = None,
    limit: str = None,
    module_path: str = None,
    forks: int = None,
    vault_ids: list = None,
    vault_password_file: str = None,
    extravars: dict = None,
    suppress_ansible_output: bool = False,
    ssh_key: str = None,
    process_isolation: bool = False,
    process_isolation_executable: str = None,
    process_isolation_path: str = None,
    process_isolation_hide_paths: list = None,
    process_isolation_show_paths: list = None,
    process_isolation_ro_paths: list = None,
    container_image: str = None,
    container_volume_mounts: list = None,
    container_options: list = None,
    directory_isolation_base_path: str = None,
    envvars: dict = None,
    passwords: dict = None,
    timeout: int = None,
    job_timeout: int = None,
    idle_timeout: int = None,
    pexpect_timeout: int = None,
    pexpect_use_poll: bool = True,
    runner_mode: str = 'pexpect',
    host_cwd: str = None,
    fact_cache: str = None,
    fact_cache_type: str = None,
    project: str = None,
    cmdline: str = None,
    start_at_task: str = None,
    step: bool = False,
    cancel_callback: callable = None,
    finished_callback: callable = None,
    status_handler: callable = None,
    event_handler: callable = None,
    artifacts_handler: callable = None,
    ignore_logging: bool = True,
    debug: bool = None,
    logfile: str = None
) -> Runner

Usage example:

import ansible_runner
import time

def status_callback(data, runner_config):
    print(f"Status changed to: {data['status']}")

def finished_callback(runner):
    print(f"Playbook completed with status: {runner.status}")

# Start async execution
runner = ansible_runner.run_async(
    private_data_dir='/path/to/private_data',
    playbook='site.yml',
    inventory='hosts',
    status_handler=status_callback,
    finished_callback=finished_callback
)

# Do other work while playbook runs
while runner.status not in ['successful', 'failed', 'error', 'canceled']:
    print("Playbook still running...")
    time.sleep(1)

print(f"Final status: {runner.status}")

Common Patterns

Directory Structure

Ansible Runner expects a specific directory structure for private_data_dir:

private_data_dir/
├── project/          # Playbooks and related files
│   ├── site.yml
│   └── roles/
├── inventory/        # Inventory files
│   └── hosts
├── artifacts/        # Output artifacts (created automatically)
├── env/             # Environment files
│   ├── extravars    # Extra variables (YAML)
│   ├── passwords    # Vault and connection passwords
│   └── ssh_key      # SSH private key
└── tmp/             # Temporary files

Event Handling

Event handlers receive detailed information about playbook execution:

def comprehensive_event_handler(event):
    event_type = event.get('event')
    
    if event_type == 'playbook_on_start':
        print("Playbook started")
    elif event_type == 'playbook_on_play_start':
        play_name = event['event_data']['play']
        print(f"Starting play: {play_name}")
    elif event_type == 'playbook_on_task_start':
        task_name = event['event_data']['task']
        print(f"Starting task: {task_name}")
    elif event_type == 'runner_on_ok':
        host = event['event_data']['host']
        task_name = event['event_data']['task']
        print(f"Task '{task_name}' succeeded on {host}")
    elif event_type == 'runner_on_failed':
        host = event['event_data']['host']
        print(f"Task failed on {host}")
        
    return True  # Continue processing events

result = ansible_runner.run(
    private_data_dir='/path/to/private_data',
    playbook='site.yml',
    event_handler=comprehensive_event_handler
)

Process Isolation

Enable container-based execution for security and reproducibility:

result = ansible_runner.run(
    private_data_dir='/path/to/private_data',
    playbook='site.yml',
    process_isolation=True,
    process_isolation_executable='podman',
    container_image='quay.io/ansible/ansible-runner:latest',
    container_volume_mounts=['/host/path:/container/path:Z'],
    container_options=['--network=host']
)

Install with Tessl CLI

npx tessl i tessl/pypi-ansible-runner

docs

command-execution.md

configuration-runner.md

index.md

playbook-execution.md

plugin-role-management.md

streaming-distributed.md

utilities-cleanup.md

tile.json