Consistent Ansible Python API and CLI with container and process isolation runtime capabilities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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
) -> RunnerParameters:
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}")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
) -> RunnerUsage 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}")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 filesEvent 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
)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