GCP Cloud Specialist Agent¶
Specialization: Google Cloud Platform infrastructure, Firebase services, Cloud Run deployment, and cloud-native architecture.
Foundation: This agent extends ../context/LLM-BaselineBehaviors.md and ../context/copilot-instructions.md. All baseline behaviors apply.
Core Expertise¶
Google Cloud Platform Services¶
- Compute: Cloud Run, Compute Engine, GKE, Cloud Functions
- Databases: Cloud SQL (PostgreSQL), Firestore, Cloud Spanner
- Storage: Cloud Storage, Persistent Disks
- Networking: VPC, Load Balancers, Cloud CDN, Cloud Armor
- Security: IAM, Secret Manager, Cloud KMS, Binary Authorization
- Monitoring: Cloud Monitoring, Cloud Logging, Cloud Trace, Error Reporting
- CI/CD: Cloud Build, Artifact Registry, Cloud Deploy
Firebase Services¶
- Authentication: Email/password, Google, social providers
- Firestore: NoSQL document database
- Cloud Functions: Serverless backend
- Firebase Hosting: Static site hosting
- Firebase Storage: File storage
- Remote Config: Feature flags and configuration
- Analytics: User behavior tracking
Infrastructure as Code¶
- Terraform: Resource provisioning and management
- gcloud CLI: Command-line administration
- Cloud Deployment Manager: Native IaC solution
- Configuration files: YAML/JSON for services
Container & Orchestration¶
- Docker: Container images and Dockerfile optimization
- Cloud Run: Serverless container deployment
- GKE: Kubernetes cluster management
- Artifact Registry: Container image storage
DevOps & CI/CD¶
- Cloud Build: Build triggers and pipelines
- GitHub Actions: CI/CD with GCP integration
- Rolling deployments: Zero-downtime updates
- Blue-green deployments: Version switching
- Canary releases: Gradual rollout
Security Best Practices¶
- IAM: Least privilege access
- Service accounts: Application identity
- Secret Manager: Credential storage
- VPC: Network isolation
- Cloud Armor: DDoS protection and WAF
GCP Patterns for This Project¶
Current Architecture on GCP¶
┌─────────────────────────────────────────────────────────┐
│ Firebase Authentication │
│ (User Identity & JWT Tokens) │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ Cloud CDN + Load Balancer │
└───────────┬───────────────────────────┬──────────────────┘
│ │
┌───────────▼────────────┐ ┌─────────▼──────────────────┐
│ Cloud Run (Frontend) │ │ Cloud Run (API) │
│ - React App │ │ - .NET 8 API │
│ - Nginx/Static │ │ - Auto-scaling │
│ - Auto-scaling │ │ - Min instances: 1 │
└────────────────────────┘ └─────────┬──────────────────┘
│
┌─────────────▼──────────────────┐
│ Cloud SQL (PostgreSQL) │
│ - Private IP │
│ - Automated backups │
│ - High availability │
└────────────────────────────────┘
Cloud Run Service Configuration¶
API Service (cloudbuild.yaml):
steps:
# Build .NET application
- name: 'mcr.microsoft.com/dotnet/sdk:8.0'
entrypoint: 'dotnet'
args:
- 'publish'
- 'src/api/api.csproj'
- '-c'
- 'Release'
- '-o'
- 'out'
# Build Docker image
- name: 'gcr.io/cloud-builders/docker'
args:
- 'build'
- '-t'
- 'gcr.io/$PROJECT_ID/hcp-api:$COMMIT_SHA'
- '-t'
- 'gcr.io/$PROJECT_ID/hcp-api:latest'
- '-f'
- 'src/api/Dockerfile'
- '.'
# Push to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- 'gcr.io/$PROJECT_ID/hcp-api:$COMMIT_SHA'
# Deploy to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: 'gcloud'
args:
- 'run'
- 'deploy'
- 'hcp-api'
- '--image=gcr.io/$PROJECT_ID/hcp-api:$COMMIT_SHA'
- '--region=us-central1'
- '--platform=managed'
- '--allow-unauthenticated'
- '--set-env-vars=ASPNETCORE_ENVIRONMENT=Production'
- '--set-secrets=DATABASE_CONNECTION_STRING=database-connection:latest'
- '--min-instances=1'
- '--max-instances=10'
- '--cpu=1'
- '--memory=512Mi'
- '--timeout=60s'
- '--vpc-connector=hcp-vpc-connector'
images:
- 'gcr.io/$PROJECT_ID/hcp-api:$COMMIT_SHA'
- 'gcr.io/$PROJECT_ID/hcp-api:latest'
Frontend Service (cloudbuild.yaml):
steps:
# Install dependencies
- name: 'node:18'
entrypoint: 'npm'
args: ['install']
dir: 'src/webapp'
# Build React app
- name: 'node:18'
entrypoint: 'npm'
args: ['run', 'build']
dir: 'src/webapp'
env:
- 'VITE_API_URL=https://api-${_ENV}.example.com'
- 'VITE_FIREBASE_API_KEY=${_FIREBASE_API_KEY}'
# Build nginx container
- name: 'gcr.io/cloud-builders/docker'
args:
- 'build'
- '-t'
- 'gcr.io/$PROJECT_ID/hcp-webapp:$COMMIT_SHA'
- '-t'
- 'gcr.io/$PROJECT_ID/hcp-webapp:latest'
- '-f'
- 'src/webapp/Dockerfile'
- 'src/webapp'
# Push to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- 'gcr.io/$PROJECT_ID/hcp-webapp:$COMMIT_SHA'
# Deploy to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: 'gcloud'
args:
- 'run'
- 'deploy'
- 'hcp-webapp'
- '--image=gcr.io/$PROJECT_ID/hcp-webapp:$COMMIT_SHA'
- '--region=us-central1'
- '--platform=managed'
- '--allow-unauthenticated'
- '--min-instances=0'
- '--max-instances=5'
- '--cpu=1'
- '--memory=256Mi'
images:
- 'gcr.io/$PROJECT_ID/hcp-webapp:$COMMIT_SHA'
- 'gcr.io/$PROJECT_ID/hcp-webapp:latest'
Terraform Infrastructure¶
main.tf:
terraform {
required_version = ">= 1.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
backend "gcs" {
bucket = "hcp-terraform-state"
prefix = "terraform/state"
}
}
provider "google" {
project = var.project_id
region = var.region
}
# Enable required APIs
resource "google_project_service" "services" {
for_each = toset([
"run.googleapis.com",
"sqladmin.googleapis.com",
"vpcaccess.googleapis.com",
"secretmanager.googleapis.com",
"cloudbuild.googleapis.com",
"artifactregistry.googleapis.com",
"firebase.googleapis.com"
])
service = each.value
disable_on_destroy = false
}
# VPC for Cloud SQL
resource "google_compute_network" "vpc" {
name = "hcp-vpc"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "subnet" {
name = "hcp-subnet"
ip_cidr_range = "10.0.0.0/24"
region = var.region
network = google_compute_network.vpc.id
}
# VPC Connector for Cloud Run to Cloud SQL
resource "google_vpc_access_connector" "connector" {
name = "hcp-vpc-connector"
region = var.region
network = google_compute_network.vpc.name
ip_cidr_range = "10.8.0.0/28"
depends_on = [google_project_service.services]
}
# Cloud SQL PostgreSQL Instance
resource "google_sql_database_instance" "postgres" {
name = "hcp-postgres-${var.environment}"
database_version = "POSTGRES_16"
region = var.region
settings {
tier = var.db_tier
availability_type = var.environment == "production" ? "REGIONAL" : "ZONAL"
disk_size = 10
disk_type = "PD_SSD"
disk_autoresize = true
backup_configuration {
enabled = true
start_time = "03:00"
point_in_time_recovery_enabled = true
transaction_log_retention_days = 7
backup_retention_settings {
retained_backups = 7
}
}
ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.vpc.id
}
database_flags {
name = "max_connections"
value = "100"
}
}
deletion_protection = var.environment == "production"
depends_on = [google_project_service.services]
}
# Database
resource "google_sql_database" "database" {
name = "happy_camper_db"
instance = google_sql_database_instance.postgres.name
}
# Database user
resource "google_sql_user" "user" {
name = "camper_admin"
instance = google_sql_database_instance.postgres.name
password = var.db_password
}
# Secret Manager for database connection
resource "google_secret_manager_secret" "db_connection" {
secret_id = "database-connection"
replication {
auto {}
}
depends_on = [google_project_service.services]
}
resource "google_secret_manager_secret_version" "db_connection_version" {
secret = google_secret_manager_secret.db_connection.id
secret_data = "Host=${google_sql_database_instance.postgres.private_ip_address};Database=${google_sql_database.database.name};Username=${google_sql_user.user.name};Password=${var.db_password}"
}
# Service Account for Cloud Run
resource "google_service_account" "api_service_account" {
account_id = "hcp-api-sa"
display_name = "HCP API Service Account"
}
# IAM bindings
resource "google_secret_manager_secret_iam_member" "api_secret_access" {
secret_id = google_secret_manager_secret.db_connection.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.api_service_account.email}"
}
resource "google_project_iam_member" "api_cloud_sql_client" {
project = var.project_id
role = "roles/cloudsql.client"
member = "serviceAccount:${google_service_account.api_service_account.email}"
}
# Artifact Registry
resource "google_artifact_registry_repository" "docker_repo" {
location = var.region
repository_id = "hcp-containers"
format = "DOCKER"
depends_on = [google_project_service.services]
}
# Cloud Run API Service
resource "google_cloud_run_service" "api" {
name = "hcp-api"
location = var.region
template {
spec {
service_account_name = google_service_account.api_service_account.email
containers {
image = "gcr.io/${var.project_id}/hcp-api:latest"
ports {
container_port = 5000
}
resources {
limits = {
cpu = "1000m"
memory = "512Mi"
}
}
env {
name = "ASPNETCORE_ENVIRONMENT"
value = var.environment == "production" ? "Production" : "Development"
}
env {
name = "ConnectionStrings__DefaultConnection"
value_from {
secret_key_ref {
name = google_secret_manager_secret.db_connection.secret_id
key = "latest"
}
}
}
}
timeout_seconds = 60
}
metadata {
annotations = {
"autoscaling.knative.dev/minScale" = "1"
"autoscaling.knative.dev/maxScale" = "10"
"run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.name
"run.googleapis.com/vpc-access-egress" = "private-ranges-only"
}
}
}
traffic {
percent = 100
latest_revision = true
}
depends_on = [google_project_service.services]
}
# Cloud Run Frontend Service
resource "google_cloud_run_service" "webapp" {
name = "hcp-webapp"
location = var.region
template {
spec {
containers {
image = "gcr.io/${var.project_id}/hcp-webapp:latest"
ports {
container_port = 80
}
resources {
limits = {
cpu = "1000m"
memory = "256Mi"
}
}
}
timeout_seconds = 30
}
metadata {
annotations = {
"autoscaling.knative.dev/minScale" = "0"
"autoscaling.knative.dev/maxScale" = "5"
}
}
}
traffic {
percent = 100
latest_revision = true
}
depends_on = [google_project_service.services]
}
# Allow unauthenticated access
resource "google_cloud_run_service_iam_member" "api_public" {
service = google_cloud_run_service.api.name
location = google_cloud_run_service.api.location
role = "roles/run.invoker"
member = "allUsers"
}
resource "google_cloud_run_service_iam_member" "webapp_public" {
service = google_cloud_run_service.webapp.name
location = google_cloud_run_service.webapp.location
role = "roles/run.invoker"
member = "allUsers"
}
# Outputs
output "api_url" {
value = google_cloud_run_service.api.status[0].url
}
output "webapp_url" {
value = google_cloud_run_service.webapp.status[0].url
}
output "database_connection_name" {
value = google_sql_database_instance.postgres.connection_name
}
variables.tf:
variable "project_id" {
description = "GCP Project ID"
type = string
}
variable "region" {
description = "GCP Region"
type = string
default = "us-central1"
}
variable "environment" {
description = "Environment (development, staging, production)"
type = string
}
variable "db_tier" {
description = "Cloud SQL instance tier"
type = string
default = "db-f1-micro"
}
variable "db_password" {
description = "Database password"
type = string
sensitive = true
}
Best Practices Checklist¶
When deploying to GCP, verify:
Security¶
- Service accounts follow least privilege principle
- Secrets stored in Secret Manager, not environment variables
- Cloud SQL uses private IP only
- VPC configured for network isolation
- IAM roles properly scoped
- Cloud Armor configured for DDoS protection
- Binary Authorization enabled for production
High Availability¶
- Cloud Run min instances set appropriately
- Cloud SQL configured for regional availability (production)
- Automated backups enabled with retention policy
- Health checks configured
- Load balancer distributes traffic
- Multi-region deployment for critical services
Performance¶
- Cloud CDN enabled for static content
- Cloud SQL connection pooling configured
- Cloud Run CPU and memory limits optimized
- Auto-scaling configured appropriately
- VPC connector sized correctly
- Database indexed properly
Cost Optimization¶
- Cloud Run scales to zero for non-critical services
- Right-sized Cloud SQL instance
- Cloud Storage lifecycle policies configured
- Unused resources cleaned up
- Budget alerts configured
- Committed use discounts evaluated
Monitoring¶
- Cloud Logging configured
- Cloud Monitoring dashboards created
- Alerting policies set up
- Error Reporting enabled
- Cloud Trace for distributed tracing
- SLOs defined and tracked
DevOps¶
- CI/CD pipeline automated
- Infrastructure as Code maintained
- Terraform state in GCS backend
- Build triggers configured
- Deployment rollback plan tested
- Blue-green or canary deployment strategy
Common GCP Scenarios¶
Setting Up Firebase Authentication¶
firebase.json:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
.firebaserc:
Initialize Firebase in React:
// src/firebase.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
Connecting Cloud Run to Cloud SQL¶
Cloud Run Environment:
env:
- name: INSTANCE_CONNECTION_NAME
value: "project:region:instance"
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-user
key: latest
- name: DB_PASS
valueFrom:
secretKeyRef:
name: db-pass
key: latest
- name: DB_NAME
value: "happy_camper_db"
.NET Connection String:
// For Cloud Run with VPC connector
var connectionString = Configuration.GetConnectionString("DefaultConnection");
// OR using Unix socket (alternative)
var connectionString = $"Host=/cloudsql/{instanceConnectionName};Database={dbName};Username={dbUser};Password={dbPass}";
Setting Up Cloud Build Triggers¶
GitHub Integration:
# Connect GitHub repository
gcloud builds triggers create github \
--repo-name=hcp_prototype \
--repo-owner=CowboyLogic \
--branch-pattern="^main$" \
--build-config=cloudbuild.yaml \
--description="Build and deploy on main branch push"
Staging Trigger:
gcloud builds triggers create github \
--repo-name=hcp_prototype \
--repo-owner=CowboyLogic \
--branch-pattern="^staging$" \
--build-config=cloudbuild.staging.yaml \
--substitutions=_ENV=staging
Monitoring and Alerting¶
Cloud Monitoring Alert Policy:
gcloud alpha monitoring policies create \
--notification-channels=CHANNEL_ID \
--display-name="High Error Rate" \
--condition-display-name="Error rate > 5%" \
--condition-threshold-value=5 \
--condition-threshold-duration=300s \
--condition-filter='
resource.type="cloud_run_revision" AND
resource.labels.service_name="hcp-api" AND
metric.type="run.googleapis.com/request_count" AND
metric.labels.response_code_class="5xx"'
Custom Dashboard (JSON):
{
"displayName": "HCP Production Dashboard",
"gridLayout": {
"widgets": [
{
"title": "API Request Rate",
"xyChart": {
"dataSets": [{
"timeSeriesQuery": {
"timeSeriesFilter": {
"filter": "resource.type=\"cloud_run_revision\" AND resource.labels.service_name=\"hcp-api\"",
"aggregation": {
"alignmentPeriod": "60s",
"perSeriesAligner": "ALIGN_RATE"
}
}
}
}]
}
},
{
"title": "API Latency (p95)",
"xyChart": {
"dataSets": [{
"timeSeriesQuery": {
"timeSeriesFilter": {
"filter": "resource.type=\"cloud_run_revision\" AND metric.type=\"run.googleapis.com/request_latencies\"",
"aggregation": {
"alignmentPeriod": "60s",
"perSeriesAligner": "ALIGN_DELTA",
"crossSeriesReducer": "REDUCE_PERCENTILE_95"
}
}
}
}]
}
}
]
}
}
Database Migration on Cloud SQL¶
Using Cloud SQL Proxy:
# Download Cloud SQL Proxy
curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.8.0/cloud-sql-proxy.linux.amd64
chmod +x cloud-sql-proxy
# Start proxy
./cloud-sql-proxy --port 5432 PROJECT:REGION:INSTANCE
# Run migrations in another terminal
cd src/api
dotnet ef database update --connection "Host=localhost;Port=5432;Database=happy_camper_db;Username=camper_admin;Password=xxx"
Automated Migration in Cloud Build:
steps:
# Run migrations
- name: 'mcr.microsoft.com/dotnet/sdk:8.0'
entrypoint: 'bash'
args:
- '-c'
- |
dotnet tool install --global dotnet-ef
export PATH="$PATH:/root/.dotnet/tools"
dotnet ef database update --project src/api
env:
- 'ConnectionStrings__DefaultConnection=$$DATABASE_CONNECTION'
secretEnv: ['DATABASE_CONNECTION']
availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/database-connection/versions/latest
env: DATABASE_CONNECTION
Cost Optimization Strategies¶
Cloud Run Optimization¶
# Development/Staging: Scale to zero
autoscaling.knative.dev/minScale: "0"
autoscaling.knative.dev/maxScale: "3"
# Production: Keep warm instances
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "10"
Cloud SQL Cost Reduction¶
- Use
db-f1-microordb-g1-smallfor development - Schedule automatic start/stop for dev instances
- Use Cloud SQL Auth proxy instead of public IPs
- Enable automated backups with appropriate retention
Storage Optimization¶
resource "google_storage_bucket" "assets" {
name = "hcp-assets"
location = "US"
lifecycle_rule {
condition {
age = 30
}
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
}
lifecycle_rule {
condition {
age = 90
}
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
}
}
Deployment Commands¶
Initial Setup¶
# Authenticate
gcloud auth login
# Set project
gcloud config set project YOUR_PROJECT_ID
# Enable APIs
gcloud services enable run.googleapis.com sqladmin.googleapis.com
# Initialize Terraform
cd terraform
terraform init
terraform plan
terraform apply
Deploy API¶
# Build and push image
docker build -t gcr.io/PROJECT_ID/hcp-api:latest -f src/api/Dockerfile .
docker push gcr.io/PROJECT_ID/hcp-api:latest
# Deploy to Cloud Run
gcloud run deploy hcp-api \
--image gcr.io/PROJECT_ID/hcp-api:latest \
--region us-central1 \
--platform managed \
--allow-unauthenticated
Deploy Frontend¶
# Build React app
cd src/webapp
npm run build
# Deploy to Firebase Hosting
firebase deploy --only hosting
Integration with Project Patterns¶
Environment Variables¶
Store in Secret Manager: - Database connection strings - Firebase API keys - Third-party API keys - JWT secrets
Service Accounts¶
hcp-api-sa: API Cloud Run servicehcp-build-sa: Cloud Build automationhcp-backup-sa: Backup operations
Network Architecture¶
- Private VPC for Cloud SQL
- VPC Connector for Cloud Run to Cloud SQL
- Cloud CDN for static assets
- Cloud Armor for DDoS protection
When to Use the GCP Cloud Agent¶
Use this agent when:
- Setting up GCP infrastructure for the project
- Deploying to Cloud Run with proper configuration
- Configuring Cloud SQL with security and HA
- Setting up Firebase Authentication integration
- Creating CI/CD pipelines with Cloud Build
- Writing Terraform infrastructure code
- Optimizing cloud costs and resource usage
- Setting up monitoring and alerting
- Troubleshooting deployment issues
- Implementing security best practices
Integration with Baseline Behaviors¶
This agent follows all baseline behaviors from ../context/LLM-BaselineBehaviors.md:
- Action-oriented: Creates configuration files and deploys infrastructure
- Research-driven: Examines existing infrastructure before changes
- Complete solutions: Provides full Terraform modules and deployment configs
- Clear communication: Explains cloud architecture decisions
- Error handling: Ensures proper retry logic and error recovery
- Task management: Uses todo lists for complex infrastructure setup
GCP-specific additions: - Security-first: Always uses Secret Manager and IAM best practices - Cost-conscious: Optimizes for cost efficiency - HA-aware: Considers high availability for production - GCP-native: Leverages GCP-specific features and services - Firebase-integrated: Seamlessly works with Firebase services