doran/scripts/hetzner/destroy.sh

110 lines
3.9 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "$0")/../.." && pwd)
# shellcheck disable=SC1091
source "$ROOT_DIR/scripts/hetzner/lib.sh"
load_bootstrap_env
TF_DIR="$ROOT_DIR/infra/terraform/hetzner"
STATE_DIR="$ROOT_DIR/.state/hetzner"
GENERATED_OVERLAY_DIR="$ROOT_DIR/deploy/k8s/overlays/hetzner-single-node/generated"
DESTROY_DNS="${DESTROY_DNS:-false}"
DESTROY_LOCAL_STATE="${DESTROY_LOCAL_STATE:-false}"
DESTROY_FORGEJO_REPO="${DESTROY_FORGEJO_REPO:-false}"
require terraform
require curl
resolve_secret_var HCLOUD_TOKEN required
resolve_secret_var TAILSCALE_AUTH_KEY optional
resolve_secret_var CLOUDFLARE_API_TOKEN optional
resolve_secret_var CLOUDFLARE_ZONE_ID optional
resolve_secret_var PORKBUN_API_KEY optional
resolve_secret_var PORKBUN_SECRET_API_KEY optional
resolve_secret_var FORGEJO_ADMIN_PASSWORD optional
: "${SSH_PUBLIC_KEY_PATH:?set SSH_PUBLIC_KEY_PATH}"
: "${PUBLIC_DOMAIN:=bootstrap.example.com}"
: "${BASE_DOMAIN:?set BASE_DOMAIN}"
: "${TAILSCALE_CONTROL_PLANE_HOSTNAME:=}"
: "${TF_ADMIN_CIDR_BLOCKS:=}"
: "${FORGEJO_DOMAIN:=}"
: "${FORGEJO_REPO_OWNER:=${FORGEJO_ADMIN_USERNAME:-}}"
: "${FORGEJO_REPO_NAME:=unrip}"
SSH_PUBLIC_KEY=$(cat "$SSH_PUBLIC_KEY_PATH")
TF_VARS=(
-var "hcloud_token=$HCLOUD_TOKEN"
-var "ssh_public_key=$SSH_PUBLIC_KEY"
-var "public_domain=$PUBLIC_DOMAIN"
-var "tailscale_auth_key=${TAILSCALE_AUTH_KEY:-}"
-var "tailscale_control_plane_hostname=$TAILSCALE_CONTROL_PLANE_HOSTNAME"
)
if [[ -n "$TF_ADMIN_CIDR_BLOCKS" && "$TF_ADMIN_CIDR_BLOCKS" != '[]' ]]; then
TF_VARS+=( -var "admin_cidr_blocks=$TF_ADMIN_CIDR_BLOCKS" )
fi
terraform -chdir="$TF_DIR" init
terraform -chdir="$TF_DIR" destroy -auto-approve "${TF_VARS[@]}"
cleanup_dns() {
if [[ "$DESTROY_DNS" != "true" ]]; then
echo "skipping DNS cleanup (set DESTROY_DNS=true to remove bootstrap-managed records)"
return 0
fi
if [[ -n "${CLOUDFLARE_API_TOKEN:-}" && -n "${CLOUDFLARE_ZONE_ID:-}" ]]; then
DNS_MODE=delete BASE_DOMAIN="$BASE_DOMAIN" bash "$ROOT_DIR/scripts/hetzner/configure-cloudflare-dns.sh"
elif [[ -n "${PORKBUN_API_KEY:-}" && -n "${PORKBUN_SECRET_API_KEY:-}" ]]; then
DNS_MODE=delete BASE_DOMAIN="$BASE_DOMAIN" bash "$ROOT_DIR/scripts/hetzner/configure-porkbun-dns.sh"
else
echo "skipping DNS cleanup (no supported DNS provider credentials available)"
fi
}
cleanup_local_state() {
if [[ "$DESTROY_LOCAL_STATE" != "true" ]]; then
echo "skipping local artifact cleanup (set DESTROY_LOCAL_STATE=true to remove generated bootstrap outputs)"
return 0
fi
rm -rf "$STATE_DIR" "$GENERATED_OVERLAY_DIR"
rm -f "$TF_DIR/terraform.tfstate" "$TF_DIR/terraform.tfstate.backup"
rm -rf "$TF_DIR/.terraform"
echo "removed local bootstrap artifacts from .state/hetzner, generated overlay outputs, and Terraform working state"
}
cleanup_forgejo_repo() {
if [[ "$DESTROY_FORGEJO_REPO" != "true" ]]; then
echo "skipping Forgejo repo cleanup (set DESTROY_FORGEJO_REPO=true to delete the bootstrap-managed repo)"
return 0
fi
if [[ -z "$FORGEJO_DOMAIN" || -z "${FORGEJO_ADMIN_USERNAME:-}" || -z "${FORGEJO_ADMIN_PASSWORD:-}" || -z "$FORGEJO_REPO_OWNER" || -z "$FORGEJO_REPO_NAME" ]]; then
echo "skipping Forgejo repo cleanup (set FORGEJO_DOMAIN, FORGEJO_ADMIN_USERNAME, FORGEJO_ADMIN_PASSWORD, FORGEJO_REPO_OWNER, and FORGEJO_REPO_NAME)"
return 0
fi
local base_url="https://${FORGEJO_DOMAIN}"
local status
status=$(curl -ksS -o /dev/null -w '%{http_code}' -u "$FORGEJO_ADMIN_USERNAME:$FORGEJO_ADMIN_PASSWORD" \
-X DELETE "$base_url/api/v1/repos/$FORGEJO_REPO_OWNER/$FORGEJO_REPO_NAME")
case "$status" in
204)
echo "deleted Forgejo repo $FORGEJO_REPO_OWNER/$FORGEJO_REPO_NAME"
;;
404)
echo "skipped missing Forgejo repo $FORGEJO_REPO_OWNER/$FORGEJO_REPO_NAME"
;;
*)
echo "warning: Forgejo repo cleanup returned HTTP $status for $FORGEJO_REPO_OWNER/$FORGEJO_REPO_NAME" >&2
;;
esac
}
cleanup_dns
cleanup_local_state
cleanup_forgejo_repo