asyncio ansible tower like shed to run playbooks and have prometheus collector stats
Project description
ansible_shed
Simple Ansible tower to run playbooks via ansible-playbook + export prometheus metrics about success.
Example Run + Stats
Playbook(s) will be run on host(s) and then the output parsed to generated statistics
Log example:
[2021-03-09 15:59:36,239] DEBUG: Starting /usr/local/bin/ansible-shed (main.py:71)
[2021-03-09 15:59:36,239] DEBUG: Using selector: EpollSelector (selector_events.py:59)
[2021-03-09 15:59:36,241] DEBUG: Prometheus metrics server starting on :::12345/metrics (service.py:133)
[2021-03-09 15:59:36,243] INFO: Rebasing /tmp/ansible_shed/repo from git@github.com:cooperlees/clc_ansible.git (shed.py:36)
[2021-03-09 15:59:36,246] DEBUG: Prometheus metrics server started on http://[::]:12345/metrics (service.py:160)
[2021-03-09 15:59:36,246] INFO: Serving prometheus metrics on: http://[::]:12345/metrics (shed.py:150)
Already up to date.
Current branch master is up to date.
[2021-03-09 15:59:37,480] INFO: Running ansible-playbook: '/home/cooper/venvs/a/bin/ansible-playbook --inventory hosts site.yaml --limit home2.cooperlees.com --tags chrony --skip-tags php_static_files,zfs' (shed.py:70)
[2021-03-09 15:59:38,906] DEBUG: negotiating {'*/*'} resulted in choosing TextFormatter (negotiator.py:32)
[2021-03-09 15:59:38,908] INFO: ::1 [09/Mar/2021:15:59:38 +0000] "GET /metrics HTTP/1.1" 200 1128 "-" "curl/7.68.0" (web_log.py:206)
[2021-03-09 15:59:53,651] INFO: Finished running ansible in 16s (shed.py:75)
[2021-03-09 15:59:53,651] INFO: Parsing ansible run output to update stats (shed.py:79)
[2021-03-09 15:59:53,652] DEBUG: Host Results: home2.cooperlees.com - ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 (shed.py:92)
[2021-03-09 15:59:53,652] DEBUG: Updating prometheus stats due to event being set (shed.py:129)
[2021-03-09 15:59:53,652] INFO: Updated 10 metrics (shed.py:141)
[2021-03-09 15:59:53,652] INFO: Finished ansible run in 17s. Sleeping for 43s (shed.py:176)
[2021-03-09 15:59:53,652] DEBUG: Stats:
{
"ansible_last_run_returncode": 0,
"ansible_last_run_time": 16,
"ansible_stats_last_updated": 1615305593,
"host_home2.cooperlees.com_changed": 0,
"host_home2.cooperlees.com_failed": 0,
"host_home2.cooperlees.com_ignored": 0,
"host_home2.cooperlees.com_ok": 7,
"host_home2.cooperlees.com_rescued": 0,
"host_home2.cooperlees.com_skipped": 1,
"host_home2.cooperlees.com_unreachable": 0
} (shed.py:177)
[2021-03-09 15:59:57,045] DEBUG: negotiating {'*/*'} resulted in choosing TextFormatter (negotiator.py:32)
[2021-03-09 15:59:57,047] INFO: ::1 [09/Mar/2021:15:59:57 +0000] "GET /metrics HTTP/1.1" 200 1577 "-" "curl/7.68.0" (web_log.py:206)
Metrics Example:
# HELP ansible_changed Number of 'changed' plays
# TYPE ansible_changed gauge
ansible_changed{hostname="home2.cooperlees.com"}
# HELP ansible_failed Number of failed plays on hosts
# TYPE ansible_failed gauge
ansible_failed{hostname="home2.cooperlees.com"} 0
# HELP ansible_ignored Number of ignored plays on hosts
# TYPE ansible_ignored gauge
ansible_ignored{hostname="home2.cooperlees.com"} 0
# HELP ansible_last_run_returncode UNIX return code of the ansible-playbook process
# TYPE ansible_last_run_returncode gauge
ansible_last_run_returncode 0
# HELP ansible_last_run_time Time in seconds it took the ansible-playbook process to execute
# TYPE ansible_last_run_time gauge
ansible_last_run_time 17
# HELP ansible_ok Number of 'ok' (no change) plays
# TYPE ansible_ok gauge
ansible_ok{hostname="home2.cooperlees.com"} 7
# HELP ansible_rescued Number of rescued plays on hosts
# TYPE ansible_rescued gauge
ansible_rescued{hostname="home2.cooperlees.com"} 0
# HELP ansible_skipped Number of skipped plays on hosts
# TYPE ansible_skipped gauge
ansible_skipped{hostname="home2.cooperlees.com"} 1
# HELP ansible_stats_last_updated UNIX timestamp of last time we updated the stats
# TYPE ansible_stats_last_updated gauge
ansible_stats_last_updated 1615305655
# HELP ansible_unreachable Number of inaccessible hosts
# TYPE ansible_unreachable gauge
ansible_unreachable{hostname="home2.cooperlees.com"} 0
- Avaliable http://IP:PORT/metrics
- All aioprometheus powered
- Additional REST APIs (token-authenticated using
X-API-Tokenheader):POST /pausewithtimestampin JSON body (UNIX epoch or ISO8601) or queryPOST /force-runGET /healthzvalidatesansible-playbook --helpandgit --help
API CLI
ansible_shed now installs ansible-shed-cli in the same Python environment as the
service. It reads api_token and port from the same config file:
ansible-shed-cli --config /etc/ansible_shed.ini pause --timestamp 1735689600ansible-shed-cli --config /etc/ansible_shed.ini force-runansible-shed-cli --config /etc/ansible_shed.ini healthz
Grafana Dashboard
- Available here: https://grafana.com/grafana/dashboards/14073
Install
We're not on PyPI as I don't feel the need (if we get popular that's easy to fix).
pip install git+https://github.com/cooperlees/ansible_shed
or if you want ansible tools installed into the same Python environment use our ansible extra install:
pip install git+https://github.com/cooperlees/ansible_shed#egg=ansible_shed[ansible]
SystemD
Today I only run it by systemd cause it makes SSH auth easier. Would happily take a Dockerfile PR.
Config
(TODO: Full config file docs - PR welcome)
We have a simple ini file to point @ your ansbile-playbook binary and arguments.
If not specified, ansible_shed defaults to look for /etc/ansible_shed.ini
- We have an example config here: ansible_shed.ini
Config Settings:
interval: Minutes betweenansible-playbookrunsstart_splay: Upper max of time to wait before firstansible-playbookrun after starting the service - Code generates a random int from 0 to this upper max.port: Statistics listening port + intervalvault_pass_file: (Optional) Path to Ansible vault password file. If set, this file will be copied to.vault_passin the checked out repo and ansible-playbook will be run with--vault-password-fileflag.api_token: API token required inX-API-Tokenfor/pause,/force-run, and/healthzansible_playbook_binary: Must point to anansible-playbookbinary inside a Python virtualenv (<venv>/bin/ansible-playbook); ansible_shed uses the sibling<venv>/bin/activatescript path to activate that venv environment
mypyc build/install
ansible_shed can be compiled with mypyc. The code is strictly typed and that allows for it to be converted to C and compiled.
To enable, set a environment variable asking for a mypyc build
Only tested on Linux
export MYPYC_BUILD=1pip install -U pip mypy setuptools wheelpip install ansible_shed
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 ansible_shed-2026.5.6.tar.gz.
File metadata
- Download URL: ansible_shed-2026.5.6.tar.gz
- Upload date:
- Size: 27.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4ef4bdcb980cf0d27191361bc90a30be162819a68668c1edc45b7dfce68775d
|
|
| MD5 |
99b17ab2f833940dd1ffbcb34dc3d602
|
|
| BLAKE2b-256 |
c6a76e8ef086f85ce44615a6b150fbc41b05f2a88201881c24eee03f96cd3b2b
|
Provenance
The following attestation bundles were made for ansible_shed-2026.5.6.tar.gz:
Publisher:
release.yml on cooperlees/ansible_shed
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ansible_shed-2026.5.6.tar.gz -
Subject digest:
c4ef4bdcb980cf0d27191361bc90a30be162819a68668c1edc45b7dfce68775d - Sigstore transparency entry: 1445360714
- Sigstore integration time:
-
Permalink:
cooperlees/ansible_shed@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Branch / Tag:
refs/tags/2026.5.6 - Owner: https://github.com/cooperlees
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ansible_shed-2026.5.6-py3-none-any.whl.
File metadata
- Download URL: ansible_shed-2026.5.6-py3-none-any.whl
- Upload date:
- Size: 30.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c916bb9bbf2a4b7ffe5e96645fab4082b679ac42aa6092911326e8e3dad89d6
|
|
| MD5 |
6a726acd836c30782f0d969384213ebf
|
|
| BLAKE2b-256 |
c9c0ba019be12009ec6823a8ea920127cc94c2be6853c391feb6091a8dcb948c
|
Provenance
The following attestation bundles were made for ansible_shed-2026.5.6-py3-none-any.whl:
Publisher:
release.yml on cooperlees/ansible_shed
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ansible_shed-2026.5.6-py3-none-any.whl -
Subject digest:
3c916bb9bbf2a4b7ffe5e96645fab4082b679ac42aa6092911326e8e3dad89d6 - Sigstore transparency entry: 1445361371
- Sigstore integration time:
-
Permalink:
cooperlees/ansible_shed@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Branch / Tag:
refs/tags/2026.5.6 - Owner: https://github.com/cooperlees
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ansible_shed-2026.5.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: ansible_shed-2026.5.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 432.2 kB
- Tags: CPython 3.14, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
809a4b5df805b9acd926a09de2019e7676663cb988ae77fcb90dfa9bae09040a
|
|
| MD5 |
47521e4906991d3a63b486012e20fd60
|
|
| BLAKE2b-256 |
d57c4ed5eeecc388bc5b536b89b7db19aa44b9c6f7bf72146e29a5a56befd3f3
|
Provenance
The following attestation bundles were made for ansible_shed-2026.5.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
release.yml on cooperlees/ansible_shed
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ansible_shed-2026.5.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
809a4b5df805b9acd926a09de2019e7676663cb988ae77fcb90dfa9bae09040a - Sigstore transparency entry: 1445361566
- Sigstore integration time:
-
Permalink:
cooperlees/ansible_shed@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Branch / Tag:
refs/tags/2026.5.6 - Owner: https://github.com/cooperlees
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ansible_shed-2026.5.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: ansible_shed-2026.5.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 431.2 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf04b97f655132e8658f7c01758ad02cc05c42430cd30487e07ce7d0f2b73336
|
|
| MD5 |
46ee327e24224966efc41ac4013c9736
|
|
| BLAKE2b-256 |
057fbc56ebdf5a536290570f22cbb203312aba7f080b7bb36ea899eba2e2f556
|
Provenance
The following attestation bundles were made for ansible_shed-2026.5.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
release.yml on cooperlees/ansible_shed
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ansible_shed-2026.5.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
cf04b97f655132e8658f7c01758ad02cc05c42430cd30487e07ce7d0f2b73336 - Sigstore transparency entry: 1445362232
- Sigstore integration time:
-
Permalink:
cooperlees/ansible_shed@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Branch / Tag:
refs/tags/2026.5.6 - Owner: https://github.com/cooperlees
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6a157b98e5306b2eb3e5ce2a1aea7f06dd6b98d3 -
Trigger Event:
release
-
Statement type: