#!/usr/bin/env bash # hcloud_new_server.sh — Add a host to inventory and provision it on Hetzner # Usage: # scripts/hcloud_new_server.sh [--type cpx11] [--region nbg1] [--role web] [--image ubuntu-24.04] [--user admin] # # Prereqs: # - age + SOPS installed, with access to decrypt your Hetzner token # - terraform installed # - Python3 + PyYAML (for scripts/new_host.py) # set -euo pipefail fail() { echo "❌ $*" >&2; exit 1; } ok() { echo "✔ $*"; } info() { echo "ℹ $*"; } # --- Parse args --- NAME="${1:-}" shift || true TYPE="cpx21" REGION="nbg1" ROLE="generic" IMAGE="ubuntu-24.04" USER="admin" while [[ $# -gt 0 ]]; do case "$1" in --type) TYPE="$2"; shift 2;; --region) REGION="$2"; shift 2;; --role) ROLE="$2"; shift 2;; --image) IMAGE="$2"; shift 2;; --user) USER="$2"; shift 2;; *) fail "Unknown arg: $1 (usage: scripts/hcloud_new_server.sh [--type cpx11] [--region nbg1] [--role web] [--image ubuntu-24.04] [--user admin])";; esac done [[ -n "$NAME" ]] || fail "Missing NAME. Usage: scripts/hcloud_new_server.sh [--type ...] ..." # --- Sanity checks --- command -v terraform >/dev/null || fail "terraform not found" command -v sops >/dev/null || fail "sops not found" command -v python3 >/dev/null || fail "python3 not found" python3 -c "import yaml" 2>/dev/null || fail "PyYAML not installed for python3 (pip install pyyaml)" if [[ ! -f "scripts/new_host.py" ]]; then fail "scripts/new_host.py not found (expected in repo)." fi if [[ ! -f "keys/admin_ssh.pub" ]]; then info "keys/admin_ssh.pub missing. Hetzner will still inject your project key if configured, but you may want to add one." fi # --- Add host to inventory --- python3 scripts/new_host.py \ --name "$NAME" \ --type "$TYPE" \ --region "$REGION" \ --role "$ROLE" \ --image "$IMAGE" \ --user "$USER" ok "Inventory updated: $NAME → inventory/servers.yaml" # --- Decrypt Hetzner token and apply Terraform --- HCLOUD_TOKEN="$(sops -d --extract '["hetzner"]["token"]' secrets/hetzner-token.sops.yaml 2>/dev/null)" [[ -n "$HCLOUD_TOKEN" ]] || fail "Could not decrypt ops.hcloud_token from secrets/hetzner-token.sops.yaml. Ensure SOPS_AGE_KEY or keys.txt is set and token exists." pushd terraform/hetzner >/dev/null terraform init -upgrade export HCLOUD_TOKEN terraform apply -auto-approve # Try to show IP of the created host if command -v jq >/dev/null; then IP="$(terraform output -json servers | jq -r --arg n "$NAME" '.[$n] // empty')" if [[ -n "$IP" && "$IP" != "null" ]]; then ok "Server $NAME IPv4: $IP" echo "" echo "SSH quick check (if admin key injected):" echo " ssh admin@$IP" else info "Could not extract IP for $NAME (jq path empty). Full outputs:" terraform output fi else info "jq not found. Terraform outputs:" terraform output fi popd >/dev/null ok "Provisioning complete."