Files
miracles_in_motion/scripts/deployment-checklist.ps1

351 lines
12 KiB
PowerShell
Raw Normal View History

# Deployment Checklist Script for Miracles In Motion
# This script verifies all prerequisites are met before deployment
param(
[Parameter(Mandatory=$false)]
[string]$ResourceGroupName = "rg-miraclesinmotion-prod",
[Parameter(Mandatory=$false)]
[string]$StaticWebAppName = "",
[Parameter(Mandatory=$false)]
[string]$FunctionAppName = "",
[Parameter(Mandatory=$false)]
[switch]$SkipCloudflare = $false,
[Parameter(Mandatory=$false)]
[switch]$SkipStripe = $false
)
$ErrorActionPreference = "Stop"
# Colors for output
function Write-ColorOutput($ForegroundColor) {
$fc = $host.UI.RawUI.ForegroundColor
$host.UI.RawUI.ForegroundColor = $ForegroundColor
if ($args) {
Write-Output $args
}
$host.UI.RawUI.ForegroundColor = $fc
}
Write-ColorOutput Green "🚀 Deployment Prerequisites Checklist"
Write-Output "=========================================="
Write-Output ""
$allChecksPassed = $true
$checks = @()
# Function to add check result
function Add-Check {
param(
[string]$Name,
[bool]$Passed,
[string]$Message = ""
)
$checks += @{
Name = $Name
Passed = $Passed
Message = $Message
}
if (-not $Passed) {
$script:allChecksPassed = $false
}
}
# 1. Azure CLI Check
Write-ColorOutput Cyan "1. Checking Azure CLI..."
try {
$azVersion = az version --output json | ConvertFrom-Json
Add-Check "Azure CLI" $true "Version: $($azVersion.'azure-cli')"
Write-ColorOutput Green " ✅ Azure CLI installed"
} catch {
Add-Check "Azure CLI" $false "Azure CLI not found. Install from: https://docs.microsoft.com/cli/azure/install-azure-cli"
Write-ColorOutput Red " ❌ Azure CLI not found"
}
Write-Output ""
# 2. Azure Login Check
Write-ColorOutput Cyan "2. Checking Azure login status..."
try {
$account = az account show --output json 2>$null | ConvertFrom-Json
if ($account) {
Add-Check "Azure Login" $true "Logged in as: $($account.user.name)"
Write-ColorOutput Green " ✅ Logged in to Azure"
Write-Output " Subscription: $($account.name)"
Write-Output " Tenant ID: $($account.tenantId)"
} else {
throw "Not logged in"
}
} catch {
Add-Check "Azure Login" $false "Not logged in to Azure. Run: az login"
Write-ColorOutput Red " ❌ Not logged in to Azure"
}
Write-Output ""
# 3. Resource Group Check
Write-ColorOutput Cyan "3. Checking resource group..."
try {
$rg = az group show --name $ResourceGroupName --output json 2>$null | ConvertFrom-Json
if ($rg) {
Add-Check "Resource Group" $true "Resource group exists: $($rg.name)"
Write-ColorOutput Green " ✅ Resource group exists"
Write-Output " Location: $($rg.location)"
} else {
throw "Resource group not found"
}
} catch {
Add-Check "Resource Group" $false "Resource group not found: $ResourceGroupName"
Write-ColorOutput Red " ❌ Resource group not found"
}
Write-Output ""
# 4. Static Web App Check
Write-ColorOutput Cyan "4. Checking Static Web App..."
if ([string]::IsNullOrEmpty($StaticWebAppName)) {
# Try to find Static Web App
$swa = az staticwebapp list --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json | Select-Object -First 1
if ($swa) {
$StaticWebAppName = $swa.name
}
}
if (-not [string]::IsNullOrEmpty($StaticWebAppName)) {
try {
$swa = az staticwebapp show --name $StaticWebAppName --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json
if ($swa) {
Add-Check "Static Web App" $true "Static Web App exists: $($swa.name)"
Write-ColorOutput Green " ✅ Static Web App exists"
Write-Output " URL: https://$($swa.defaultHostname)"
} else {
throw "Static Web App not found"
}
} catch {
Add-Check "Static Web App" $false "Static Web App not found: $StaticWebAppName"
Write-ColorOutput Red " ❌ Static Web App not found"
}
} else {
Add-Check "Static Web App" $false "Static Web App name not specified"
Write-ColorOutput Red " ❌ Static Web App name not specified"
}
Write-Output ""
# 5. Function App Check
Write-ColorOutput Cyan "5. Checking Function App..."
if ([string]::IsNullOrEmpty($FunctionAppName)) {
# Try to find Function App
$fa = az functionapp list --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json | Select-Object -First 1
if ($fa) {
$FunctionAppName = $fa.name
}
}
if (-not [string]::IsNullOrEmpty($FunctionAppName)) {
try {
$fa = az functionapp show --name $FunctionAppName --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json
if ($fa) {
Add-Check "Function App" $true "Function App exists: $($fa.name)"
Write-ColorOutput Green " ✅ Function App exists"
Write-Output " URL: https://$($fa.defaultHostName)"
} else {
throw "Function App not found"
}
} catch {
Add-Check "Function App" $false "Function App not found: $FunctionAppName"
Write-ColorOutput Red " ❌ Function App not found"
}
} else {
Add-Check "Function App" $false "Function App name not specified"
Write-ColorOutput Red " ❌ Function App name not specified"
}
Write-Output ""
# 6. Key Vault Check
Write-ColorOutput Cyan "6. Checking Key Vault..."
try {
$kv = az keyvault list --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json | Select-Object -First 1
if ($kv) {
Add-Check "Key Vault" $true "Key Vault exists: $($kv.name)"
Write-ColorOutput Green " ✅ Key Vault exists"
# Check for required secrets
$requiredSecrets = @("stripe-secret-key", "azure-client-id", "azure-tenant-id")
$missingSecrets = @()
foreach ($secret in $requiredSecrets) {
try {
$secretValue = az keyvault secret show --vault-name $kv.name --name $secret --output json 2>$null | ConvertFrom-Json
if (-not $secretValue) {
$missingSecrets += $secret
}
} catch {
$missingSecrets += $secret
}
}
if ($missingSecrets.Count -eq 0) {
Write-ColorOutput Green " ✅ Required secrets present"
} else {
Write-ColorOutput Yellow " ⚠️ Missing secrets: $($missingSecrets -join ', ')"
}
} else {
throw "Key Vault not found"
}
} catch {
Add-Check "Key Vault" $false "Key Vault not found"
Write-ColorOutput Red " ❌ Key Vault not found"
}
Write-Output ""
# 7. Cosmos DB Check
Write-ColorOutput Cyan "7. Checking Cosmos DB..."
try {
$cosmos = az cosmosdb list --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json | Select-Object -First 1
if ($cosmos) {
Add-Check "Cosmos DB" $true "Cosmos DB exists: $($cosmos.name)"
Write-ColorOutput Green " ✅ Cosmos DB exists"
} else {
throw "Cosmos DB not found"
}
} catch {
Add-Check "Cosmos DB" $false "Cosmos DB not found"
Write-ColorOutput Red " ❌ Cosmos DB not found"
}
Write-Output ""
# 8. Application Insights Check
Write-ColorOutput Cyan "8. Checking Application Insights..."
try {
$ai = az monitor app-insights component show --app $ResourceGroupName --output json 2>$null | ConvertFrom-Json
if (-not $ai) {
# Try alternative method
$ai = az resource list --resource-group $ResourceGroupName --resource-type "Microsoft.Insights/components" --output json 2>$null | ConvertFrom-Json | Select-Object -First 1
}
if ($ai) {
Add-Check "Application Insights" $true "Application Insights exists"
Write-ColorOutput Green " ✅ Application Insights exists"
} else {
throw "Application Insights not found"
}
} catch {
Add-Check "Application Insights" $false "Application Insights not found"
Write-ColorOutput Red " ❌ Application Insights not found"
}
Write-Output ""
# 9. Azure AD App Registration Check
Write-ColorOutput Cyan "9. Checking Azure AD App Registration..."
try {
$appReg = az ad app list --display-name "Miracles In Motion Web App" --output json 2>$null | ConvertFrom-Json | Select-Object -First 1
if ($appReg) {
Add-Check "Azure AD App Registration" $true "App Registration exists: $($appReg.appId)"
Write-ColorOutput Green " ✅ Azure AD App Registration exists"
Write-Output " App ID: $($appReg.appId)"
# Check redirect URIs
if ($appReg.web.redirectUris) {
Write-Output " Redirect URIs: $($appReg.web.redirectUris.Count)"
}
} else {
throw "App Registration not found"
}
} catch {
Add-Check "Azure AD App Registration" $false "Azure AD App Registration not found"
Write-ColorOutput Red " ❌ Azure AD App Registration not found"
}
Write-Output ""
# 10. Cloudflare Check
if (-not $SkipCloudflare) {
Write-ColorOutput Cyan "10. Checking Cloudflare configuration..."
try {
# Check DNS resolution
$dnsResult = Resolve-DnsName -Name "miraclesinmotion.org" -ErrorAction SilentlyContinue
if ($dnsResult) {
Add-Check "Cloudflare DNS" $true "DNS resolution working"
Write-ColorOutput Green " ✅ DNS resolution working"
} else {
Add-Check "Cloudflare DNS" $false "DNS resolution failed"
Write-ColorOutput Red " ❌ DNS resolution failed"
}
} catch {
Add-Check "Cloudflare DNS" $false "Could not verify DNS"
Write-ColorOutput Yellow " ⚠️ Could not verify DNS"
}
Write-Output ""
}
# 11. Stripe Check
if (-not $SkipStripe) {
Write-ColorOutput Cyan "11. Checking Stripe configuration..."
try {
if ($kv) {
$stripeKey = az keyvault secret show --vault-name $kv.name --name "stripe-secret-key" --output json 2>$null | ConvertFrom-Json
if ($stripeKey -and $stripeKey.value -like "sk_live_*") {
Add-Check "Stripe Configuration" $true "Stripe keys configured"
Write-ColorOutput Green " ✅ Stripe keys configured"
} else {
Add-Check "Stripe Configuration" $false "Stripe keys not configured or not production keys"
Write-ColorOutput Yellow " ⚠️ Stripe keys not configured or not production keys"
}
} else {
Add-Check "Stripe Configuration" $false "Key Vault not available"
Write-ColorOutput Yellow " ⚠️ Key Vault not available"
}
} catch {
Add-Check "Stripe Configuration" $false "Could not verify Stripe configuration"
Write-ColorOutput Yellow " ⚠️ Could not verify Stripe configuration"
}
Write-Output ""
}
# 12. Environment Variables Check
Write-ColorOutput Cyan "12. Checking environment variables..."
$envFile = ".env.production"
if (Test-Path $envFile) {
Add-Check "Environment File" $true "Environment file exists"
Write-ColorOutput Green " ✅ Environment file exists"
} else {
Add-Check "Environment File" $false "Environment file not found: $envFile"
Write-ColorOutput Yellow " ⚠️ Environment file not found"
}
Write-Output ""
# Summary
Write-Output ""
Write-ColorOutput Cyan "=========================================="
Write-ColorOutput Cyan "Summary"
Write-ColorOutput Cyan "=========================================="
Write-Output ""
$passedChecks = ($checks | Where-Object { $_.Passed -eq $true }).Count
$totalChecks = $checks.Count
Write-Output "Passed: $passedChecks / $totalChecks"
Write-Output ""
foreach ($check in $checks) {
if ($check.Passed) {
Write-ColorOutput Green "$($check.Name)"
} else {
Write-ColorOutput Red "$($check.Name)"
if ($check.Message) {
Write-Output " $($check.Message)"
}
}
}
Write-Output ""
if ($allChecksPassed) {
Write-ColorOutput Green "✅ All checks passed! Ready for deployment."
exit 0
} else {
Write-ColorOutput Red "❌ Some checks failed. Please fix the issues before deploying."
exit 1
}