Files
railiance-infra/docs/provisioning.md

3.2 KiB
Raw Blame History

🚀 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:

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)

# 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:

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:

# plan and apply in separate steps
make tf-plan
make tf-apply

or the end-to-end convenience:

make apply    # terraform apply + ansible bootstrap

If you used the one-shot script:

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:

ssh admin@<server-ip>

Run Ansible base bootstrap (if not using make apply):

make ansible-bootstrap

6) Destroy (tear down)

To remove all servers managed by this repo:

make tf-destroy

To remove just one server, delete its entry from inventory/servers.yaml, commit, then:

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 ~3060s after creation for first-boot tasks before first SSH.
  • Labels & role: labels are freeform tags; role can drive Ansible plays as you grow.