From 389c20478f5cab10dae7f932178f3d9fcd9069a6 Mon Sep 17 00:00:00 2001 From: Bernd Worsch Date: Sun, 14 Sep 2025 00:57:26 +0200 Subject: [PATCH] docs: add documentation for provisioning a server --- README.md | 13 +++++ docs/provisioning.md | 117 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 docs/provisioning.md diff --git a/README.md b/README.md index 26b04c2..8d9ea96 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,19 @@ Learn how to add your SSH key and test connectivity after provisioning: ➡️ [SSH Access & Connectivity Test](docs/ssh-access.md) +TL;DR + - put your public key into keys/admin_ssh.pub + +## 🚀 Provisioning + +How to declare hosts and bring them up on Hetzner: + +➡️ [Provisioning Servers](docs/provisioning.md) + +TL;DR + - Define servers in inventory/servers.yaml (name, region, type, image, ssh_user, labels/role). + - Provision with make tf-apply (or make apply to also run Ansible). + - One-shot helper: scripts/hcloud_new_server.sh --type ... --region .... xxx diff --git a/docs/provisioning.md b/docs/provisioning.md new file mode 100644 index 0000000..7a89a3c --- /dev/null +++ b/docs/provisioning.md @@ -0,0 +1,117 @@ +# 🚀 Provisioning Servers with RailianceHosts + +This guide explains **where you declare servers**, **how Terraform uses that declaration**, and **how to provision** (and later destroy) machines on Hetzner. + +--- + +## 1) Where you define servers + +All desired hosts live in **`inventory/servers.yaml`**. Each entry is a simple YAML object with the required attributes: + +```yaml +servers: + - name: core-01 + labels: [core, wireguard, git] + role: "core" + region: "nbg1" # Hetzner location (e.g., nbg1, fsn1, hel1) + type: "cpx21" # Hetzner server type/flavor + image: "ubuntu-24.04" # OS image slug + ssh_user: "admin" # bootstrap user (cloud-init creates this) +``` + +> Tip: Keep **names stable**. Renaming a server in this file makes Terraform think the old one was destroyed and a new one should be created. + +--- + +## 2) Two ways to add a server + +### A) Edit YAML by hand (simple) +Open `inventory/servers.yaml`, add a new entry, save, commit. + +### B) Use the helper script (safe & quick) +```bash +# requires scripts/new_host.py +make new-host NAME=web-01 TYPE=cpx21 REGION=nbg1 ROLE=web +# or directly: +python3 scripts/new_host.py --name web-01 --type cpx21 --region nbg1 --role web +``` + +You can also do **add + provision in one step**: +```bash +scripts/hcloud_new_server.sh web-01 --type cpx21 --region nbg1 --role web +``` + +--- + +## 3) How Terraform uses your declaration + +The module at `terraform/hetzner/`: +- Reads `inventory/servers.yaml` (`for_each` over `servers`) +- Registers your SSH key from `keys/admin_ssh.pub` +- Injects **cloud-init** that sets up the `admin` user and basic hardening +- Creates/updates/destroys servers to match the YAML + +Outputs include a map of server names → IPv4 addresses. + +--- + +## 4) Provision (create/update) + +Make sure your Hetzner API token is present and **SOPS-decryptable** in `inventory/group_vars/secrets.sops.yaml` under `ops.hcloud_token`. + +Then run either: +```bash +# plan and apply in separate steps +make tf-plan +make tf-apply +``` +or the end-to-end convenience: +```bash +make apply # terraform apply + ansible bootstrap +``` + +If you used the one-shot script: +```bash +scripts/hcloud_new_server.sh web-01 --type cpx21 --region nbg1 --role web +``` + +Terraform will print the new servers’ IPv4 addresses at the end. + +--- + +## 5) Connect & converge + +Connect via SSH: +```bash +ssh admin@ +``` + +Run Ansible base bootstrap (if not using `make apply`): +```bash +make ansible-bootstrap +``` + +--- + +## 6) Destroy (tear down) + +To remove all servers managed by this repo: +```bash +make tf-destroy +``` + +To remove just one server, delete its entry from `inventory/servers.yaml`, commit, then: +```bash +make tf-apply +``` +Terraform will destroy the missing server and leave others intact. + +--- + +## 7) Notes & conventions + +- **Idempotent:** You can run `make apply` repeatedly; Terraform converges infra, Ansible converges config. +- **SSH keys:** Ensure `keys/admin_ssh.pub` exists before provisioning. +- **Secret token:** The Hetzner API token must be in `inventory/group_vars/secrets.sops.yaml` (encrypted with SOPS). +- **Cloud-init delay:** Allow ~30–60s after creation for first-boot tasks before first SSH. +- **Labels & role:** `labels` are freeform tags; `role` can drive Ansible plays as you grow.