Gardience Documentation gardience.com →
Docs / Using Gardience

Ansible playbooks

Gardience runs existing Ansible playbooks over the Salt connection it already has to every node. You do not need WinRM on Windows nodes, SSH keys for Linux nodes, or an inventory file.

Start here: Automation > Ansible

Automation > Ansible is the home for everything Ansible, in three steps:

  1. Bring your playbooks. Connect a Git repository, start a local project, or import from AWX or Ansible Automation Platform. Each opens the right part of Projects.
  2. Choose a playbook and its machines. Pick a playbook and the group it runs on, then Make it runnable. Each variable the playbook declares becomes a field on its run form. Passwords it prompts for come from the secrets vault by name.
  3. Run, schedule, or require approval. Under Your playbooks, Run… opens the form (with Check mode to preview the changes), Schedule… runs it on a schedule, and Workflows and approvals adds a sign-off step before it runs.

Each playbook shows when it last ran, its result, and who ran it. Recent Ansible runs shows live logs. Coming from AWX or Ansible Automation Platform? The table at the bottom of the page shows where each AWX feature lives in Gardience.

People who are not admins can run playbooks there. An admin makes them runnable.

There are two ways to run a playbook:

ModeRunbookNodesWhere ansible-playbook runs
Controller modeRun an Ansible playbook (Windows and Linux, no WinRM)Windows and LinuxOn the Gardience server, in the separate playbook runner
Local modeRun an Ansible playbook (Linux)Linux onlyOn each node, against itself

Uploads from the gdn command line use controller mode.

Controller mode

How it works

  1. Gardience builds the inventory from the target nodes. Windows nodes use PowerShell. Linux nodes use their own Python.
  2. The playbook runs in the playbook runner, a separate container that holds no Gardience data or secrets. Each run gets its own unprivileged account and private folder, and anything the run leaves behind is removed when it ends.
  3. Each command a task sends to a node goes as a Salt job to that node only. The command and its result are encrypted with that node's own key, so Salt's job history only ever holds encrypted data.
  4. The run can reach only the nodes it was approved for, and only for the length of the run (at most 4 hours).

One step of a playbook may run for up to an hour, for example a large Windows update. To change that for one playbook, set the variable gardience_salt_timeout (in seconds). If a command's message to a node or the node's answer is lost on the way, Gardience notices within about a minute and sends the command again. The node never runs the same command twice: it returns the saved result instead.

If a command gets no answer, Gardience sends it again. Each command carries an ID, so a node that already ran it returns the saved result instead of running it twice.

Who can run it

Running a playbook means running commands on the nodes. The person behind the run needs command-execution rights (cmd.run_all) on every target node, or the run is refused.

Controller runs go through the same checks as any runbook:

Run a playbook

  1. Open Automation > Runbooks.
  2. On Run an Ansible playbook (Windows and Linux, no WinRM), choose Run….
  3. Fill in the form:

    • Node group: the nodes to run on.
    • Project: the demo project that ships with the server, or one of your Git projects.
    • Playbook (path in the project): for example site.yml or playbooks/web.yml.
    • Limit to machines: optional. Machine names or wildcards separated by commas, with ! to leave one out, for example web-*,!web-03. The limit only narrows the node group, and approvals, locks and the audit log see the narrowed list.
    • Only these tags: optional. Ansible tags separated by commas, like --tags.
    • Extra variables: optional. name=value pairs separated by spaces, like -e. Names starting with ansible_ or gardience_ are refused, so a run can never leave the Salt connection.
    • Vault secrets to pass: secret names, separated by commas. Leave empty for none.
    • Check mode (preview only): True runs Ansible with --check --diff, which shows what would change without changing it.
  4. Choose Run now as your name.

The run log shows each node's result with Ansible's own ok, changed and failed counts, followed by a PLAY RECAP. If ansible-playbook cannot start (for example, because of a YAML error), the log shows its error message.

Git projects

Keep your playbooks in Git, the way you did with AWX or Ansible Automation Platform, and run them from Gardience.

Add a project

  1. Choose how Gardience reaches the repository:

    • https with a token: store an access token in the Secrets vault first, either the token alone or user:token. GitHub, GitLab, Bitbucket, Azure DevOps and Gitea tokens all work. A public repository needs no token.
    • SSH with a deploy key: use an SSH address such as git@github.com:acme/infra.git or ssh://git@git.example.com:2222/srv/git/infra.git. Gardience creates a key pair for the project and shows its public key on the Projects page. Add it to the repository as a read-only deploy key (GitHub: Settings, Deploy keys; GitLab: Settings, Repository, Deploy keys; Bitbucket: Repository settings, Access keys), then choose Sync now. The private key is sealed with the server's vault key and never shown.
  2. Open Automation > Projects.
  3. Under Add a Git project, fill in:

    • Name: lowercase letters, digits, - and _, up to 40 characters.
    • Clone address: the https address, with no user name or token in it.
    • Branch or tag: main unless you say otherwise.
    • Token from the vault: the secret name from step 1. Leave empty for a public repository.
    • Pin to commit: optional. A full 40-character commit id. The project then stays on exactly that commit until you change or clear it.
    • Sync on a timer: every hour, every 6 hours, or every day. Off by default (sync by hand, by webhook, or before a run). A sync that fails waits for the next turn.
    • Update before every run: Gardience syncs the branch before each run of a playbook from this project.
    • Allow choosing a branch, tag or commit at run time: see below.
  4. Choose Save. An https project syncs right away; an SSH project syncs once you have added its deploy key.

Only admins add, sync and delete projects. A sync:

Every run from a Git project logs the project, the commit and the time of the sync.

Your Git projects at the top of the page lists every project with what it follows, its status, its commit and how many playbooks it has. Under each project, Sync history keeps its last 20 syncs: when, who or what started it (a person, the push webhook, the timer, or a run), whether it worked, the commit it moved from and to (or "no new commits"), how long it took, and the install log. Tokens are removed from the log.

Python packages

Some collections need Python packages on the controller, for example VMware or cloud collections. List them in a requirements.txt at the top of the project (one package per line, with an optional version, such as pyvmomi>=8.0). Gardience also reads the requirements.txt of each collection the project installs. At sync, Gardience installs them into the project:

Playbooks from the project then find the packages when they run. This is what AAP's execution environments are for, without building container images.

Collections source

By default, collections come from Ansible Galaxy and Python packages from PyPI. On a private or air-gapped network, set Collections source on the Projects page to your own Galaxy server (Automation Hub, Galaxy NG or Pulp) and your own Python package index (Artifactory, Nexus or devpi). Every collection and package Gardience downloads is also kept in a mirror on the server, so a later sync still installs it when the Galaxy server cannot be reached. The playbook runner itself never needs the internet: collections and roles travel with the project.

Sync on every push

Each project has a push webhook. On the Projects page, open Push webhook under the project for the payload address and secret.

Git hostWhere the secret goes
GitHub, Gitea, ForgejoThe webhook's secret (Gardience checks the signature)
GitLabThe webhook's secret token
Anything elseAn X-Gardience-Token header

A push to another branch is ignored. A webhook with the wrong secret gets HTTP 403 and changes nothing.

Signed commits only

To make sure only code from your own developers runs, edit the project, tick Only run commits signed by an approved developer, and paste each developer's SSH public key, one per line, as GitHub shows it (ssh-ed25519 AAAA... ann@acme.com). From then on every sync, manual, by webhook, on the timer, before a run or for a branch chosen at run time, checks the commit it lands on:

So a stolen Git password, or a push by someone with access to the repository but not on your list, never reaches a machine. Developers sign with the SSH key they already use:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

GitHub, GitLab and Bitbucket then mark their commits Verified once the same key is added there as a signing key. SSH signatures are checked; GPG signatures are not yet.

Choose a branch at run time

When a project allows it, a run can use another branch, tag or commit than the project's own, for example to try a feature branch before it is merged (AWX calls this branch override). The built-in controller runbook and runbooks made from that project's playbooks then show Branch, tag or commit. Gardience fetches that branch for the run only, logs its commit, and keeps the five most recently used branches cached. A project that does not allow it refuses such a run.

A branch that is not merged yet may hold code nobody has reviewed. Allow this only on projects where that is acceptable, and keep change windows and approvals on production groups.

Turn a playbook into a runbook

On the Projects page, each playbook has Make a runbook. Gardience reads the playbook and builds a form:

People who may run runbooks then run the playbook from that form, without writing YAML or knowing Ansible. Form values may only use letters, digits, spaces and . , : @ / + = _ -, so a value can never carry Ansible template code.

Import from AWX or Ansible Automation Platform

To move projects, job templates, schedules and inventory groups from AWX or Ansible Automation Platform:

  1. On a machine that can reach AWX or AAP, install the awx command and export:

    pip install awxkit
    awx export --projects --job_templates --inventory --schedules > awx.json
  2. In Gardience, open Automation > Projects and, under Import from AWX or Ansible Automation Platform, choose the file and Preview.
  3. Read the preview. Nothing is created until you choose Import.
From AWX or AAPBecomes in Gardience
Git project (https or SSH address, branch, update on launch, allow branch override)Git project (an SSH project gets a new deploy key to add)
Job template (playbook, survey, extra variables, limit, tags, skip tags, check mode)Runbook with a form
Survey text, number and choice questionsForm fields
Survey password questionsA vault secret of the same name, passed by the runbook
Inventory and its groupsNode groups of the machines Gardience manages, matched by name or short name
Weekly, daily and monthly (nth or last weekday) schedulesSchedules, imported turned off

The preview lists everything that does not carry over, and why. Repository tokens are not in exports (store them in the vault and set them on the project). Machine credentials are not needed, because Gardience reaches machines over Salt. Workflow templates, notifications, teams, roles, custom execution environments and schedules other than daily, weekly or the nth weekday of the month are not imported. Imported schedules start turned off, so nothing runs until an admin turns each one on.

Projects without Git

Local projects keep playbooks, states and scripts on the Gardience server, in folders, with no Git host. On Automation > Projects, choose New local project and give it a name. It starts with playbooks, states and scripts folders. Admins work in its file browser:

Playbooks in a local project become runbooks with Make a runbook, and states in its states folder publish under Automation > States (see States). Every change is in the audit log as project.file_saved. Under the hood each local project is a Git repository on the server, so its history is a real commit history.

You can also copy a project folder into srv/ansible/projects/ in your Gardience install directory, for example srv/ansible/projects/webapp/ with site.yml inside it. It appears on the Projects page as shipped with the server, and Make a runbook works the same way.

Ask the AI assistant for a playbook

Ask Ask Gardience for one in plain words, for example "write an Ansible playbook that runs yum update on the RHEL and Oracle machines". It shows the playbook and the node group; Dry run runs it in check mode, Run for real runs it. The playbook is saved in your own upload folder, so you can run it again with gdn or the API, and only you can run it. Running a playbook needs command-execution rights, as above. See AI assistant.

Upload a playbook with gdn

The gdn command line runs a playbook file from your own computer through Gardience. It needs Python 3 and an API key with the Operate scope.

  1. In Administration > Settings, under API keys, create a key with the scope Operate (request runbooks). Copy it; it is shown once.
  2. Download gdn and sign in. Replace gardience.example.com with your server's address:

    curl -fsSLo gdn https://gardience.example.com/gardience/cli/gdn && chmod +x gdn
    ./gdn login https://gardience.example.com

    If the server uses a certificate your computer does not trust, pass it with --ca, for example ./gdn login https://gardience.example.com --ca gardience.crt.

  3. Run the playbook on a node group:

    ./gdn playbook site.yml -l webservers --check
    ./gdn playbook site.yml -l webservers --secrets db_password

Options:

OptionMeaning
-l, --limitThe node group to run on (required).
--checkCheck mode: show what would change.
--secretsVault secret names, separated by commas.
--reasonA reason shown with the request.
--no-waitStart the run and return. Follow it with ./gdn status RUN_ID.

What happens to an upload:

Local mode (Linux)

In local mode, each Linux node runs the playbook against itself. Gardience copies the project to the node over the Salt connection.

Before the first run, install the Ansible runtime on the nodes by applying the Salt state ansible.runtime. You can do this with a custom runbook whose Salt function is state.apply and whose Arguments is ansible.runtime. The state installs ansible-core 2.18 and the ansible.posix collection into /opt/gardience-ansible, away from the system Python.

To run a playbook, use the Run an Ansible playbook (Linux) runbook. Its form has the same fields as controller mode, plus Login banner text, which the demo playbook uses. Projects come from the same srv/ansible/projects/ folder.

Local mode does not run on Windows nodes. Use controller mode for Windows.

Secrets in playbooks

List the secret names in the runbook's Vault secrets field, or with --secrets in gdn. In the playbook, refer to each secret as a variable with the same name:

- hosts: all
  tasks:
    - name: Write the database password
      ansible.builtin.copy:
        content: "{{ db_password }}"
        dest: /etc/app/db.pass
        mode: "0600"
Gardience by Bouziden Management LLC.