#!/bin/bash set -e # Configuration IMAGE_NAME="contoso-api" REGION="us-central1" SERVICE_NAME="contoso" # Get project ID from terraform.tfvars if it exists, otherwise use gcloud if [ -f "$(dirname "$0")/terraform/terraform.tfvars" ]; then PROJECT_ID=$(grep '^project_id' "$(dirname "$0")/terraform/terraform.tfvars" | cut -d'"' -f2) fi # Fallback to gcloud if not found in tfvars if [ -z "$PROJECT_ID" ]; then PROJECT_ID=$(gcloud config get-value project 2>/dev/null || echo "") fi # Help function function show_help { echo "Usage: $0 [options]" echo "Options:" echo " --deploy Deploy to Cloud Run via Terraform" echo " --build Build and push Docker image before deploying (use with --deploy)" echo " --destroy Destroy cloud resources with Terraform" echo " --list List all Cloud Run services in the project" echo " --help Show this help message" echo "" echo "Examples:" echo " $0 --deploy # Deploy with existing Docker image" echo " $0 --deploy --build # Build Docker image then deploy" echo "" echo "Additional scripts:" echo " ./deployment/cleanup-images.sh Clean up container images (not managed by Terraform)" exit 0 } # Check if any arguments were provided if [ $# -eq 0 ]; then show_help fi # Process arguments BUILD=false DEPLOY=false DESTROY=false LIST=false while [[ $# -gt 0 ]]; do case "$1" in --build) BUILD=true shift ;; --deploy) DEPLOY=true shift ;; --destroy) DESTROY=true shift ;; --list) LIST=true shift ;; --help) show_help ;; *) echo "Unknown option: $1" show_help ;; esac done # Ensure project ID is available if [ -z "$PROJECT_ID" ]; then echo "ERROR: No Google Cloud project ID found." echo "Either run 'gcloud config set project YOUR_PROJECT_ID' or ensure terraform.tfvars contains project_id" exit 1 fi echo "Using Google Cloud project: $PROJECT_ID" echo "===================================" # List Cloud Run services if [ "$LIST" = true ]; then echo "Listing all services and resources in project: $PROJECT_ID" echo "=================================================" # Check if gcloud is available if ! command -v gcloud &> /dev/null; then echo "ERROR: gcloud CLI is not installed or not in PATH" exit 1 fi echo "=== COMPUTE SERVICES ===" echo "Cloud Run Services:" if gcloud run services list --project="$PROJECT_ID" --format="value(metadata.name)" --limit=1 &>/dev/null; then gcloud run services list --project="$PROJECT_ID" --format="table(metadata.name,status.url,metadata.labels.region)" 2>/dev/null else echo " None found or Cloud Run API not enabled" fi echo "" echo "Compute Engine Instances:" if gcloud compute instances list --project="$PROJECT_ID" --format="value(name)" --limit=1 &>/dev/null; then gcloud compute instances list --project="$PROJECT_ID" --format="table(name,zone,status,machineType.basename())" 2>/dev/null else echo " None found or Compute Engine API not enabled" fi echo "" echo "App Engine Services:" if gcloud app describe --project="$PROJECT_ID" &>/dev/null; then gcloud app services list --project="$PROJECT_ID" --format="table(id,versions)" 2>/dev/null || echo " None found" else echo " App Engine not configured" fi echo "" echo "=== DATABASE SERVICES ===" echo "Firestore Databases:" if gcloud firestore databases list --project="$PROJECT_ID" --format="table(name,type,locationId)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found databases above" else echo " None found or Firestore API not enabled" fi echo "" echo "Cloud SQL Instances:" if gcloud sql instances list --project="$PROJECT_ID" --format="table(name,databaseVersion,region,tier)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found instances above" else echo " None found or Cloud SQL API not enabled" fi echo "" echo "=== STORAGE SERVICES ===" echo "Cloud Storage Buckets:" if gsutil ls -p "$PROJECT_ID" 2>/dev/null; then echo " Found buckets above" else echo " None found or Cloud Storage API not enabled" fi echo "" echo "=== SECURITY & SECRETS ===" echo "Secret Manager Secrets:" if gcloud secrets list --project="$PROJECT_ID" --format="table(name,createTime)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found secrets above" else echo " None found or Secret Manager API not enabled" fi echo "" echo "IAM Service Accounts:" if gcloud iam service-accounts list --project="$PROJECT_ID" --format="table(email,displayName)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found service accounts above" else echo " None found" fi echo "" echo "=== NETWORKING ===" echo "VPC Networks:" if gcloud compute networks list --project="$PROJECT_ID" --format="table(name,subnet_mode,bgp_routing_mode)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found networks above" else echo " None found or using default network" fi echo "" echo "=== APIS & SERVICES ===" echo "Enabled APIs:" if gcloud services list --enabled --project="$PROJECT_ID" --format="table(name,title)" --limit=10 2>/dev/null; then echo " (Showing first 10 enabled APIs)" else echo " Unable to list APIs" fi echo "" echo "=== MONITORING & LOGGING ===" echo "Cloud Functions:" if gcloud functions list --project="$PROJECT_ID" --format="table(name,status,trigger.eventTrigger.eventType)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found functions above" else echo " None found or Cloud Functions API not enabled" fi echo "" echo "Pub/Sub Topics:" if gcloud pubsub topics list --project="$PROJECT_ID" --format="table(name)" 2>/dev/null | grep -v "Listed 0 items"; then echo " Found topics above" else echo " None found or Pub/Sub API not enabled" fi echo "" echo "Instance listing completed." exit 0 fi # Destroy resources with Terraform if [ "$DESTROY" = true ]; then echo "WARNING: This will destroy all cloud resources managed by Terraform!" echo "This includes Cloud Run services, Firestore database, storage buckets, and all data!" echo "This action cannot be undone." read -p "Are you sure you want to continue? (yes/no): " confirm if [ "$confirm" != "yes" ]; then echo "Destroy operation cancelled." exit 0 fi echo "Destroying cloud resources with Terraform..." cd "$(dirname "$0")/terraform" # Check if terraform.tfvars exists if [ ! -f terraform.tfvars ]; then echo "ERROR: terraform.tfvars not found. Cannot proceed with destroy." echo "Make sure you have provisioned resources first." exit 1 fi terraform init # Destroy everything through Terraform terraform destroy -auto-approve cd - > /dev/null echo "All resources destroyed successfully via Terraform." exit 0 fi # Deploy workflow if [ "$DEPLOY" = true ]; then echo "Starting deployment workflow..." # Step 1: Build and push Docker image if --build flag is provided if [ "$BUILD" = true ]; then echo "Building and pushing Docker image..." # Note: Docker authentication should be configured externally via: # gcloud auth configure-docker gcr.io # or by using service account key files # Build the image with timestamp tag TAG=$(date +%Y%m%d-%H%M%S) FULL_IMAGE_NAME="gcr.io/$PROJECT_ID/$IMAGE_NAME:$TAG" LATEST_IMAGE_NAME="gcr.io/$PROJECT_ID/$IMAGE_NAME:latest" echo "Building image: $FULL_IMAGE_NAME" docker build -t "$FULL_IMAGE_NAME" -t "$LATEST_IMAGE_NAME" -f Dockerfile . echo "Pushing images to Container Registry..." docker push "$FULL_IMAGE_NAME" docker push "$LATEST_IMAGE_NAME" echo "Image built and pushed successfully." fi # Step 2: Deploy to Cloud Run via Terraform echo "Deploying to Cloud Run via Terraform..." cd "$(dirname "$0")/terraform" # Check if terraform.tfvars exists, if not copy from example if [ ! -f terraform.tfvars ]; then echo "Creating terraform.tfvars from example..." cp terraform.tfvars.example terraform.tfvars # Replace project ID in tfvars file sed -i "s/your-gcp-project-id/$PROJECT_ID/g" terraform.tfvars echo "Please review and edit terraform.tfvars with your desired values" exit 0 fi # If we're building, ensure the latest image exists before deploying if [ "$BUILD" = true ]; then LATEST_IMAGE_NAME="gcr.io/$PROJECT_ID/$IMAGE_NAME:latest" # Check if image exists if ! docker manifest inspect "$LATEST_IMAGE_NAME" > /dev/null 2>&1; then echo "ERROR: Image $LATEST_IMAGE_NAME not found after build. Something went wrong." exit 1 fi fi echo "Applying Terraform configuration..." terraform init terraform apply -auto-approve # Get service URL from Terraform output SERVICE_URL=$(terraform output -raw cloud_run_url 2>/dev/null || echo "URL not available") # Get Qdrant VM information QDRANT_IP=$(terraform output -raw vector_db_vm_external_ip 2>/dev/null || echo "IP not available") QDRANT_ENDPOINT=$(terraform output -raw qdrant_http_endpoint 2>/dev/null || echo "Endpoint not available") cd - > /dev/null echo "Deployment completed successfully." echo "==================================" echo "Service URL: $SERVICE_URL" echo "Qdrant VM IP: $QDRANT_IP" echo "Qdrant HTTP Endpoint: $QDRANT_ENDPOINT" echo "" echo "Environment variables set in Cloud Run:" echo " QDRANT_HOST=$QDRANT_IP" echo " QDRANT_PORT=6333" echo "" fi echo "All operations completed."