# 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`](base.yml) | Hostname (per the schema) + shared MOTD + seed root keys from `globals/` + SSH hardening (`harden-ssh.sh`) + deny-by-default host firewall (`harden-firewall.sh`, `ENABLE_FIREWALL=1`). | | [`jumphost.yml`](jumphost.yml) | Same base, but bastion hardening (`harden-jumphost.sh`) with an `ssh-admins`/`ssh-jumpers` split and a ProxyJump whitelist; same host firewall. | These are for the **host itself**. To stand up a Docker stack on a host, use the per-deployment `cloud-init.yml` under `deployments//` instead (those clone the repo and run the stack's `deploy.sh`). ## Usage 1. Copy the template, fill in `REPO_URL`, `HOST` (`-`, e.g. `sto-1`), and the other values at the top of the `runcmd` block. 2. Paste it as the instance's **user-data** when creating the VM. 3. On first boot the host names itself, installs the MOTD, seeds admin keys from `globals/`, hardens SSH, and brings up the deny-by-default firewall. Hostnames follow [`../globals/Network Domain Name Schema.md`](../globals/Network%20Domain%20Name%20Schema.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` (or `SSH_KEYS_URL`) and ignore it.