chore: pre-migration snapshot
Layer0, MCP servers, Terraform consolidation
This commit is contained in:
308
scripts/deploy_infrastructure.sh
Normal file
308
scripts/deploy_infrastructure.sh
Normal file
@@ -0,0 +1,308 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Cloudflare Infrastructure Deployment Automation
|
||||
# Automated Terraform deployment with safety checks and rollback capabilities
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
TERRAFORM_DIR="terraform"
|
||||
BACKUP_DIR="terraform_backups"
|
||||
STATE_FILE="terraform.tfstate"
|
||||
PLAN_FILE="deployment_plan.tfplan"
|
||||
LOG_FILE="deployment_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# Function to log messages
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to log success
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to log warning
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to log error
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${NC}" | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Function to check prerequisites
|
||||
check_prerequisites() {
|
||||
log "Checking prerequisites..."
|
||||
|
||||
# Check if .env file exists
|
||||
if [[ ! -f "../.env" ]]; then
|
||||
error "Missing .env file. Run setup_credentials.sh first."
|
||||
fi
|
||||
|
||||
# Source environment variables
|
||||
source "../.env"
|
||||
|
||||
# Check required variables
|
||||
if [[ -z "$CLOUDFLARE_API_TOKEN" ]]; then
|
||||
error "CLOUDFLARE_API_TOKEN not set in .env"
|
||||
fi
|
||||
|
||||
if [[ -z "$CLOUDFLARE_ACCOUNT_ID" ]]; then
|
||||
error "CLOUDFLARE_ACCOUNT_ID not set in .env"
|
||||
fi
|
||||
|
||||
# Check Terraform installation
|
||||
if ! command -v terraform &> /dev/null; then
|
||||
error "Terraform not found. Please install Terraform first."
|
||||
fi
|
||||
|
||||
# Check Terraform version
|
||||
TF_VERSION=$(terraform version | head -n1 | awk '{print $2}' | sed 's/v//')
|
||||
log "Terraform version: $TF_VERSION"
|
||||
|
||||
success "Prerequisites check passed"
|
||||
}
|
||||
|
||||
# Function to backup current state
|
||||
backup_state() {
|
||||
log "Creating backup of current state..."
|
||||
|
||||
# Create backup directory
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Backup state file if it exists
|
||||
if [[ -f "$STATE_FILE" ]]; then
|
||||
BACKUP_NAME="${BACKUP_DIR}/state_backup_$(date +%Y%m%d_%H%M%S).tfstate"
|
||||
cp "$STATE_FILE" "$BACKUP_NAME"
|
||||
success "State backed up to: $BACKUP_NAME"
|
||||
else
|
||||
warning "No existing state file found"
|
||||
fi
|
||||
|
||||
# Backup terraform.tfvars
|
||||
if [[ -f "terraform.tfvars" ]]; then
|
||||
cp "terraform.tfvars" "${BACKUP_DIR}/terraform.tfvars.backup"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to prepare terraform.tfvars
|
||||
prepare_config() {
|
||||
log "Preparing Terraform configuration..."
|
||||
|
||||
# Update terraform.tfvars with actual credentials
|
||||
cat > terraform.tfvars << EOF
|
||||
cloudflare_api_token = "$CLOUDFLARE_API_TOKEN"
|
||||
cloudflare_account_id = "$CLOUDFLARE_ACCOUNT_ID"
|
||||
cloudflare_account_name = "" # Use account_id from .env
|
||||
EOF
|
||||
|
||||
# Add optional Zone ID if set
|
||||
if [[ -n "$CLOUDFLARE_ZONE_ID" ]]; then
|
||||
echo "cloudflare_zone_id = \"$CLOUDFLARE_ZONE_ID\"" >> terraform.tfvars
|
||||
fi
|
||||
|
||||
success "Configuration prepared"
|
||||
}
|
||||
|
||||
# Function to initialize Terraform
|
||||
init_terraform() {
|
||||
log "Initializing Terraform..."
|
||||
|
||||
if terraform init -upgrade; then
|
||||
success "Terraform initialized successfully"
|
||||
else
|
||||
error "Terraform initialization failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to validate Terraform configuration
|
||||
validate_config() {
|
||||
log "Validating Terraform configuration..."
|
||||
|
||||
if terraform validate; then
|
||||
success "Configuration validation passed"
|
||||
else
|
||||
error "Configuration validation failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to create deployment plan
|
||||
create_plan() {
|
||||
log "Creating deployment plan..."
|
||||
|
||||
if terraform plan -out="$PLAN_FILE" -detailed-exitcode; then
|
||||
case $? in
|
||||
0)
|
||||
success "No changes needed"
|
||||
return 0
|
||||
;;
|
||||
2)
|
||||
success "Plan created successfully"
|
||||
return 2
|
||||
;;
|
||||
*)
|
||||
error "Plan creation failed"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
error "Plan creation failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to show plan summary
|
||||
show_plan_summary() {
|
||||
log "Plan Summary:"
|
||||
terraform show -json "$PLAN_FILE" | jq -r '
|
||||
.resource_changes[] |
|
||||
select(.change.actions != ["no-op"]) |
|
||||
"\(.change.actions | join(",")) \(.type).\(.name)"
|
||||
' | sort | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to confirm deployment
|
||||
confirm_deployment() {
|
||||
echo
|
||||
echo "=================================================="
|
||||
echo "🚀 DEPLOYMENT CONFIRMATION"
|
||||
echo "=================================================="
|
||||
echo
|
||||
echo "The following changes will be applied:"
|
||||
show_plan_summary
|
||||
echo
|
||||
echo "Log file: $LOG_FILE"
|
||||
echo "Backup directory: $BACKUP_DIR"
|
||||
echo
|
||||
read -p "Do you want to proceed with deployment? (y/n): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log "Deployment cancelled by user"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to apply deployment
|
||||
apply_deployment() {
|
||||
log "Applying deployment..."
|
||||
|
||||
if terraform apply "$PLAN_FILE"; then
|
||||
success "Deployment applied successfully"
|
||||
else
|
||||
error "Deployment failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to verify deployment
|
||||
verify_deployment() {
|
||||
log "Verifying deployment..."
|
||||
|
||||
# Check if resources were created successfully
|
||||
OUTPUTS=$(terraform output -json)
|
||||
|
||||
if [[ -n "$OUTPUTS" ]]; then
|
||||
success "Deployment verification passed"
|
||||
echo "Outputs:"
|
||||
terraform output
|
||||
else
|
||||
warning "No outputs generated - manual verification required"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to cleanup temporary files
|
||||
cleanup() {
|
||||
log "Cleaning up temporary files..."
|
||||
|
||||
if [[ -f "$PLAN_FILE" ]]; then
|
||||
rm "$PLAN_FILE"
|
||||
success "Plan file removed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to show deployment summary
|
||||
deployment_summary() {
|
||||
echo
|
||||
echo "=================================================="
|
||||
echo "🎉 DEPLOYMENT SUMMARY"
|
||||
echo "=================================================="
|
||||
echo
|
||||
echo "✅ Infrastructure deployed successfully"
|
||||
echo "📋 Log file: $LOG_FILE"
|
||||
echo "💾 Backups: $BACKUP_DIR"
|
||||
echo "🌐 Resources deployed:"
|
||||
terraform state list
|
||||
echo
|
||||
echo "Next steps:"
|
||||
echo "1. Check Cloudflare dashboard for deployed resources"
|
||||
echo "2. Test DNS resolution for your domains"
|
||||
echo "3. Verify WAF rules are active"
|
||||
echo "4. Test tunnel connectivity"
|
||||
echo
|
||||
}
|
||||
|
||||
# Function to handle rollback
|
||||
rollback() {
|
||||
error "Deployment failed - rolling back..."
|
||||
|
||||
# Check if we have a backup
|
||||
LATEST_BACKUP=$(ls -t "${BACKUP_DIR}/state_backup_*.tfstate" 2>/dev/null | head -n1)
|
||||
|
||||
if [[ -n "$LATEST_BACKUP" ]]; then
|
||||
log "Restoring from backup: $LATEST_BACKUP"
|
||||
cp "$LATEST_BACKUP" "$STATE_FILE"
|
||||
warning "State restored from backup. Manual verification required."
|
||||
else
|
||||
error "No backup available for rollback"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main deployment function
|
||||
main() {
|
||||
echo "🚀 Cloudflare Infrastructure Deployment"
|
||||
echo "=================================================="
|
||||
echo
|
||||
|
||||
# Change to Terraform directory
|
||||
cd "$TERRAFORM_DIR" || error "Terraform directory not found"
|
||||
|
||||
# Set trap for cleanup on exit
|
||||
trap cleanup EXIT
|
||||
|
||||
# Execute deployment steps
|
||||
check_prerequisites
|
||||
backup_state
|
||||
prepare_config
|
||||
init_terraform
|
||||
validate_config
|
||||
|
||||
# Create plan and check if changes are needed
|
||||
if create_plan; then
|
||||
case $? in
|
||||
0)
|
||||
success "No changes needed - infrastructure is up to date"
|
||||
exit 0
|
||||
;;
|
||||
2)
|
||||
confirm_deployment
|
||||
apply_deployment
|
||||
verify_deployment
|
||||
deployment_summary
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle errors
|
||||
trap 'rollback' ERR
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user