#!/bin/bash # 01-setupenv.sh — Enable APIs, create staging bucket with lifecycle, SA, billing budgets # Run in: local VS Code terminal OR Cloud Shell # Source .env before running: source .env set -euo pipefail : "${PROJECT_ID:?Set PROJECT_ID in .env}" : "${REGION:?Set REGION in .env}" : "${BILLING_ACCOUNT_ID:?Set BILLING_ACCOUNT_ID in .env}" : "${AGENT_SA:?Set AGENT_SA in .env}" # ── Region Guard ──────────────────────────────────────────────────────── source "$(dirname "$0")/99-region-guard.sh" log_region_context "Storage-Bucket" "$REGION" "SELECTED" BUCKET_NAME="gs://${PROJECT_ID}-agent-staging" BUDGET_PROD_NAME="OSVauco-Agent-Budget-500USD" BUDGET_DEV_NAME="OSVauco-Dev-Budget-75USD" PUBSUB_TOPIC="billing-alert-auto-teardown" echo "=== 01: Environment Setup for ${PROJECT_ID} ===" # 0. Auth check bash "$(dirname "$0")/00-authcheck.sh" # 1. Enable required APIs (idempotent) echo "Enabling required APIs..." gcloud services enable \ aiplatform.googleapis.com \ storage.googleapis.com \ cloudbilling.googleapis.com \ cloudresourcemanager.googleapis.com \ iam.googleapis.com \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ cloudbuildv2.googleapis.com \ secretmanager.googleapis.com \ monitoring.googleapis.com \ logging.googleapis.com \ cloudtrace.googleapis.com \ pubsub.googleapis.com \ cloudfunctions.googleapis.com \ --project="$PROJECT_ID" --quiet echo "✓ APIs enabled." # 2. Create staging bucket (idempotent) if gcloud storage ls "$BUCKET_NAME" >/dev/null 2>&1; then echo "✓ Staging bucket $BUCKET_NAME already exists." else gcloud storage buckets create "$BUCKET_NAME" \ --location="$REGION" --project="$PROJECT_ID" --quiet echo "✓ Bucket created: $BUCKET_NAME" fi # 3. Apply lifecycle rule (auto-delete objects >7 days) cat > /tmp/lifecycle.json << 'EOF' {"rule":[{"action":{"type":"Delete"},"condition":{"age":7}}]} EOF gcloud storage buckets update "$BUCKET_NAME" --lifecycle-file=/tmp/lifecycle.json --quiet echo "✓ Lifecycle rule applied (delete after 7 days)." # 4. Service account (idempotent) SA_NAME=$(echo "$AGENT_SA" | cut -d'@' -f1) if ! gcloud iam service-accounts describe "$AGENT_SA" --project="$PROJECT_ID" >/dev/null 2>&1; then gcloud iam service-accounts create "$SA_NAME" \ --display-name="OSVauco Agent Runner SA" --project="$PROJECT_ID" --quiet echo "✓ Service account created: $AGENT_SA" fi for ROLE in \ roles/aiplatform.user \ roles/storage.objectAdmin \ roles/logging.logWriter \ roles/cloudtrace.agent \ roles/monitoring.metricWriter \ roles/secretmanager.secretAccessor \ roles/run.invoker; do gcloud projects add-iam-policy-binding "$PROJECT_ID" \ --member="serviceAccount:${AGENT_SA}" --role="$ROLE" --quiet done echo "✓ IAM bindings configured." # 5. Pub/Sub topic for billing auto-teardown (idempotent) if ! gcloud pubsub topics describe "${PUBSUB_TOPIC}" --project="${PROJECT_ID}" >/dev/null 2>&1; then gcloud pubsub topics create "${PUBSUB_TOPIC}" --project="${PROJECT_ID}" --quiet echo "✓ Pub/Sub topic created: ${PUBSUB_TOPIC}" else echo "✓ Pub/Sub topic already exists: ${PUBSUB_TOPIC}" fi # 6. Prod billing budget — $500, varsler på 50% / 80% / 100% + Pub/Sub (idempotent) EXISTING_PROD=$(gcloud billing budgets list \ --billing-account="${BILLING_ACCOUNT_ID}" \ --filter="displayName=${BUDGET_PROD_NAME}" \ --format="value(name)" 2>/dev/null | head -1 || true) if [[ -z "${EXISTING_PROD}" ]]; then gcloud billing budgets create \ --billing-account="${BILLING_ACCOUNT_ID}" \ --display-name="${BUDGET_PROD_NAME}" \ --budget-amount=500USD \ --threshold-rule=percent=0.5 \ --threshold-rule=percent=0.8 \ --threshold-rule=percent=1.0 \ --notifications-rule-pubsub-topic="projects/${PROJECT_ID}/topics/${PUBSUB_TOPIC}" echo "✓ Prod budget alert created ($500, Pub/Sub koblet)" else echo "✓ Prod budget alert already exists" fi # 7. Dev billing budget — $75, varsler på 70% / 90% + Pub/Sub (idempotent) EXISTING_DEV=$(gcloud billing budgets list \ --billing-account="${BILLING_ACCOUNT_ID}" \ --filter="displayName=${BUDGET_DEV_NAME}" \ --format="value(name)" 2>/dev/null | head -1 || true) if [[ -z "${EXISTING_DEV}" ]]; then gcloud billing budgets create \ --billing-account="${BILLING_ACCOUNT_ID}" \ --display-name="${BUDGET_DEV_NAME}" \ --budget-amount=75USD \ --threshold-rule=percent=0.7 \ --threshold-rule=percent=0.9 \ --threshold-rule=percent=1.0 \ --notifications-rule-pubsub-topic="projects/${PROJECT_ID}/topics/${PUBSUB_TOPIC}" echo "✓ Dev budget alert created ($75, Pub/Sub koblet)" else echo "✓ Dev budget alert already exists" fi echo "" echo "=== 01: Environment setup COMPLETE ===" echo " Kjør nå: bash infrastructure/10-cost-guard.sh" echo " for å aktivere auto-teardown Cloud Function"