# ============================================================================= # 03-create-secrets.ps1 (Windows) # Creates and configures secrets in Google Cloud Secret Manager. # # Run this after 02-setup-project.ps1 to set up sensitive configuration # values (e.g., MongoDB connection string). # # Linux users: run GCR/scripts/03-create-secrets.sh instead. # ============================================================================= #Requires -Version 5.1 Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $EnvFile = Join-Path $ScriptDir "..\\.env" # ── Load .env ───────────────────────────────────────────────────────────────── if (-not (Test-Path $EnvFile)) { Write-Error "ERROR: $EnvFile not found.`nCopy GCR\.env.example to GCR\.env and fill in your values first." exit 1 } $config = @{} foreach ($line in Get-Content $EnvFile) { if ($line -match '^\s*$' -or $line -match '^\s*#') { continue } if ($line -match '^([^=]+)=(.*)$') { $config[$Matches[1].Trim()] = $Matches[2].Trim() } } $GCP_PROJECT_ID = $config['GCP_PROJECT_ID'] ?? '' if (-not $GCP_PROJECT_ID) { Write-Error "GCP_PROJECT_ID is not set in .env"; exit 1 } Write-Host "================================================================" Write-Host " Google Cloud Secret Manager setup" Write-Host "================================================================" Write-Host " Project: $GCP_PROJECT_ID" Write-Host "" # ── Helper function to create or update a secret ────────────────────────────── function New-OrUpdateSecret { param( [string]$SecretName, [string]$SecretPrompt ) Write-Host ">>> Setting up secret: $SecretName" Write-Host " $SecretPrompt" # Read secret without echo $SecretValue = Read-Host " Enter value (will not be echoed)" -AsSecureString $PlainValue = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUni($SecretValue) ) # Write to temp file without trailing newline to avoid contaminating the secret $TempFile = [System.IO.Path]::GetTempFileName() try { [System.IO.File]::WriteAllText($TempFile, $PlainValue, [System.Text.Encoding]::UTF8) $secretExists = $false try { gcloud secrets describe $SecretName --project=$GCP_PROJECT_ID 2>$null | Out-Null $secretExists = $true } catch { } if ($secretExists) { Write-Host " Secret already exists — creating new version..." gcloud secrets versions add $SecretName ` --data-file=$TempFile ` --project=$GCP_PROJECT_ID } else { Write-Host " Creating new secret..." gcloud secrets create $SecretName ` --data-file=$TempFile ` --replication-policy="automatic" ` --project=$GCP_PROJECT_ID } } finally { Remove-Item $TempFile -Force -ErrorAction SilentlyContinue } Write-Host " ✓ Secret '$SecretName' ready." Write-Host "" } # ── Step 1: Create MongoDB connection string secret ────────────────────────── New-OrUpdateSecret ` "mongodb-connection-string" ` "MongoDB Atlas or self-hosted connection URI (e.g., mongodb+srv://user:pass@cluster.mongodb.net)" # ── Step 2: Grant Cloud Run service account access to secrets ───────────────── Write-Host ">>> Granting Cloud Run service account access to secrets..." Write-Host "" # Get the default Cloud Run service account for this project $SERVICE_ACCOUNT = "$GCP_PROJECT_ID@appspot.gserviceaccount.com" foreach ($SECRET_NAME in @("mongodb-connection-string")) { Write-Host " Granting Secret Accessor role for '$SECRET_NAME' to $SERVICE_ACCOUNT" gcloud secrets add-iam-policy-binding $SECRET_NAME ` --member="serviceAccount:$SERVICE_ACCOUNT" ` --role="roles/secretmanager.secretAccessor" ` --project=$GCP_PROJECT_ID ` --quiet } Write-Host "" Write-Host "================================================================" Write-Host " Secret Manager setup complete!" Write-Host "================================================================" Write-Host "" Write-Host ">>> Summary:" Write-Host " Secrets created:" Write-Host " • mongodb-connection-string" Write-Host "" Write-Host " Service account granted access:" Write-Host " • $SERVICE_ACCOUNT" Write-Host "" Write-Host ">>> Next step: run GCR\scripts\04-deploy.ps1" Write-Host " (The deploy script will automatically inject secrets into" Write-Host " the running container.)"