Small Ansible - Minimal Ansible-compatible runner for Windows and Linux
Project description
Sansible
A minimal, pure-Python Ansible runner for Windows and Linux
Sansible runs Ansible playbooks natively on Windows without WSL, targeting both Windows (WinRM) and Linux (SSH) hosts. It delivers 80% of Ansible's value with 20% of the code.
✨ Highlights
- 🪟 Windows Native — Run as a control node on Windows, no WSL required
- 🐍 Pure Python — Ships as `py3-none-any` wheel, no compiled extensions
- 🚀 Fast Setup — `pip install sansible` and you're ready
- 📦 Ansible Compatible — Uses the same playbook/inventory syntax
- 🎯 Focused — Core features that cover most use cases
🚀 Quick Start
Installation
```bash
Basic installation (local execution only)
pip install sansible
With SSH support (Linux/Unix targets)
pip install "sansible[ssh]"
With WinRM support (Windows targets)
pip install "sansible[winrm]"
Full installation (all transports)
pip install "sansible[all]" ```
Your First Playbook
Create `hello.yml`:
```yaml
- name: Hello World
hosts: localhost
gather_facts: false
tasks:
-
name: Say hello debug: msg: "Hello from Sansible!"
-
name: Run a command command: echo "It works!" register: result
-
name: Show result debug: var: result.stdout ```
-
Create `inventory.ini`:
```ini [local] localhost ansible_connection=local ```
Run it:
```bash san run -i inventory.ini hello.yml ```
Output:
``` PLAY [Hello World] ************************************************************
TASK [Say hello] ************************************************************** ok: [localhost]
TASK [Run a command] ********************************************************** changed: [localhost]
TASK [Show result] ************************************************************ ok: [localhost]
PLAY RECAP ******************************************************************** localhost : ok=3 changed=1 failed=0 ```
📖 Examples
The `examples/playbooks/` directory contains runnable examples for all features:
| Playbook | Features |
|---|---|
| 01_basics.yml | debug, set_fact, command, shell, copy |
| 02_conditionals.yml | when, loop, register, changed_when |
| 03_file_management.yml | file, copy, stat, lineinfile |
| 04_handlers.yml | handlers, notify, listen |
| 05_blocks.yml | block, rescue, always |
| 06_become.yml | become (sudo) |
| 07_gather_facts.yml | gather_facts, setup |
| 08_wait_for.yml | wait_for (port, file) |
| 09_assert_fail.yml | assert, fail |
| 10_roles.yml | roles |
| 11_check_diff.yml | --check, --diff modes |
Windows Examples:
| Playbook | Features |
|---|---|
| win_01_basics.yml | win_command, win_shell, win_copy |
| win_02_services.yml | win_service |
| win_03_files.yml | win_stat, win_lineinfile |
Run any example:
```bash san run -i examples/playbooks/inventory.ini examples/playbooks/01_basics.yml -l localhost ```
🛠 Supported Features
Modules
| Linux | Windows | Purpose |
|---|---|---|
| `command` | `win_command` | Execute command |
| `shell` | `win_shell` | Execute shell/PowerShell |
| `copy` | `win_copy` | Copy files |
| `file` | `win_file` | Manage files/directories |
| `template` | — | Render Jinja2 templates |
| `stat` | `win_stat` | Get file info |
| `lineinfile` | `win_lineinfile` | Manage lines in files |
| `wait_for` | `win_wait_for` | Wait for port/file |
| `setup` | `setup` | Gather facts |
| `debug` | `debug` | Print messages |
| `set_fact` | `set_fact` | Set variables |
| `fail` | `fail` | Fail with message |
| `assert` | `assert` | Assert conditions |
| — | `win_service` | Manage Windows services |
Playbook Features
| Feature | Status | Notes |
|---|---|---|
| Multiple plays | ✅ | Sequential execution |
| Variables (`vars`, `vars_files`) | ✅ | Full support |
| Conditionals (`when`) | ✅ | Jinja2 expressions |
| Loops (`loop`, `with_items`) | ✅ | List iteration |
| Handlers (`notify`, `listen`) | ✅ | Triggered on change |
| Error handling (`block/rescue/always`) | ✅ | Try/catch blocks |
| Privilege escalation (`become`) | ✅ | sudo, su |
| Fact gathering (`gather_facts`) | ✅ | OS info |
| Roles | ✅ | tasks, defaults, vars |
include_role / import_role |
✅ | Dynamic role inclusion |
delegate_to |
✅ | Task delegation |
| Dynamic inventory | ✅ | Executable scripts |
| Vault | ✅ | Encrypted vars (requires cryptography) |
| Diff mode (`--diff`) | ✅ | Show changes |
| JSON output (`--json`) | ✅ | Machine-readable |
Connections
| Type | Dependency | Platform |
|---|---|---|
| `local` | None | Control node |
| `ssh` | `asyncssh` | Linux/Unix |
| `winrm` | `pypsrp` | Windows |
📋 CLI Reference
san run / sansible-playbook
```bash san run -i INVENTORY PLAYBOOK [OPTIONS]
Options: -i, --inventory FILE Inventory file or directory -l, --limit PATTERN Limit to hosts matching pattern -t, --tags TAGS Only run tagged tasks --skip-tags TAGS Skip tagged tasks -e, --extra-vars VARS Extra variables (JSON or key=value) -f, --forks N Parallel execution limit (default: 5) -C, --check Dry-run mode (no changes) --diff Show file differences --json JSON output format --vault-password-file Path to vault password file --ask-vault-pass Prompt for vault password -v/-vv/-vvv Verbosity level ```
Examples
```bash
Basic execution
san run -i inventory.ini playbook.yml
Limit to specific hosts
san run -i inventory.ini playbook.yml -l webservers
Check mode (dry run)
san run -i inventory.ini playbook.yml --check
Show what would change
san run -i inventory.ini playbook.yml --check --diff
Extra variables
san run -i inventory.ini playbook.yml -e "version=2.0"
JSON output for scripting
san run -i inventory.ini playbook.yml --json ```
⚠️ Not Supported
Sansible focuses on core features. These are not supported:
- Ansible Galaxy / Collections
async/poll- Callbacks / Plugins
Unsupported features raise `UnsupportedFeatureError` with a clear message.
🔧 Development
```bash
Clone repository
git clone https://github.com/small-ansible/sansible.git cd sansible
Install with dev dependencies
pip install -e ".[dev]"
Run tests
pytest tests/unit/ -v
Run a specific test
pytest tests/unit/test_become.py -v
Build wheel
pip wheel . -w dist/
Verify pure Python wheel
python -m tools.dep_audit ```
📊 Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 2 | Host failure(s) |
| 3 | Parse/syntax error |
| 4 | Unsupported feature |
📚 Documentation
- Architecture — System design
- Compatibility — Feature matrix
- Testing — Test instructions
- Contributing — Development guide
📄 License
MIT License — See LICENSE for details.
Made with ❤️ for Windows DevOps engineers who just want to run playbooks.
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 sansible-0.3.0.tar.gz.
File metadata
- Download URL: sansible-0.3.0.tar.gz
- Upload date:
- Size: 83.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f7560e31864f0fea4f5143cf8ac9adc9c174f16b53a89c2af331260548f159e
|
|
| MD5 |
3fb5511eb8cc5cf64c88673c6b45a83c
|
|
| BLAKE2b-256 |
7fd292e7042cb33569d883ecfa63801ab54cc9ab1f89082d38c62f9f4797b67f
|
File details
Details for the file sansible-0.3.0-py3-none-any.whl.
File metadata
- Download URL: sansible-0.3.0-py3-none-any.whl
- Upload date:
- Size: 107.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f5aae8e154ff78801933944901b4e43bdf7f0ea00f935b741ef284ae54268c5
|
|
| MD5 |
3d45cc0a25fa78e013dd089fdcf8f7e8
|
|
| BLAKE2b-256 |
0a8d6f3103050fbc10725e6daf9a324139110eb164d6b31edcdaab82fc74a9b2
|