slides(tappaas): session details, dev-topology slide, identity login
Date 24 August; the demo environment is lab1 (zone lab1, lab1.makerfloss.eu outside / lab1.internal inside). Adds the upstream 'developing TAPPaaS modules' topology from tappaas.org ahead of our own repo picture, which now carries forgejo.makerfloss.eu and highlights that this site tracks main, not stable. Drops the manager-verbs slide; the demo slides carry the verbs where they are actually used, with network/environment/module status commands. Cockpit now logs in via identity:identity rather than a local PAM password, and identity hand-out uses 'authentik-manager user-recovery-link' so no password is ever read aloud. NOTE: podman.json in Community does not yet declare identity:identity — the module needs that change before the session.
This commit is contained in:
parent
f1c1c79b63
commit
834bd406f2
1 changed files with 80 additions and 53 deletions
|
|
@ -4,7 +4,7 @@ theme: gaia
|
||||||
class: invert
|
class: invert
|
||||||
paginate: true
|
paginate: true
|
||||||
title: How to implement a TAPPaaS module
|
title: How to implement a TAPPaaS module
|
||||||
description: Live build of a Podman module — OrangeMaker session
|
description: Live build of a Podman module — OrangeMaker, 24 August
|
||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -29,7 +29,7 @@ section.diagram h2 { margin-bottom: 0.1em; }
|
||||||
|
|
||||||
Live build of a **Podman** container host
|
Live build of a **Podman** container host
|
||||||
|
|
||||||
OrangeMaker · `TODO: date`
|
OrangeMaker · 24 August
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Slides are the map; the terminal is the territory. Everything here has a live
|
Slides are the map; the terminal is the territory. Everything here has a live
|
||||||
|
|
@ -40,9 +40,9 @@ counterpart — keep the deck moving and spend the time in the shell.
|
||||||
|
|
||||||
## The plan
|
## The plan
|
||||||
|
|
||||||
1. **What TAPPaaS is** — two diagrams, ten minutes, no deeper
|
1. **What TAPPaaS is** — a few diagrams, ten minutes, no deeper
|
||||||
2. **What a module actually is** — a json contract and three scripts
|
2. **What a module actually is** — a json contract and three scripts
|
||||||
3. **Build one live** — a test environment, then `podman` into it
|
3. **Build one live** — the `lab1` environment, then `podman` into it
|
||||||
4. **Prove it works** — tests, then the web console
|
4. **Prove it works** — tests, then the web console
|
||||||
5. **You get a login** — your own identity on this system
|
5. **You get a login** — your own identity on this system
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ flowchart LR
|
||||||
nc["nextcloud"]
|
nc["nextcloud"]
|
||||||
ha["home-assistant"]
|
ha["home-assistant"]
|
||||||
end
|
end
|
||||||
subgraph z2["test · zone hacklab"]
|
subgraph z2["lab1 · zone lab1"]
|
||||||
pod["podman — today"]
|
pod["podman — today"]
|
||||||
end
|
end
|
||||||
sat --> net
|
sat --> net
|
||||||
|
|
@ -83,7 +83,7 @@ flowchart LR
|
||||||
| Word | Meaning |
|
| Word | Meaning |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| **Module** | The smallest deployable unit — its own VM, its own json contract. Foundation *and* apps are modules. |
|
| **Module** | The smallest deployable unit — its own VM, its own json contract. Foundation *and* apps are modules. |
|
||||||
| **Environment** | A tenant. `mgmt` and one named after the site always exist; add more freely. |
|
| **Environment** | A tenant. `mgmt` and one named after the site always exist; add more freely. Today we add `lab1`. |
|
||||||
| **Zone** | A VLAN with a firewall policy. Modules land in their environment's zone. |
|
| **Zone** | A VLAN with a firewall policy. Modules land in their environment's zone. |
|
||||||
| **Mothership** | `tappaas-cicd` — where the managers run and where you type. |
|
| **Mothership** | `tappaas-cicd` — where the managers run and where you type. |
|
||||||
| **Satellite** | Optional VPS, for sites with no usable public IP. |
|
| **Satellite** | Optional VPS, for sites with no usable public IP. |
|
||||||
|
|
@ -94,40 +94,62 @@ Everything is a module. There is one model to learn, not eight.
|
||||||
|
|
||||||
<!-- _class: invert diagram -->
|
<!-- _class: invert diagram -->
|
||||||
|
|
||||||
## How code gets in: pull-based GitOps
|
## Developing modules: dev instance, private branch
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart RL
|
flowchart RL
|
||||||
subgraph t["TAPPaaS repository"]
|
subgraph Development["Development repository"]
|
||||||
stable["stable"]
|
dev_main["main"]
|
||||||
main["main"]
|
|
||||||
end
|
end
|
||||||
subgraph c["Community repository"]
|
subgraph Upstream["Upstream repository"]
|
||||||
cm["main"]
|
up_main["main"]
|
||||||
|
up_stable["stable"]
|
||||||
|
up_main -->|merge| up_stable
|
||||||
end
|
end
|
||||||
subgraph inst["Your TAPPaaS · tappaas-cicd"]
|
subgraph InstanceDev["TAPPaaS instance · dev"]
|
||||||
lt["clone of TAPPaaS"]
|
localDev["clone of Upstream"]
|
||||||
lc["clone of Community"]
|
localDev_dev["clone of Development"]
|
||||||
end
|
end
|
||||||
lt -->|pull| stable
|
subgraph InstanceProd["TAPPaaS instance · prod"]
|
||||||
lc -->|pull| cm
|
localProd["clone of Upstream"]
|
||||||
|
end
|
||||||
|
localProd -->|pull| up_stable
|
||||||
|
localDev -->|pull| up_main
|
||||||
|
localDev_dev -->|push| dev_main
|
||||||
|
dev_main -->|PR| up_main
|
||||||
```
|
```
|
||||||
|
|
||||||
Nothing pushes into your site. It pulls, on a schedule, and reconciles.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Managers: the verbs you will watch me type
|
<!-- _class: invert diagram -->
|
||||||
|
|
||||||
```bash
|
## Our setup tonight
|
||||||
module-manager module add|test|reconcile|modify|delete
|
|
||||||
environment-manager add|modify|reconcile
|
```mermaid
|
||||||
network-manager zone add|merge|reconcile
|
flowchart RL
|
||||||
people-manager user add|modify · reconcile --apply
|
subgraph t["TAPPaaS · codeberg"]
|
||||||
|
stable["stable"]
|
||||||
|
main["main"]
|
||||||
|
end
|
||||||
|
subgraph c["Community · codeberg"]
|
||||||
|
cm["main"]
|
||||||
|
end
|
||||||
|
subgraph f["forgejo.makerfloss.eu"]
|
||||||
|
fm["main"]
|
||||||
|
end
|
||||||
|
subgraph inst["Our TAPPaaS · tappaas-cicd"]
|
||||||
|
lt["clone of TAPPaaS"]
|
||||||
|
lc["clone of Community"]
|
||||||
|
lf["clone of MakerFLOSS"]
|
||||||
|
end
|
||||||
|
lt -->|pull| main
|
||||||
|
lc -->|pull| cm
|
||||||
|
lf -->|pull| fm
|
||||||
|
classDef tracked stroke:#ff8a80,stroke-width:3px
|
||||||
|
class main tracked
|
||||||
```
|
```
|
||||||
|
|
||||||
Admins drive **verbs**, never hand-edited JSON. Each manager owns one slice of
|
We track **`main`**, not `stable` — this is a lab, we want the new things.
|
||||||
desired state; controllers push it into OPNsense, Proxmox, the switch, Authentik.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -153,7 +175,8 @@ That is the whole surface. Everything else is the platform's job.
|
||||||
{
|
{
|
||||||
"description": "Podman container host — Debian 13 VM with rootless Podman + Cockpit",
|
"description": "Podman container host — Debian 13 VM with rootless Podman + Cockpit",
|
||||||
"vmname": "podman", "vmid": 812,
|
"vmname": "podman", "vmid": 812,
|
||||||
"dependsOn": ["cluster:vm", "templates:debian", "backup:vm", "network:proxy"],
|
"dependsOn": ["cluster:vm", "templates:debian", "backup:vm",
|
||||||
|
"network:proxy", "identity:identity"],
|
||||||
"config": {
|
"config": {
|
||||||
"cluster:vm": { "cores": 2, "memory": "2048", "diskSize": "20G",
|
"cluster:vm": { "cores": 2, "memory": "2048", "diskSize": "20G",
|
||||||
"image": "debian-13-generic-amd64.qcow2" },
|
"image": "debian-13-generic-amd64.qcow2" },
|
||||||
|
|
@ -163,7 +186,7 @@ That is the whole surface. Everything else is the platform's job.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`dependsOn` is the whole trick: four services, declared — not scripted.
|
`dependsOn` is the whole trick: five services, declared — not scripted.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -184,30 +207,30 @@ If `test.sh` is honest, unattended updates are safe. That is the entire deal.
|
||||||
- A VM — `cluster:vm` built it from the Debian 13 cloud image
|
- A VM — `cluster:vm` built it from the Debian 13 cloud image
|
||||||
- OS prep — `templates:debian` did apt + guest agent
|
- OS prep — `templates:debian` did apt + guest agent
|
||||||
- A VLAN, an interface, DHCP, firewall rules — the zone came with the environment
|
- A VLAN, an interface, DHCP, firewall rules — the zone came with the environment
|
||||||
- `https://podman.<domain>` with a real certificate — `network:proxy`, one dependency
|
- `https://podman.lab1.makerfloss.eu` with a real certificate — `network:proxy`
|
||||||
- Nightly backup to PBS — `backup:vm`
|
- A login — `identity:identity`, so it is your TAPPaaS account, not a local one
|
||||||
- Scheduled updates and health reporting — the mothership
|
- Nightly backup to PBS, scheduled updates, health reporting
|
||||||
|
|
||||||
Six lines of json bought all of it.
|
A few lines of json bought all of it.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Demo 1 — an environment of our own
|
## Demo 1 — an environment of our own
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# srvTest ships in the zone template; a fresh one keeps the demo self-contained
|
network-manager zone add lab1 --from-zone srv
|
||||||
network-manager zone add hacklab --from-zone srv
|
network-manager show lab1 # vlan tag, subnet, access-to
|
||||||
|
network-manager reconcile # dry-run: drift on all 4 planes
|
||||||
|
network-manager reconcile --apply # converge OPNsense, Proxmox, switch, AP
|
||||||
|
|
||||||
environment-manager add test \
|
environment-manager add lab1 --display "MakerFLOSS lab" \
|
||||||
--display "Hackerspace test" \
|
--zone lab1 --domain lab1.makerfloss.eu
|
||||||
--zone hacklab \
|
environment-manager list
|
||||||
--domain test.<our-domain>
|
environment-manager show lab1
|
||||||
```
|
```
|
||||||
|
|
||||||
A tenant with its own VLAN, its own firewall posture, its own DNS names —
|
A tenant with its own VLAN, firewall posture and DNS names —
|
||||||
and nothing in it can touch production.
|
`lab1.makerfloss.eu` outside, `lab1.internal` inside.
|
||||||
|
|
||||||
`TODO: our domain — and do we build the zone live or pre-bake it?`
|
|
||||||
|
|
||||||
<!-- Show zones.json before/after, and the OPNsense interface appearing. -->
|
<!-- Show zones.json before/after, and the OPNsense interface appearing. -->
|
||||||
|
|
||||||
|
|
@ -216,7 +239,10 @@ and nothing in it can touch production.
|
||||||
## Demo 2 — install the module
|
## Demo 2 — install the module
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
module-manager module add podman --environment test
|
module-manager module add podman --environment lab1
|
||||||
|
|
||||||
|
module-manager module list # what is deployed
|
||||||
|
module-manager module show podman # the resolved config, cascade applied
|
||||||
```
|
```
|
||||||
|
|
||||||
Watch the order: dependencies resolve first, then the VM, then the network, then
|
Watch the order: dependencies resolve first, then the VM, then the network, then
|
||||||
|
|
@ -233,13 +259,11 @@ maintains a list.
|
||||||
module-manager module test podman
|
module-manager module test podman
|
||||||
```
|
```
|
||||||
|
|
||||||
Then open **`https://podman.<domain>`** — Cockpit, with the Podman page.
|
Then open **`https://podman.lab1.makerfloss.eu`** — Cockpit, with the Podman page.
|
||||||
|
|
||||||
- Reachable from the `mgmt` zone only. Not from the internet, by declaration.
|
- Reachable from the `mgmt` zone only. Not from the internet, by declaration.
|
||||||
- Cockpit authenticates against **Linux accounts on the VM** — the cloud-init
|
- You log in with your **TAPPaaS identity** — that is what the `identity:identity`
|
||||||
`tappaas` user has no password until someone sets one.
|
dependency buys; no per-VM Linux passwords to hand out.
|
||||||
|
|
||||||
`TODO: pre-create the demo login, or set the password live?`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -255,7 +279,7 @@ Three homes for a module, all first-class:
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| **TAPPaaS** repo, by pull request | modules the whole project should carry |
|
| **TAPPaaS** repo, by pull request | modules the whole project should carry |
|
||||||
| **Community** repo | yours, shared, no gatekeeping — today's podman |
|
| **Community** repo | yours, shared, no gatekeeping — today's podman |
|
||||||
| **Private** repo | yours, not shared |
|
| **Private** repo — e.g. `forgejo.makerfloss.eu` | yours, not shared |
|
||||||
|
|
||||||
Adding a repository is one `site-manager repository add`.
|
Adding a repository is one `site-manager repository add`.
|
||||||
|
|
||||||
|
|
@ -265,13 +289,16 @@ Adding a repository is one `site-manager repository add`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
people-manager user add <you> --email <you>@example.org \
|
people-manager user add <you> --email <you>@example.org \
|
||||||
--roles user --groups orangemaker__users
|
--roles user --groups <group>
|
||||||
|
|
||||||
people-manager reconcile # preview
|
people-manager reconcile # preview
|
||||||
people-manager reconcile --apply # push to Authentik
|
people-manager reconcile --apply # push to Authentik
|
||||||
|
|
||||||
|
authentik-manager user-recovery-link <you> # one-time URL: set your own password
|
||||||
```
|
```
|
||||||
|
|
||||||
One login per person, roles via groups. `TODO: which groups/roles do participants get?`
|
One login per person, roles via groups. Nobody types a password into a chat window.
|
||||||
|
|
||||||
|
`TODO: which group do participants land in?`
|
||||||
|
|
||||||
<!-- Do these live, one per participant, while the podman VM builds. -->
|
<!-- Do these live, one per participant, while the podman VM builds. -->
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue