Skip to main content

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
  • Additional REST APIs (token-authenticated using X-API-Token header):
    • POST /pause with timestamp in JSON body (UNIX epoch or ISO8601) or query
    • POST /force-run
    • GET /healthz validates ansible-playbook --help and git --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 1735689600
  • ansible-shed-cli --config /etc/ansible_shed.ini force-run
  • ansible-shed-cli --config /etc/ansible_shed.ini healthz

Grafana Dashboard

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

Config Settings:

  • interval: Minutes between ansible-playbook runs
  • start_splay: Upper max of time to wait before first ansible-playbook run after starting the service - Code generates a random int from 0 to this upper max.
  • port: Statistics listening port + interval
  • vault_pass_file: (Optional) Path to Ansible vault password file. If set, this file will be copied to .vault_pass in the checked out repo and ansible-playbook will be run with --vault-password-file flag.
  • api_token: API token required in X-API-Token for /pause, /force-run, and /healthz
  • ansible_playbook_binary: Must point to an ansible-playbook binary inside a Python virtualenv (<venv>/bin/ansible-playbook); ansible_shed uses the sibling <venv>/bin/activate script 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=1
  • pip install -U pip mypy setuptools wheel
  • pip install ansible_shed

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

ansible_shed-2026.5.6.tar.gz (27.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ansible_shed-2026.5.6-py3-none-any.whl (30.8 kB view details)

Uploaded Python 3

ansible_shed-2026.5.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (432.2 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

ansible_shed-2026.5.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (431.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

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

Hashes for ansible_shed-2026.5.6.tar.gz
Algorithm Hash digest
SHA256 c4ef4bdcb980cf0d27191361bc90a30be162819a68668c1edc45b7dfce68775d
MD5 99b17ab2f833940dd1ffbcb34dc3d602
BLAKE2b-256 c6a76e8ef086f85ce44615a6b150fbc41b05f2a88201881c24eee03f96cd3b2b

See more details on using hashes here.

Provenance

The following attestation bundles were made for ansible_shed-2026.5.6.tar.gz:

Publisher: release.yml on cooperlees/ansible_shed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ansible_shed-2026.5.6-py3-none-any.whl.

File metadata

File hashes

Hashes for ansible_shed-2026.5.6-py3-none-any.whl
Algorithm Hash digest
SHA256 3c916bb9bbf2a4b7ffe5e96645fab4082b679ac42aa6092911326e8e3dad89d6
MD5 6a726acd836c30782f0d969384213ebf
BLAKE2b-256 c9c0ba019be12009ec6823a8ea920127cc94c2be6853c391feb6091a8dcb948c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ansible_shed-2026.5.6-py3-none-any.whl:

Publisher: release.yml on cooperlees/ansible_shed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

File hashes

Hashes for ansible_shed-2026.5.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 809a4b5df805b9acd926a09de2019e7676663cb988ae77fcb90dfa9bae09040a
MD5 47521e4906991d3a63b486012e20fd60
BLAKE2b-256 d57c4ed5eeecc388bc5b536b89b7db19aa44b9c6f7bf72146e29a5a56befd3f3

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

File hashes

Hashes for ansible_shed-2026.5.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cf04b97f655132e8658f7c01758ad02cc05c42430cd30487e07ce7d0f2b73336
MD5 46ee327e24224966efc41ac4013c9736
BLAKE2b-256 057fbc56ebdf5a536290570f22cbb203312aba7f080b7bb36ea899eba2e2f556

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page