Skip to main content

Spage

Spage is a high-performance, modular Golang-based playbook runner. It is designed to be as compatible with Ansible as possible, while leveraging Go's performance and modularity for faster execution.

Spage does not depend on a Python interpreter on the target hosts. This simplifies the process of adopting Spage. For example, if you want to run a playbook on a host that still needs to be provisioned, you can do so with Spage. Simply target the host with your playbook and Spage will run it, no dependencies required. Or even better, generate a Go program out of your playbook, compile it to a binary (using the Golang toolchain), and run it on the target host.

Built entirely in Go, Spage leverages the language's performance and modularity to provide different execution engines for running playbooks. Currently, Spage supports running playbooks locally (just like Ansible), and inside of a Temporal workflow, with more execution engines planned for the future.

Getting Started

Get started by installing Spage through the installation guide. Once you're set up, write a playbook like the following:

playbook.yaml
- name: Tell me the time
shell: echo "The time is $(date)"
register: time

- name: Show me the time
debug:
msg: "The time is {{ time.stdout }}"

Note that while the syntax is similar to Ansible, Spage is not an Ansible implementation. The keen-eyed reader will notice that there are some notable differences between Spage and Ansible.

Once you've written your playbook, you can run it with Spage:

Running a playbook
$ spage run playbook.yaml

Or if you want to compile your playbook to a binary, you can do so with the following command:

Compiling a playbook
$ spage generate playbook.yaml -o generated_tasks.go
$ GOOS=linux GOARCH=amd64 go build -o your_spage_program your_spage_program.go
$ ./your_spage_program

For more details about how Spage transforms your playbooks into executable Go code, see the Code Generation documentation.

This will generate a Go program that you can run on the target host. Both methods will print the following output:

Output
TASK [Tell me the time] (localhost) ****************************************************
changed: [localhost] =>
cmd: "echo \"The time is $(date)\""
stdout: "The time is Wed Aug 27 22:18:44 CEST 2025\n"
stderr: ""

2025-08-27T22:18:44.119+0200 INFO msg: The time is The time is Wed Aug 27 22:18:44 CEST 2025
{"host": "localhost", "module": "debug", "action": "execute"}

TASK [Show me the time] (localhost) ****************************************************
ok: [localhost]
msg: The time is The time is Wed Aug 27 22:18:44 CEST 2025


PLAY RECAP ****************************************************
localhost : ok=1 changed=1 failed=0 skipped=0 ignored=0

Contributing

Spage is an open-source project, and contributions are welcome.

If you want to contribute, please check out the contributing guide.