Files
miracles_in_motion/scripts/store-secrets-in-keyvault.ps1

198 lines
8.1 KiB
PowerShell

# Script to store secrets in Azure Key Vault
# This script reads from .env.production and stores secrets in Key Vault
param(
[Parameter(Mandatory=$false)]
[string]$ResourceGroupName = "rg-miraclesinmotion-prod",
[Parameter(Mandatory=$false)]
[string]$KeyVaultName = "",
[Parameter(Mandatory=$false)]
[switch]$CreateKeyVault = $false
)
$ErrorActionPreference = "Stop"
Write-Host "🔐 Storing Secrets in Azure Key Vault" -ForegroundColor Green
Write-Host "====================================" -ForegroundColor Green
Write-Host ""
# Check if logged in to Azure
$account = az account show --output json 2>$null | ConvertFrom-Json
if (-not $account) {
Write-Host "❌ Not logged in to Azure. Please run: az login" -ForegroundColor Red
exit 1
}
Write-Host "✅ Logged in to Azure" -ForegroundColor Green
Write-Host " Subscription: $($account.name)" -ForegroundColor Gray
Write-Host ""
# Get Key Vault name
if ([string]::IsNullOrEmpty($KeyVaultName)) {
$KeyVaultName = az keyvault list --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json | Select-Object -First 1 -ExpandProperty name
}
if ([string]::IsNullOrEmpty($KeyVaultName)) {
if ($CreateKeyVault) {
$KeyVaultName = "mim-prod-$(Get-Random -Minimum 1000 -Maximum 9999)-kv"
Write-Host "📦 Creating Key Vault: $KeyVaultName" -ForegroundColor Cyan
az keyvault create `
--name $KeyVaultName `
--resource-group $ResourceGroupName `
--location $(az group show --name $ResourceGroupName --query location -o tsv) `
--sku standard `
--enable-rbac-authorization true `
--enable-soft-delete true `
--retention-days 90 | Out-Null
Write-Host "✅ Key Vault created" -ForegroundColor Green
} else {
Write-Host "❌ Key Vault not found. Run with -CreateKeyVault to create one." -ForegroundColor Red
exit 1
}
} else {
Write-Host "✅ Found Key Vault: $KeyVaultName" -ForegroundColor Green
}
Write-Host ""
# Check if .env.production exists
$envFile = ".env.production"
if (-not (Test-Path $envFile)) {
Write-Host "❌ .env.production file not found. Please create it first." -ForegroundColor Red
Write-Host " Run: .\scripts\populate-env.ps1" -ForegroundColor Yellow
exit 1
}
Write-Host "📄 Reading secrets from $envFile..." -ForegroundColor Cyan
# Read .env file and parse key-value pairs
$envContent = Get-Content $envFile -Raw
$secrets = @{}
# Parse environment variables (simple parser - handles KEY=VALUE format)
$lines = $envContent -split "`n"
foreach ($line in $lines) {
$line = $line.Trim()
if ($line -and -not $line.StartsWith("#") -and $line -match "^([^=]+)=(.*)$") {
$key = $matches[1].Trim()
$value = $matches[2].Trim()
# Skip empty values and placeholders
if ($value -and $value -notmatch "^(your-|YOUR_|placeholder)" -and $value -ne "") {
$secrets[$key] = $value
}
}
}
Write-Host "✅ Found $($secrets.Count) secrets to store" -ForegroundColor Green
Write-Host ""
# Define which secrets to store in Key Vault
$secretsToStore = @(
@{Name="azure-tenant-id"; EnvKey="AZURE_TENANT_ID"; Required=$true},
@{Name="azure-client-id"; EnvKey="AZURE_CLIENT_ID"; Required=$false},
@{Name="azure-client-secret"; EnvKey="AZURE_CLIENT_SECRET"; Required=$false},
@{Name="stripe-publishable-key"; EnvKey="VITE_STRIPE_PUBLISHABLE_KEY"; Required=$false},
@{Name="stripe-secret-key"; EnvKey="STRIPE_SECRET_KEY"; Required=$false},
@{Name="stripe-webhook-secret"; EnvKey="STRIPE_WEBHOOK_SECRET"; Required=$false},
@{Name="cosmos-endpoint"; EnvKey="COSMOS_ENDPOINT"; Required=$false},
@{Name="cosmos-key"; EnvKey="COSMOS_KEY"; Required=$false},
@{Name="cosmos-database-name"; EnvKey="COSMOS_DATABASE_NAME"; Required=$false},
@{Name="app-insights-connection-string"; EnvKey="APPLICATIONINSIGHTS_CONNECTION_STRING"; Required=$false},
@{Name="signalr-connection-string"; EnvKey="SIGNALR_CONNECTION_STRING"; Required=$false},
@{Name="cloudflare-zone-id"; EnvKey="CLOUDFLARE_ZONE_ID"; Required=$false},
@{Name="cloudflare-api-token"; EnvKey="CLOUDFLARE_API_TOKEN"; Required=$false},
@{Name="salesforce-client-id"; EnvKey="SALESFORCE_CLIENT_ID"; Required=$false},
@{Name="salesforce-client-secret"; EnvKey="SALESFORCE_CLIENT_SECRET"; Required=$false},
@{Name="smtp-password"; EnvKey="SMTP_PASSWORD"; Required=$false},
@{Name="session-secret"; EnvKey="SESSION_SECRET"; Required=$false},
@{Name="jwt-secret"; EnvKey="JWT_SECRET"; Required=$false},
@{Name="encryption-key"; EnvKey="ENCRYPTION_KEY"; Required=$false}
)
$storedCount = 0
$skippedCount = 0
$errorCount = 0
Write-Host "📦 Storing secrets in Key Vault..." -ForegroundColor Cyan
Write-Host ""
foreach ($secretDef in $secretsToStore) {
$secretName = $secretDef.Name
$envKey = $secretDef.EnvKey
$required = $secretDef.Required
if ($secrets.ContainsKey($envKey)) {
$secretValue = $secrets[$envKey]
try {
Write-Host " Storing: $secretName" -ForegroundColor Gray
az keyvault secret set `
--vault-name $KeyVaultName `
--name $secretName `
--value $secretValue 2>$null | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-Host " ✅ Stored successfully" -ForegroundColor Green
$storedCount++
} else {
Write-Host " ⚠️ Failed to store (may need RBAC permissions)" -ForegroundColor Yellow
$errorCount++
}
} catch {
Write-Host " ❌ Error: $($_.Exception.Message)" -ForegroundColor Red
$errorCount++
}
} else {
if ($required) {
Write-Host " ⚠️ Missing required secret: $secretName ($envKey)" -ForegroundColor Yellow
$skippedCount++
} else {
Write-Host " ⏭️ Skipping: $secretName (not in .env file)" -ForegroundColor Gray
$skippedCount++
}
}
}
Write-Host ""
Write-Host "📊 Summary:" -ForegroundColor Cyan
Write-Host " ✅ Stored: $storedCount" -ForegroundColor Green
Write-Host " ⏭️ Skipped: $skippedCount" -ForegroundColor Yellow
Write-Host " ❌ Errors: $errorCount" -ForegroundColor $(if ($errorCount -gt 0) { "Red" } else { "Green" })
Write-Host ""
# Prompt for additional secrets
Write-Host "💡 Additional Secrets" -ForegroundColor Cyan
Write-Host "You can manually add more secrets using:" -ForegroundColor Gray
Write-Host " az keyvault secret set --vault-name $KeyVaultName --name <secret-name> --value <secret-value>" -ForegroundColor White
Write-Host ""
# Show how to retrieve secrets
Write-Host "📖 Retrieving Secrets" -ForegroundColor Cyan
Write-Host "To retrieve a secret:" -ForegroundColor Gray
Write-Host " az keyvault secret show --vault-name $KeyVaultName --name <secret-name> --query value -o tsv" -ForegroundColor White
Write-Host ""
# Show Key Vault URL
$keyVaultUrl = "https://$KeyVaultName.vault.azure.net/"
Write-Host "🔗 Key Vault URL: $keyVaultUrl" -ForegroundColor Cyan
Write-Host ""
if ($errorCount -gt 0) {
Write-Host "⚠️ Some secrets failed to store. You may need to:" -ForegroundColor Yellow
Write-Host "1. Grant yourself 'Key Vault Secrets Officer' role on the Key Vault" -ForegroundColor White
Write-Host "2. Or use Azure Portal to manually add secrets" -ForegroundColor White
Write-Host ""
Write-Host "Grant role command:" -ForegroundColor Cyan
$currentUser = az ad signed-in-user show --query id -o tsv
Write-Host " az role assignment create --role 'Key Vault Secrets Officer' --assignee $currentUser --scope /subscriptions/$($account.id)/resourceGroups/$ResourceGroupName/providers/Microsoft.KeyVault/vaults/$KeyVaultName" -ForegroundColor White
Write-Host ""
}
Write-Host "✅ Done!" -ForegroundColor Green