198 lines
8.1 KiB
PowerShell
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
|
|
|