Restructure around a single entry point (automations.sh) with a Gum wizard and a self-extracting bundle for repo-less installs. Add scripts/oslib.sh so the provisioning scripts (setup-host, harden-ssh, harden-jumphost, sshuser) run on Alpine/Debian/Alma; seed root keys from globals/. - ntfy SSH-login alerts (user, source IP, key, region, jump target) via pam_exec - daily auto-updates with AUTO_REBOOT=idle (reboots only when no SSH active) and opt-in Alpine stable-branch upgrades - generic + per-deployment cloud-init; Gitea release workflow on tag - README/LICENSE/.gitignore/.gitattributes (force LF); repo URLs -> Gitea
cloud-init/
Generic, distro-agnostic cloud-init templates for standing up a base host
or a bastion from scratch. They run on Alpine, Debian, or Alma — the
runcmd prelude detects the package manager and installs bash/git/curl
before invoking the scripts.
| Template | What it does |
|---|---|
base.yml |
Hostname (per the schema) + shared MOTD + seed root keys from globals/ + SSH hardening (harden-ssh.sh). |
jumphost.yml |
Same base, but bastion hardening (harden-jumphost.sh) with an ssh-admins/ssh-jumpers split and a ProxyJump whitelist. |
These are for the host itself. To stand up a Docker stack on a host,
use the per-deployment cloud-init.yml under deployments/<name>/ instead
(those clone the repo and run the stack's deploy.sh).
Usage
- Copy the template, fill in
REPO_URL,HOST(<svc>-<n>, e.g.sto-1), and the other values at the top of theruncmdblock. - Paste it as the instance's user-data when creating the VM.
- On first boot the host names itself, installs the MOTD, seeds admin keys
from
globals/, and hardens SSH.
Hostnames follow ../globals/Network Domain Name Schema.md;
our VMs skip the region code and use srvno.de as the base.
The harden scripts print a generated root private key to stdout, which lands in the cloud provider's serial/console log. Capture it there, or rely on the keys seeded from
globals/authorized_keys(orSSH_KEYS_URL) and ignore it.