Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Check

on:
pull_request:
push:
branches:
- main

env:
JETPACK_REPO: https://github.com/riffcc/jetpack
JETPACK_REF: main

jobs:
jetpack:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Clone Jetpack
run: git clone --depth 1 --branch "$JETPACK_REF" "$JETPACK_REPO" /tmp/jetpack

- name: Build Jetpack
run: cargo build --locked --bin jetpack
working-directory: /tmp/jetpack

- name: Validate
run: JETPACK_BIN=/tmp/jetpack/target/debug/jetpack ./scripts/check.sh
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.PHONY: check

check:
./scripts/check.sh
107 changes: 70 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,90 @@
# jetpack-expanso

Deploy [Expanso Edge](https://expanso.io) agents with
[Jetpack](https://github.com/riffcc/jetpack): a reusable, target-agnostic role
plus an example provisioning recipe and inventory.
[Jetpack](https://github.com/riffcc/jetpack).

The role installs, bootstraps, and runs `expanso-edge` on any Debian/EL host. How
those hosts come into being — Proxmox LXC, a VM, a cloud instance, or bare metal
— is a per-host `provision:` detail in inventory, not something the deploy play
knows about. (Consumers like Dragonfly drive Jetpack as a Rust crate rather than
running these playbooks.)
This repo contains a reusable `expanso-edge` role plus example inventory and a
Proxmox LXC provisioning recipe. The deploy playbook is target-agnostic: a host
can come from Proxmox LXC, a VM, a cloud instance, or bare metal as long as the
inventory describes how Jetpack should reach it.

## Layout

```
```text
deploy/
roles/expanso-edge/ # install + bootstrap + systemd (no curl|bash); runs anywhere
roles/expanso-edge/ # install, bootstrap, and run expanso-edge
playbooks/
expanso-edge.yml # the deploy — provision-agnostic (groups: edge, roles: expanso-edge)
provision-proxmox-lxc.yml # ONE recipe to stand up a fleet (instantiate); swap for VMs/cloud/etc.
inventory/ # committed, extensionless, NO secrets
groups/edge # the edge fleet
groups/proxmox # the Proxmox API host for the LXC recipe
group_vars/all # version, ostemplate, operator SSH key
host_vars/expanso-edge-0N # per-host provision: blocks (the target detail)
secrets.example/ # template for the secret overlay (copy -> secrets/)
expanso-edge.yml # deploy to the edge fleet
provision-proxmox-lxc.yml # optional Proxmox LXC provisioning recipe
inventory/ # committed inventory, no secrets
groups/edge
groups/proxmox
group_vars/all
host_vars/expanso-edge-0N
secrets.example/ # copy to deploy/secrets and fill in
scripts/
check.sh # local validation wrapper
```

## Validate

Run the local validation wrapper before changing inventory or roles:

```bash
./scripts/check.sh
```

The wrapper looks for `jetp` or `jetpack` on `PATH`. If you built Jetpack from
source or keep it elsewhere, set `JETPACK_BIN`:

```bash
JETPACK_BIN=/path/to/jetpack ./scripts/check.sh
```

Secrets never live in the committed inventory. They go in a separate overlay
inventory (`deploy/secrets/`, gitignored) that Jetpack merges on top:
It runs Jetpack syntax checks for both playbooks, validates the committed
inventory with `deploy/secrets.example`, and runs full checks for both
playbook/inventory combinations.

- `secrets/host_vars/mrow` — Proxmox API credentials (for the LXC recipe)
- `secrets/group_vars/edge` — the Expanso Cloud bootstrap key (`exp_bk_…`)
## Secrets

## Run
Secrets never live in the committed inventory. Copy the example overlay and
replace the placeholders:

```bash
cp -r deploy/secrets.example deploy/secrets # then fill in real values
cp -r deploy/secrets.example deploy/secrets
```

Expected local-only secret files:

```text
deploy/secrets/host_vars/mrow # Proxmox API credentials
deploy/secrets/group_vars/edge # Expanso Cloud bootstrap key
```

Jetpack merges inventories in order, so the secret overlay should be last:

# Deploy to the edge fleet (each host self-provisions from its provision: block):
jetp ssh --playbook deploy/playbooks/expanso-edge.yml \
--inventory deploy/inventory --inventory deploy/secrets \
--roles deploy/roles
```bash
jetp ssh \
--playbook deploy/playbooks/expanso-edge.yml \
--inventory deploy/inventory:deploy/secrets \
--roles deploy/roles
```

Inventories merge in the order given, so the secret overlay (last) wins on top of
the committed inventory. (`--inventory a:b` colon-syntax works too; repeating the
flag is clearer.)
## Provision Proxmox LXC Hosts

To scaffold the example Proxmox LXC fleet first, run the provisioning playbook:

```bash
jetp ssh \
--playbook deploy/playbooks/provision-proxmox-lxc.yml \
--inventory deploy/inventory:deploy/secrets \
--roles deploy/roles
```

To scaffold a fresh Proxmox LXC fleet first, run `provision-proxmox-lxc.yml` —
it writes the per-host `provision:` blocks and creates the containers. To target
VMs or bare metal instead, change the `provision:` blocks (or drop them); the
role and `expanso-edge.yml` don't change.
The provisioning playbook writes per-host `provision:` blocks and creates the
containers. To target VMs or bare metal, change or remove the `provision:`
blocks; the `expanso-edge` role and deploy playbook stay the same.

Re-runs are idempotent: existing hosts are reused, the agent restarts only when
the version actually changes, and a node is bootstrapped exactly once (its
credentials file is the guard).
Re-runs are intended to be idempotent. Existing hosts are reused, the agent
restarts only when the version changes, and a node is bootstrapped exactly once
because its credentials file is the guard.
54 changes: 54 additions & 0 deletions scripts/check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "${BASH_SOURCE[0]}")/.."

find_jetpack() {
if [[ -n "${JETPACK_BIN:-}" ]]; then
printf '%s\n' "$JETPACK_BIN"
return 0
fi

if command -v jetp >/dev/null 2>&1; then
command -v jetp
return 0
fi

if command -v jetpack >/dev/null 2>&1; then
command -v jetpack
return 0
fi

printf 'error: set JETPACK_BIN or install jetp/jetpack on PATH\n' >&2
return 127
}

JETPACK_BIN="$(find_jetpack)"
ROLES="deploy/roles"
INVENTORY="deploy/inventory:deploy/secrets.example"

run() {
printf '\n==> %s\n' "$*"
"$JETPACK_BIN" "$@"
}

run syntax-check \
--playbook deploy/playbooks/expanso-edge.yml \
--roles "$ROLES"

run syntax-check \
--playbook deploy/playbooks/provision-proxmox-lxc.yml \
--roles "$ROLES"

run inventory-check \
--inventory "$INVENTORY"

run full-check \
--playbook deploy/playbooks/expanso-edge.yml \
--inventory "$INVENTORY" \
--roles "$ROLES"

run full-check \
--playbook deploy/playbooks/provision-proxmox-lxc.yml \
--inventory "$INVENTORY" \
--roles "$ROLES"