Files
miracles_in_motion/scripts/setup-cloudflare.sh

241 lines
9.0 KiB
Bash

#!/bin/bash
# Cloudflare Setup Script for Miracles In Motion
# This script helps configure Cloudflare for the production deployment
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
DOMAIN="miraclesinmotion.org"
STATIC_WEB_APP_NAME="${STATIC_WEB_APP_NAME:-mim-prod-web}"
AZURE_RESOURCE_GROUP="${AZURE_RESOURCE_GROUP:-rg-miraclesinmotion-prod}"
echo -e "${GREEN}🌐 Cloudflare Setup Script${NC}"
echo "=================================="
echo ""
# Check if Cloudflare CLI is installed
if ! command -v cloudflared &> /dev/null; then
echo -e "${YELLOW}⚠️ Cloudflare CLI (cloudflared) not found.${NC}"
echo "Install it from: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/"
echo ""
fi
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo -e "${YELLOW}⚠️ jq not found. Installing...${NC}"
# Try to install jq (this may vary by OS)
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo apt-get update && sudo apt-get install -y jq
elif [[ "$OSTYPE" == "darwin"* ]]; then
brew install jq
fi
fi
# Get Azure Static Web App default hostname
echo -e "${GREEN}📋 Getting Azure Static Web App information...${NC}"
AZURE_STATIC_WEB_APP_URL=$(az staticwebapp show \
--name "$STATIC_WEB_APP_NAME" \
--resource-group "$AZURE_RESOURCE_GROUP" \
--query "defaultHostname" -o tsv 2>/dev/null || echo "")
if [ -z "$AZURE_STATIC_WEB_APP_URL" ]; then
echo -e "${RED}❌ Could not find Static Web App. Please check the name and resource group.${NC}"
echo "Usage: STATIC_WEB_APP_NAME=your-app-name AZURE_RESOURCE_GROUP=your-rg ./setup-cloudflare.sh"
exit 1
fi
echo -e "${GREEN}✅ Found Static Web App: ${AZURE_STATIC_WEB_APP_URL}${NC}"
echo ""
# Prompt for Cloudflare API credentials
echo -e "${YELLOW}📝 Cloudflare API Configuration${NC}"
echo "You need a Cloudflare API token with the following permissions:"
echo " - Zone:Read, DNS:Edit, SSL:Edit, Page Rules:Edit"
echo ""
read -p "Enter your Cloudflare API Token: " CF_API_TOKEN
read -p "Enter your Cloudflare Zone ID (or we'll look it up): " CF_ZONE_ID
if [ -z "$CF_ZONE_ID" ]; then
echo "Looking up Zone ID for $DOMAIN..."
CF_ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
if [ -z "$CF_ZONE_ID" ] || [ "$CF_ZONE_ID" == "null" ]; then
echo -e "${RED}❌ Could not find Zone ID for $DOMAIN${NC}"
exit 1
fi
fi
echo -e "${GREEN}✅ Zone ID: $CF_ZONE_ID${NC}"
echo ""
# Function to create DNS record
create_dns_record() {
local record_type=$1
local record_name=$2
local record_content=$3
local proxy=$4
echo "Creating DNS record: $record_name.$DOMAIN -> $record_content"
local data=$(jq -n \
--arg type "$record_type" \
--arg name "$record_name" \
--arg content "$record_content" \
--argjson proxied "$proxy" \
'{
type: $type,
name: $name,
content: $content,
proxied: $proxied,
ttl: 1
}')
local response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "$data")
local success=$(echo "$response" | jq -r '.success')
if [ "$success" == "true" ]; then
echo -e "${GREEN}✅ DNS record created successfully${NC}"
else
local errors=$(echo "$response" | jq -r '.errors[]?.message' | tr '\n' ' ')
echo -e "${YELLOW}⚠️ DNS record may already exist or error: $errors${NC}"
fi
}
# Create CNAME records
echo -e "${GREEN}📝 Creating DNS Records...${NC}"
create_dns_record "CNAME" "www" "$AZURE_STATIC_WEB_APP_URL" "true"
create_dns_record "CNAME" "@" "$AZURE_STATIC_WEB_APP_URL" "true"
echo ""
# Configure SSL/TLS settings
echo -e "${GREEN}🔒 Configuring SSL/TLS...${NC}"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/ssl" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"full"}' | jq -r '.success' && echo -e "${GREEN}✅ SSL mode set to Full${NC}" || echo -e "${YELLOW}⚠️ Could not update SSL settings${NC}"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/always_use_https" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}' | jq -r '.success' && echo -e "${GREEN}✅ Always Use HTTPS enabled${NC}" || echo -e "${YELLOW}⚠️ Could not enable Always Use HTTPS${NC}"
echo ""
# Create Page Rules
echo -e "${GREEN}📋 Creating Page Rules...${NC}"
# Rule 1: Force HTTPS
create_page_rule() {
local url=$1
local settings=$2
local rule_name=$3
local data=$(jq -n \
--arg url "$url" \
--argjson settings "$settings" \
'{
targets: [
{
target: "url",
constraint: {
operator: "matches",
value: $url
}
}
],
actions: $settings,
priority: 1,
status: "active"
}')
local response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/pagerules" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "$data")
local success=$(echo "$response" | jq -r '.success')
if [ "$success" == "true" ]; then
echo -e "${GREEN}✅ Page rule '$rule_name' created${NC}"
else
echo -e "${YELLOW}⚠️ Could not create page rule '$rule_name'${NC}"
fi
}
# Create page rules
HTTPS_SETTINGS='[{"id": "always_use_https"}]'
create_page_rule "*${DOMAIN}/*" "$HTTPS_SETTINGS" "Force HTTPS"
echo ""
# Configure Security Settings
echo -e "${GREEN}🛡️ Configuring Security Settings...${NC}"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/security_level" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"medium"}' | jq -r '.success' && echo -e "${GREEN}✅ Security level set to Medium${NC}" || echo -e "${YELLOW}⚠️ Could not update security level${NC}"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/browser_check" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}' | jq -r '.success' && echo -e "${GREEN}✅ Browser Integrity Check enabled${NC}" || echo -e "${YELLOW}⚠️ Could not enable browser check${NC}"
echo ""
# Configure Speed Settings
echo -e "${GREEN}⚡ Configuring Speed Settings...${NC}"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/minify" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":{"css":"on","html":"on","js":"on"}}' | jq -r '.success' && echo -e "${GREEN}✅ Minification enabled${NC}" || echo -e "${YELLOW}⚠️ Could not enable minification${NC}"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/brotli" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}' | jq -r '.success' && echo -e "${GREEN}✅ Brotli compression enabled${NC}" || echo -e "${YELLOW}⚠️ Could not enable Brotli${NC}"
echo ""
# Add custom domain to Azure Static Web App
echo -e "${GREEN}🔗 Adding Custom Domain to Azure Static Web App...${NC}"
az staticwebapp hostname set \
--name "$STATIC_WEB_APP_NAME" \
--resource-group "$AZURE_RESOURCE_GROUP" \
--hostname "$DOMAIN" 2>/dev/null && echo -e "${GREEN}✅ Custom domain $DOMAIN added${NC}" || echo -e "${YELLOW}⚠️ Domain may already be added or DNS not ready${NC}"
az staticwebapp hostname set \
--name "$STATIC_WEB_APP_NAME" \
--resource-group "$AZURE_RESOURCE_GROUP" \
--hostname "www.$DOMAIN" 2>/dev/null && echo -e "${GREEN}✅ Custom domain www.$DOMAIN added${NC}" || echo -e "${YELLOW}⚠️ Domain may already be added or DNS not ready${NC}"
echo ""
# Summary
echo -e "${GREEN}✅ Cloudflare Setup Complete!${NC}"
echo "=================================="
echo ""
echo "Next Steps:"
echo "1. Verify DNS propagation (may take 24-48 hours)"
echo "2. Verify SSL certificates are provisioned"
echo "3. Test the website at https://$DOMAIN"
echo "4. Monitor Cloudflare analytics"
echo ""
echo "DNS Records Created:"
echo " - www.$DOMAIN -> $AZURE_STATIC_WEB_APP_URL"
echo " - $DOMAIN -> $AZURE_STATIC_WEB_APP_URL"
echo ""
echo "Cloudflare Settings:"
echo " - SSL Mode: Full (strict)"
echo " - Always Use HTTPS: Enabled"
echo " - Security Level: Medium"
echo " - Minification: Enabled"
echo " - Brotli Compression: Enabled"
echo ""