Files
Sankofa/scripts/configure-cloudflare.sh

195 lines
6.0 KiB
Bash
Raw Normal View History

#!/bin/bash
set -euo pipefail
# Cloudflare Tunnel Configuration Script
# Load environment variables from .env if it exists
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "${SCRIPT_DIR}/../.env" ]; then
set -a
source <(grep -v '^#' "${SCRIPT_DIR}/../.env" | grep -v '^$' | sed 's/^/export /')
set +a
fi
CLOUDFLARE_API_TOKEN="${CLOUDFLARE_API_TOKEN:-}"
CLOUDFLARE_API_KEY="${CLOUDFLARE_API_KEY:-}"
CLOUDFLARE_EMAIL="${CLOUDFLARE_EMAIL:-}"
ZONE_ID="${CLOUDFLARE_ZONE_ID:-${ZONE_ID:-}}"
ACCOUNT_ID="${CLOUDFLARE_ACCOUNT_ID:-${ACCOUNT_ID:-}}"
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2
}
error() {
log "ERROR: $*"
exit 1
}
check_prerequisites() {
# Check authentication method
if [ -z "${CLOUDFLARE_API_TOKEN}" ] && [ -z "${CLOUDFLARE_API_KEY}" ]; then
error "Either CLOUDFLARE_API_TOKEN or CLOUDFLARE_API_KEY must be set"
fi
if [ -z "${CLOUDFLARE_API_TOKEN}" ] && [ -z "${CLOUDFLARE_EMAIL}" ]; then
error "If using CLOUDFLARE_API_KEY, CLOUDFLARE_EMAIL must also be set"
fi
if [ -z "${ACCOUNT_ID}" ]; then
warn "ACCOUNT_ID not set, attempting to get from API..."
get_account_id
fi
if ! command -v cloudflared &> /dev/null; then
error "cloudflared is not installed. Install it first."
fi
}
get_account_id() {
if [ -n "${CLOUDFLARE_API_TOKEN}" ]; then
ACCOUNT_ID=$(curl -s -X GET \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/accounts" | \
jq -r '.result[0].id')
elif [ -n "${CLOUDFLARE_API_KEY}" ] && [ -n "${CLOUDFLARE_EMAIL}" ]; then
ACCOUNT_ID=$(curl -s -X GET \
-H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \
-H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/accounts" | \
jq -r '.result[0].id')
fi
if [ -n "${ACCOUNT_ID}" ] && [ "${ACCOUNT_ID}" != "null" ]; then
log "Account ID: ${ACCOUNT_ID}"
export CLOUDFLARE_ACCOUNT_ID="${ACCOUNT_ID}"
else
error "Failed to get Account ID"
fi
}
create_tunnel() {
local tunnel_name=$1
log "Creating Cloudflare tunnel: ${tunnel_name}"
# Create tunnel via API
local auth_header
if [ -n "${CLOUDFLARE_API_TOKEN}" ]; then
TUNNEL_ID=$(curl -s -X POST \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cfd_tunnel" \
-d "{\"name\":\"${tunnel_name}\",\"config_src\":\"local\"}" \
| jq -r '.result.id')
else
TUNNEL_ID=$(curl -s -X POST \
-H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \
-H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cfd_tunnel" \
-d "{\"name\":\"${tunnel_name}\",\"config_src\":\"local\"}" \
| jq -r '.result.id')
fi
if [ -z "${TUNNEL_ID}" ] || [ "${TUNNEL_ID}" = "null" ]; then
error "Failed to create tunnel ${tunnel_name}"
fi
log "Tunnel created with ID: ${TUNNEL_ID}"
echo "${TUNNEL_ID}"
}
get_tunnel_token() {
local tunnel_id=$1
log "Getting tunnel token for ${tunnel_id}..."
TOKEN=$(curl -s -X GET \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cfd_tunnel/${tunnel_id}/token" \
| jq -r '.result.token')
if [ -z "${TOKEN}" ] || [ "${TOKEN}" = "null" ]; then
error "Failed to get tunnel token"
fi
echo "${TOKEN}"
}
configure_dns() {
local hostname=$1
local tunnel_id=$2
log "Configuring DNS for ${hostname}..."
# Create CNAME record
curl -s -X POST \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-d "{
\"type\": \"CNAME\",
\"name\": \"${hostname}\",
\"content\": \"${tunnel_id}.cfargotunnel.com\",
\"ttl\": 1,
\"proxied\": true
}" > /dev/null
log "DNS record created for ${hostname}"
}
setup_control_plane_tunnel() {
log "Setting up control plane tunnel..."
TUNNEL_ID=$(create_tunnel "control-plane-tunnel")
TUNNEL_TOKEN=$(get_tunnel_token "${TUNNEL_ID}")
log "Control plane tunnel token: ${TUNNEL_TOKEN}"
log "Save this token securely and use it when running cloudflared on control plane nodes"
# Configure DNS for control plane services
configure_dns "portal" "${TUNNEL_ID}"
configure_dns "rancher" "${TUNNEL_ID}"
configure_dns "argocd" "${TUNNEL_ID}"
configure_dns "grafana" "${TUNNEL_ID}"
configure_dns "vault" "${TUNNEL_ID}"
configure_dns "keycloak" "${TUNNEL_ID}"
}
setup_proxmox_tunnels() {
local sites=("site-1" "site-2" "site-3")
for site in "${sites[@]}"; do
log "Setting up tunnel for ${site}..."
TUNNEL_ID=$(create_tunnel "proxmox-${site}-tunnel")
TUNNEL_TOKEN=$(get_tunnel_token "${TUNNEL_ID}")
log "${site} tunnel token: ${TUNNEL_TOKEN}"
log "Save this token and use it when running setup-proxmox-agents.sh on ${site} nodes"
done
}
main() {
log "Starting Cloudflare tunnel configuration..."
check_prerequisites
setup_control_plane_tunnel
setup_proxmox_tunnels
log ""
log "Cloudflare tunnel configuration completed!"
log ""
log "Next steps:"
log "1. Save all tunnel tokens securely"
log "2. Use tokens when running cloudflared on respective nodes"
log "3. Verify DNS records are created correctly"
log "4. Test tunnel connectivity"
}
main "$@"