127 lines
5.1 KiB
PowerShell
127 lines
5.1 KiB
PowerShell
# =============================================================================
|
|
# 02-setup-project.ps1 (Windows)
|
|
# One-time GCP project setup:
|
|
# - Links a billing account to the project
|
|
# - Enables required APIs (Cloud Run, Artifact Registry, Secret Manager)
|
|
# - Creates an Artifact Registry Docker repository
|
|
# - Grants the current user the minimum required IAM roles
|
|
#
|
|
# Safe to re-run — most operations are idempotent.
|
|
# Linux users: run GCR/scripts/02-setup-project.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'] ?? ''
|
|
$GCP_REGION = $config['GCP_REGION'] ?? ''
|
|
$GCP_REPOSITORY = $config['GCP_REPOSITORY'] ?? ''
|
|
|
|
if (-not $GCP_PROJECT_ID) { Write-Error "GCP_PROJECT_ID is not set in .env"; exit 1 }
|
|
if (-not $GCP_REGION) { Write-Error "GCP_REGION is not set in .env"; exit 1 }
|
|
if (-not $GCP_REPOSITORY) { Write-Error "GCP_REPOSITORY is not set in .env"; exit 1 }
|
|
|
|
Write-Host ">>> Active project: $GCP_PROJECT_ID"
|
|
Write-Host ">>> Region: $GCP_REGION"
|
|
Write-Host ">>> AR repository: $GCP_REPOSITORY"
|
|
Write-Host ""
|
|
|
|
# ── Step 1: Link billing account ──────────────────────────────────────────────
|
|
Write-Host ">>> Checking billing status..."
|
|
$billingOutput = gcloud billing projects describe $GCP_PROJECT_ID --format="value(billingEnabled)" 2>$null
|
|
$billingEnabled = ($billingOutput -eq "True")
|
|
|
|
if ($billingEnabled) {
|
|
Write-Host " Billing is already enabled — skipping."
|
|
} else {
|
|
Write-Host ""
|
|
Write-Host " Billing is NOT enabled on this project."
|
|
Write-Host " Listing available billing accounts..."
|
|
Write-Host ""
|
|
gcloud billing accounts list --format="table(name,displayName,open)"
|
|
Write-Host ""
|
|
$BILLING_ACCOUNT_ID = Read-Host " Enter the BILLING_ACCOUNT_ID from the list above (format: XXXXXX-XXXXXX-XXXXXX)"
|
|
gcloud billing projects link $GCP_PROJECT_ID --billing-account=$BILLING_ACCOUNT_ID
|
|
Write-Host " Billing linked."
|
|
}
|
|
|
|
# ── Step 2: Enable required APIs ─────────────────────────────────────────────
|
|
Write-Host ""
|
|
Write-Host ">>> Enabling required Google Cloud APIs (this may take a minute)..."
|
|
gcloud services enable `
|
|
run.googleapis.com `
|
|
artifactregistry.googleapis.com `
|
|
secretmanager.googleapis.com `
|
|
cloudresourcemanager.googleapis.com `
|
|
--project=$GCP_PROJECT_ID
|
|
Write-Host " APIs enabled."
|
|
|
|
# ── Step 3: Create Artifact Registry Docker repository ───────────────────────
|
|
Write-Host ""
|
|
Write-Host ">>> Creating Artifact Registry repository: $GCP_REPOSITORY ..."
|
|
$repoExists = $false
|
|
try {
|
|
gcloud artifacts repositories describe $GCP_REPOSITORY `
|
|
--location=$GCP_REGION `
|
|
--project=$GCP_PROJECT_ID 2>$null | Out-Null
|
|
$repoExists = $true
|
|
} catch { }
|
|
|
|
if ($repoExists) {
|
|
Write-Host " Repository already exists — skipping."
|
|
} else {
|
|
gcloud artifacts repositories create $GCP_REPOSITORY `
|
|
--repository-format=docker `
|
|
--location=$GCP_REGION `
|
|
--description="Container images for Htmx app" `
|
|
--project=$GCP_PROJECT_ID
|
|
Write-Host " Repository created."
|
|
}
|
|
|
|
# ── Step 4: Grant current user the minimum required IAM roles ─────────────────
|
|
$CURRENT_USER = (gcloud config get-value account).Trim()
|
|
Write-Host ""
|
|
Write-Host ">>> Granting IAM roles to $CURRENT_USER ..."
|
|
|
|
foreach ($role in @(
|
|
"roles/run.developer",
|
|
"roles/artifactregistry.writer",
|
|
"roles/iam.serviceAccountUser",
|
|
"roles/secretmanager.admin",
|
|
"roles/secretmanager.secretAccessor",
|
|
"roles/secretmanager.secretVersionAdder"
|
|
)) {
|
|
Write-Host " Adding role: $role"
|
|
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID `
|
|
--member="user:$CURRENT_USER" `
|
|
--role=$role `
|
|
--quiet
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host ">>> Project setup complete."
|
|
Write-Host ""
|
|
Write-Host ">>> Summary:"
|
|
Write-Host " Project ID: $GCP_PROJECT_ID"
|
|
Write-Host " Region: $GCP_REGION"
|
|
Write-Host " Artifact Registry: $GCP_REGION-docker.pkg.dev/$GCP_PROJECT_ID/$GCP_REPOSITORY"
|
|
Write-Host ""
|
|
Write-Host ">>> Next step: run GCR\scripts\03-create-secrets.ps1"
|