299 lines
10 KiB
Bash
299 lines
10 KiB
Bash
#!/bin/bash
|
|
# Automated Cloudflare Setup Script
|
|
# Reads credentials from .env.production and configures Cloudflare automatically
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
DOMAIN="mim4u.org"
|
|
STATIC_WEB_APP_NAME="mim-prod-igiay4-web"
|
|
AZURE_RESOURCE_GROUP="rg-miraclesinmotion-prod"
|
|
|
|
echo -e "${GREEN}🌐 Automated Cloudflare Setup${NC}"
|
|
echo "=================================="
|
|
echo ""
|
|
|
|
# Load environment variables from .env files
|
|
ENV_FILES=(".env.production" ".env" "../.env.production" "../.env")
|
|
CREDENTIALS_LOADED=false
|
|
|
|
for env_file in "${ENV_FILES[@]}"; do
|
|
if [ -f "$env_file" ]; then
|
|
echo -e "${GREEN}📋 Loading credentials from $env_file...${NC}"
|
|
# Try different formats
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^CLOUDFLARE_API_TOKEN= ]] || [[ "$line" =~ ^CLOUDFLARE_ZONE_ID= ]]; then
|
|
export "$line"
|
|
CREDENTIALS_LOADED=true
|
|
fi
|
|
done < "$env_file"
|
|
|
|
# Also try with export command
|
|
set -a
|
|
source "$env_file" 2>/dev/null || true
|
|
set +a
|
|
fi
|
|
done
|
|
|
|
# Check if credentials are already set in environment
|
|
if [ -n "$CLOUDFLARE_API_TOKEN" ] && [ -n "$CLOUDFLARE_ZONE_ID" ]; then
|
|
CREDENTIALS_LOADED=true
|
|
fi
|
|
|
|
# Check if credentials are set
|
|
if [ -z "$CLOUDFLARE_API_TOKEN" ] || [ -z "$CLOUDFLARE_ZONE_ID" ]; then
|
|
echo -e "${YELLOW}⚠️ Cloudflare credentials not found in env files${NC}"
|
|
echo "Checking environment variables..."
|
|
|
|
# Final check - maybe they're already exported
|
|
if [ -z "$CLOUDFLARE_API_TOKEN" ] || [ -z "$CLOUDFLARE_ZONE_ID" ]; then
|
|
echo -e "${RED}❌ Cloudflare credentials not found${NC}"
|
|
echo "Please set: CLOUDFLARE_API_TOKEN and CLOUDFLARE_ZONE_ID"
|
|
echo "Or add them to .env.production file"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo -e "${GREEN}✅ Credentials loaded${NC}"
|
|
echo "Zone ID: ${CLOUDFLARE_ZONE_ID:0:15}..."
|
|
echo ""
|
|
|
|
# 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${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}✅ Found Static Web App: ${AZURE_STATIC_WEB_APP_URL}${NC}"
|
|
echo ""
|
|
|
|
# Verify Cloudflare API access
|
|
echo -e "${GREEN}🔐 Verifying Cloudflare API access...${NC}"
|
|
ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json")
|
|
|
|
ZONE_SUCCESS=$(echo "$ZONE_RESPONSE" | grep -o '"success":true' || echo "")
|
|
|
|
if [ -z "$ZONE_SUCCESS" ]; then
|
|
echo -e "${RED}❌ Failed to authenticate with Cloudflare API${NC}"
|
|
echo "Response: $ZONE_RESPONSE"
|
|
exit 1
|
|
fi
|
|
|
|
ZONE_NAME=$(echo "$ZONE_RESPONSE" | grep -o '"name":"[^"]*"' | cut -d'"' -f4)
|
|
echo -e "${GREEN}✅ Authenticated with Cloudflare${NC}"
|
|
echo "Zone: $ZONE_NAME"
|
|
echo ""
|
|
|
|
# Function to create or update DNS record
|
|
create_dns_record() {
|
|
local record_type=$1
|
|
local record_name=$2
|
|
local record_content=$3
|
|
local proxy=$4
|
|
|
|
echo -n "Configuring DNS: $record_name.$DOMAIN -> $record_content... "
|
|
|
|
# Check if record exists
|
|
EXISTING_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records?type=$record_type&name=$record_name.$DOMAIN" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json")
|
|
|
|
RECORD_ID=$(echo "$EXISTING_RECORD" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
|
|
if [ -n "$RECORD_ID" ] && [ "$RECORD_ID" != "null" ]; then
|
|
# Update existing record
|
|
DATA=$(cat <<EOF
|
|
{
|
|
"type": "$record_type",
|
|
"name": "$record_name",
|
|
"content": "$record_content",
|
|
"proxied": $proxy,
|
|
"ttl": 1
|
|
}
|
|
EOF
|
|
)
|
|
RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records/$RECORD_ID" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data "$DATA")
|
|
else
|
|
# Create new record
|
|
DATA=$(cat <<EOF
|
|
{
|
|
"type": "$record_type",
|
|
"name": "$record_name",
|
|
"content": "$record_content",
|
|
"proxied": $proxy,
|
|
"ttl": 1
|
|
}
|
|
EOF
|
|
)
|
|
RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data "$DATA")
|
|
fi
|
|
|
|
SUCCESS=$(echo "$RESPONSE" | grep -o '"success":true' || echo "")
|
|
if [ -n "$SUCCESS" ]; then
|
|
echo -e "${GREEN}✅${NC}"
|
|
return 0
|
|
else
|
|
ERRORS=$(echo "$RESPONSE" | grep -o '"message":"[^"]*"' | cut -d'"' -f4 | head -1)
|
|
echo -e "${YELLOW}⚠️ $ERRORS${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Create DNS records
|
|
echo -e "${GREEN}📝 Configuring 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}"
|
|
|
|
# Set SSL mode to Full
|
|
SSL_RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/settings/ssl" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data '{"value":"full"}')
|
|
|
|
if echo "$SSL_RESPONSE" | grep -q '"success":true'; then
|
|
echo -e "${GREEN}✅ SSL mode set to Full${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not update SSL settings${NC}"
|
|
fi
|
|
|
|
# Enable Always Use HTTPS
|
|
HTTPS_RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/settings/always_use_https" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data '{"value":"on"}')
|
|
|
|
if echo "$HTTPS_RESPONSE" | grep -q '"success":true'; then
|
|
echo -e "${GREEN}✅ Always Use HTTPS enabled${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not enable Always Use HTTPS${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Configure Security Settings
|
|
echo -e "${GREEN}🛡️ Configuring Security Settings...${NC}"
|
|
|
|
# Set security level to Medium
|
|
SECURITY_RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/settings/security_level" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data '{"value":"medium"}')
|
|
|
|
if echo "$SECURITY_RESPONSE" | grep -q '"success":true'; then
|
|
echo -e "${GREEN}✅ Security level set to Medium${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not update security level${NC}"
|
|
fi
|
|
|
|
# Enable Browser Integrity Check
|
|
BROWSER_RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/settings/browser_check" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data '{"value":"on"}')
|
|
|
|
if echo "$BROWSER_RESPONSE" | grep -q '"success":true'; then
|
|
echo -e "${GREEN}✅ Browser Integrity Check enabled${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not enable browser check${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Configure Speed Settings
|
|
echo -e "${GREEN}⚡ Configuring Speed Settings...${NC}"
|
|
|
|
# Enable Minification
|
|
MINIFY_RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/settings/minify" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data '{"value":{"css":"on","html":"on","js":"on"}}')
|
|
|
|
if echo "$MINIFY_RESPONSE" | grep -q '"success":true'; then
|
|
echo -e "${GREEN}✅ Minification enabled${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not enable minification${NC}"
|
|
fi
|
|
|
|
# Enable Brotli compression
|
|
BROTLI_RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/settings/brotli" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data '{"value":"on"}')
|
|
|
|
if echo "$BROTLI_RESPONSE" | grep -q '"success":true'; then
|
|
echo -e "${GREEN}✅ Brotli compression enabled${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not enable Brotli${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Add custom domain to Azure Static Web App
|
|
echo -e "${GREEN}🔗 Adding Custom Domain to Azure Static Web App...${NC}"
|
|
|
|
# For apex domain (may require TXT validation)
|
|
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}"
|
|
|
|
# For www subdomain
|
|
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 "Configuration Summary:"
|
|
echo " Domain: $DOMAIN"
|
|
echo " Static Web App: $AZURE_STATIC_WEB_APP_URL"
|
|
echo ""
|
|
echo "DNS Records:"
|
|
echo " ✅ www.$DOMAIN -> $AZURE_STATIC_WEB_APP_URL (Proxied)"
|
|
echo " ✅ $DOMAIN -> $AZURE_STATIC_WEB_APP_URL (Proxied)"
|
|
echo ""
|
|
echo "Cloudflare Settings:"
|
|
echo " ✅ SSL Mode: Full"
|
|
echo " ✅ Always Use HTTPS: Enabled"
|
|
echo " ✅ Security Level: Medium"
|
|
echo " ✅ Browser Integrity Check: Enabled"
|
|
echo " ✅ Minification: Enabled (JS, CSS, HTML)"
|
|
echo " ✅ Brotli Compression: Enabled"
|
|
echo ""
|
|
echo "Next Steps:"
|
|
echo " 1. Wait for DNS propagation (usually 5-30 minutes)"
|
|
echo " 2. Verify SSL certificates are provisioned (1-24 hours)"
|
|
echo " 3. Test the website at https://$DOMAIN"
|
|
echo " 4. Monitor Cloudflare analytics"
|
|
echo ""
|
|
|