Ansible-Plugins for the Simple & Transparent Executor for Ansible-Playbooks
Project description
Ansible Runner minimal
DISCLAIMER: This is an unofficial community project! Do not confuse it with the vanilla Ansible/Ansible-Runner product!
WARNING: This project is still in early development. DO NOT use it in production!
Scope
The scope of this project is it to create a simple and transparent Python3-interface that can be used to execute Ansible-playbooks.
It will focus on using docker or podman to execute ansible in an isolated environment. But local execution will also be available.
The implementation will be opinionated and will have a 'narrow' interface.
Motivation
I was not 100% happy with the official ansible-runner library.
-
ansible-runnerprovides a lot more functionality than we actually need (only executing ansible-playbooks) and thus has a lot more complexity added-on. This makes it also hard to troubleshoot. -
ansible-runnerhas lax input-validation - bad user-input might be silently skipped/ignored and thus lead to unexpected behaviour
As I needed an alternative I wanted to provide it to the community to play with. (:
I will try to create a transparent documentation and a lot of unit- & integration-tests!
All user-inputs are validated for data-type and value.
Feel free to give feedback as GitHub issues or email.
Roadmap
- Ansible Execution
- Config Object & Validation incl. inline-docs
- Engines
- Local Executor
- Container Executor
- Docker
- Podman
- Functionality
- Playbook targeting local machine
- Playbook targeting remote Linux server (SSH-Key, Connect-Pass, Become-Pass, Vault-Pass)
- Pass secrets via one-time-read Pipes/FIFO (in-memory - does not write to disk)
- Stopping job
- Redirect output (stdout/stderr) to log-files
- Playbook Status (per category, per host)
- Track stati at runtime
- Tests
- Unit-Tests for all components (>85% coverage)
- Execution Config-Validation
- Execution
- Before
- Base-Executor
- Local Executor-Engine
- Containerized Executor-Engine
- After
- Execution-Status
- Before
- Integration-Tests for many practical use-cases
- Simple execution targeting localhost
- Passing extra-vars
- Passing env-vars
- Enabling output-colors
- User stopping execution
- Execution reached timeout
- Passing secrets (as value & as file)
- SSH-Key (via ssh-agent)
- Connect-Pass
- Become-Pass
- Ansible-Vault
- SSH
- SSH-Key usage
- Known-Hosts file
- tbc...
- Integration-Tests also for containerized executor
- Unit-Tests for all components (>85% coverage)
Install
pip install oxl-ansible-executor
See: pypi.org/oxl-ansible-executor
Custom Container-Image for execution
Use the default/fallback container image as a template.
Execution Stats
If you want to have access to execution-stats - make sure to install and enable the plugin:
# inside the execution-venv or -container
pip install oxl-ansible-executor-plugins
# enable the plugin by adding its path to the env-variable
ANSIBLE_CALLBACK_PLUGINS="${ANSIBLE_CALLBACK_PLUGINS:+${ANSIBLE_CALLBACK_PLUGINS}:}$(oxl-ansible-executor-plugins-callback)"
Usage
from oxl_ansible_executor import Execution, ExecutionConfig
c = ExecutionConfig(
playbook_dir='/home/demo/ansible/',
playbook_file='test.yml',
inventory_files='inv/env1/hosts.yml',
debug=True, # output infos to stdout (for testing purposes)
)
e = Execution(c)
e.run(blocking=True)
# [INFO] Creating log-files
# [INFO] Using executor: local
# [INFO] Creating secret-pipes
# [INFO] Using log files: /home/demo/.local/share/oxl-ansible-executor/ansible_1775500760_lhWOT_stdout.log & /home/demo/.local/share/oxl-ansible-executor/ansible_1775500760_lhWOT_stderr.log
# [INFO] Executing ansible-playbook
# [INFO] Command: ['ssh-agent', 'sh', '-c', 'ssh-add /tmp/ar_znjp4bih/.fIWqOdKaPzGioFfDljSw && /home/demo/.venv/bin/ansible-playbook -i inv/abc/hosts.yml -C -D -l srv1 --key-file /tmp/ar_znjp4bih/.fIWqOdKaPzGioFfDljSw --become-pass-file /tmp/ar_znjp4bih/.SHVTpOYOH93aaZBTAgVJ --vault-pass-file /tmp/ar_znjp4bih/.GwkiXZ7YrpEvGY8BnyF2 syslog.yml']
print(e.status)
# {
# "finished": true,
# "playbook_finished": true,
# "failed": false,
# "canceled": false,
# "time_start": 1775500758,
# "time_finish": 1775500783,
# "timed_out": false,
# "time_duration_sec": 25,
# "log_stdout_file": "/home/demo/.local/share/oxl-ansible-executor/ansible_1775500760_lhWOT_stdout.log",
# "log_stderr_file": "/home/demo/.local/share/oxl-ansible-executor/ansible_1775500760_lhWOT_stderr.log",
# "ansible_command": [
# "ansible-playbook",
# "-i",
# "inv/abc/hosts.yml",
# "-C",
# "-D",
# "-l",
# "srv1",
# "--key-file",
# "/tmp/ar_znjp4bih/.fIWqOdKaPzGioFfDljSw",
# "--become-pass-file",
# "/tmp/ar_znjp4bih/.SHVTpOYOH93aaZBTAgVJ",
# "--vault-pass-file",
# "/tmp/ar_znjp4bih/.GwkiXZ7YrpEvGY8BnyF2",
# "syslog.yml"
# ],
# "process_command": [
# "ssh-agent",
# "sh",
# "-c",
# "ssh-add /tmp/ar_znjp4bih/.fIWqOdKaPzGioFfDljSw && /home/demo/.venv/bin/ansible-playbook -i inv/abc/hosts.yml -C -D -l srv1 --key-file /tmp/ar_znjp4bih/.fIWqOdKaPzGioFfDljSw --become-pass-file /tmp/ar_znjp4bih/.SHVTpOYOH93aaZBTAgVJ --vault-pass-file /tmp/ar_znjp4bih/.GwkiXZ7YrpEvGY8BnyF2 syslog.yml"
# ],
# "process_rc": 0,
# "process_result": {
# "failed": false,
# "rc": 0,
# "pid": null,
# "stdout": "<OMITTED FOR DEMO>",
# "stderr": "<OMITTED FOR DEMO>",
# "stdout_lines": [
# "PLAY [all] *********************************************************************",
# "",
# "TASK [Install rsyslog & logrotate] *********************************************",
# "ok: [srv1]",
# "",
# "TASK [Add certificates] ********************************************************",
# "ok: [srv1] => (item={'c': '-----BEGIN CERTIFICATE-----\\nMIIDdjCCAv2gAwIBAgIUUkucdMI33le6pBxGgw6WRP2yPlcwCgYIKoZIzj0EAwIw\\ngZExCzAJBgNVBAYTAkFUMQ8wDQYDVQQIDAZTdHlyaWExDTALBgNVBAcMBEdyYXox\\nGDAWBgNVBAoMD09YTCBJVCBTZXJ2aWNlczESMBAGA1UECwwJTG9nc2VydmVyMRUw\\nEwYDVQQDDAxMb2dzZXJ2ZXIgQ0ExHTAbBgkqhkiG9w0BCQEWDmNvbnRhY3RAb3hs\\nLmF0MB4XDTI0MTIyNDEzMjExOFoXDTQ0MTIxOTEzMjExOFowgZExCzAJBgNVBAYT\\nAkFUMQ8wDQYDVQQIDAZTdHlyaWExDTALBgNVBAcMBEdyYXoxGDAWBgNVBAoMD09Y\\nTCBJVCBTZXJ2aWNlczESMBAGA1UECwwJTG9nc2VydmVyMRUwEwYDVQQDDAxMb2dz\\nZXJ2ZXIgQ0ExHTAbBgkqhkiG9w0BCQEWDmNvbnRhY3RAb3hsLmF0MHYwEAYHKoZI\\nzj0CAQYFK4EEACIDYgAEUwaiRMy1OcN0j5odvoTir6LFAqAlUlDp708Y39ZdFduv\\nXMEJGKWeHUKnoMT4uaDEomlwqEUa5JcG3Z9R0PeCJsNXvns53uK1j1uMY395yIvW\\nyQ8yu1vDhD/OnnOMl6oro4IBEjCCAQ4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU\\nvk1BL8cxa/eNRSQDD/T+yTyA7sswgdEGA1UdIwSByTCBxoAUvk1BL8cxa/eNRSQD\\nD/T+yTyA7suhgZekgZQwgZExCzAJBgNVBAYTAkFUMQ8wDQYDVQQIDAZTdHlyaWEx\\nDTALBgNVBAcMBEdyYXoxGDAWBgNVBAoMD09YTCBJVCBTZXJ2aWNlczESMBAGA1UE\\nCwwJTG9nc2VydmVyMRUwEwYDVQQDDAxMb2dzZXJ2ZXIgQ0ExHTAbBgkqhkiG9w0B\\nCQEWDmNvbnRhY3RAb3hsLmF0ghRSS5x0wjfeV7qkHEaDDpZE/bI+VzALBgNVHQ8E\\nBAMCAQYwCgYIKoZIzj0EAwIDZwAwZAIwHbFj7SEsIg3dUBpAkKIfLWVrpKicxDUe\\nKqUd/hcXHX/TTKKd0yehyXhZR0HBYgHEAjAbxJb8pQIVzCowHcXmv790wOiSsaFL\\nQJuH8qil1t0JSAV73EdK9zM+IDdvBVdDlBw=\\n-----END CERTIFICATE-----\\n', 'f': 'log_ca.crt'})",
# "ok: [srv1] => (item={'c': '-----BEGIN CERTIFICATE-----\\nMIIDgTCCAwagAwIBAgIQX7p1IkBq4b97O8k0caiMfjAKBggqhkjOPQQDAjCBkTEL\\nMAkGA1UEBhMCQVQxDzANBgNVBAgMBlN0eXJpYTENMAsGA1UEBwwER3JhejEYMBYG\\nA1UECgwPT1hMIElUIFNlcnZpY2VzMRIwEAYDVQQLDAlMb2dzZXJ2ZXIxFTATBgNV\\nBAMMDExvZ3NlcnZlciBDQTEdMBsGCSqGSIb3DQEJARYOY29udGFjdEBveGwuYXQw\\nHhcNMjQxMjI0MTQyNzA4WhcNMjkxMjIzMTQyNzA4WjCBjDELMAkGA1UEBhMCQVQx\\nDzANBgNVBAgMBlN0eXJpYTENMAsGA1UEBwwER3JhejEYMBYGA1UECgwPT1hMIElU\\nIFNlcnZpY2VzMRIwEAYDVQQLDAlMb2dzZXJ2ZXIxEDAOBgNVBAMMB2dlbmVyaWMx\\nHTAbBgkqhkiG9w0BCQEWDmNvbnRhY3RAb3hsLmF0MHYwEAYHKoZIzj0CAQYFK4EE\\nACIDYgAEF2uLX4WUd/4byt3aS59XxohILfEdnNvqdg87nG0PXC85yhtB5yKMWryT\\n+cWZeGYSucdLtZ4UxDqvosQ32eql/K+VoVRqkb4UF1Mmgq5+smhHIkVxFjJCUtsg\\ni+G9aPM/o4IBJDCCASAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUmULR2FK41wLFEl/B\\nSGhYkQ0Z5v8wgdEGA1UdIwSByTCBxoAUvk1BL8cxa/eNRSQDD/T+yTyA7suhgZek\\ngZQwgZExCzAJBgNVBAYTAkFUMQ8wDQYDVQQIDAZTdHlyaWExDTALBgNVBAcMBEdy\\nYXoxGDAWBgNVBAoMD09YTCBJVCBTZXJ2aWNlczESMBAGA1UECwwJTG9nc2VydmVy\\nMRUwEwYDVQQDDAxMb2dzZXJ2ZXIgQ0ExHTAbBgkqhkiG9w0BCQEWDmNvbnRhY3RA\\nb3hsLmF0ghRSS5x0wjfeV7qkHEaDDpZE/bI+VzALBgNVHQ8EBAMCBaAwEwYDVR0l\\nBAwwCgYIKwYBBQUHAwIwCgYIKoZIzj0EAwIDaQAwZgIxAKVAFBs4EaCRx/0VEZKA\\n3/n06CaEE5I05v8kN5XBWgbJPxaDi+bcRJrzBMsn/JRjvwIxAMi4cekyGCWZYDtM\\n+8WRliIMba5dbFuR/UGAf/bIfmNWM2sSqtzseSZ/RoPdjaChlQ==\\n-----END CERTIFICATE-----\\n', 'f': 'log_client.crt'})",
# "",
# "TASK [Add certificate key] *****************************************************",
# "ok: [srv1]",
# "",
# "TASK [Add graylog forwarding] **************************************************",
# "ok: [srv1]",
# "",
# "TASK [Software log files] ******************************************************",
# "ok: [srv1]",
# "",
# "TASK [Software log rotation] ***************************************************",
# "ok: [srv1]",
# "",
# "TASK [Restart services] ********************************************************",
# "changed: [srv1] => (item=rsyslog.service)",
# "changed: [srv1] => (item=logrotate.service)",
# "",
# "PLAY RECAP *********************************************************************",
# "srv1 : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0"
# ],
# "stderr_lines": [
# "Identity added: /tmp/ar_znjp4bih/.fIWqOdKaPzGioFfDljSw (Demo)"
# ]
# }
# }
# to stop a running execution
e = Execution(c)
e.run(blocking=False)
# you could 'tail -f' the log files
e.stop() # executor sends signals to subprocess running ansible
Use-Cases
See: Our simple Ansible WebUI
Contribute
We are happy to see contributions. (:
- Report issues
- Create feature-requests
- Provide PR's for:
- more Unit-Tests
- more Integration-Tests
- fixing bugs/errors
- enhancing the input-validation
- ...
Security Considerations
- Secrets are passed to Ansible via one-time-readable FIFO/Pipes
- SSH-agent is used to pass SSH-keys to Ansible
- Files are created with an explicit
0600file-mode - By default, the temporary runtime-directory is removed after the execution has finished (only log-files remain - see example above)
- tbc
AI-Usage Info
The coding of this project involved minimal AI-usage.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oxl_ansible_executor_plugins-0.5.tar.gz.
File metadata
- Download URL: oxl_ansible_executor_plugins-0.5.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54994e3c0659689f233f795bf26916a1bdb7b0ffde0cfd738e06f88f13ad366a
|
|
| MD5 |
a36461e23ff9c66a859699db422b90b9
|
|
| BLAKE2b-256 |
dc9d5a5f204df3e39959e780dab8697c7b761988d18c683c4c9931871f65b36e
|
File details
Details for the file oxl_ansible_executor_plugins-0.5-py3-none-any.whl.
File metadata
- Download URL: oxl_ansible_executor_plugins-0.5-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca6a4476d1661c893d1a0379d982e3611b7d2b2a7bd265f491e98d4bd02e9764
|
|
| MD5 |
034d4be926b3a4b9c92b3386cf589f32
|
|
| BLAKE2b-256 |
c7f7bbe09796142b1d2d475be3d6495f050dffc48b2d4aa7a51c089ff96a0247
|