Multi-Region GCP

Deploy highly available Ubuntu infrastructure across multiple GCP regions with global load balancing and auto-scaling

Expert Level
90-120 minutes
Enterprise Security
High Availability
RFS - Security Expert
RFS
eJPT, eCPPTv2, CRTP, ADCS CESP
Multi-Region Architecture Overview
Enterprise-grade infrastructure spanning 3 regions with global load balancing and auto-scaling

Global Load Balancer

Distributes traffic across regions with health checks and automatic failover

Auto Scaling

2-10 instances per region with CPU and load-based scaling

Security & Monitoring

Cloud Armor DDoS protection with comprehensive monitoring

Infrastructure Components

  • 3 Regional deployments (US Central, US East, Europe West)
  • Global VPC with regional subnets
  • Managed Instance Groups with auto-healing
  • Global HTTP(S) Load Balancer
  • Cloud Armor security policies

Enterprise Security Features

  • KMS-encrypted disks in all regions
  • DDoS protection with Cloud Armor
  • Regional traffic filtering
  • Comprehensive health monitoring
  • Automated security updates
Prerequisites & Requirements

Technical Requirements

  • Google Cloud SDK with Deployment Manager
  • Advanced YAML and Jinja2 knowledge
  • Understanding of load balancing concepts
  • Network architecture experience

GCP Requirements

  • GCP project with sufficient quotas
  • Multiple APIs enabled (Compute, KMS, etc.)
  • IAM permissions for global resources
  • Budget planning (~$200-500/month)
1
Create Multi-Region Deployment Template
Main deployment template defining global infrastructure across multiple regions

Create multi-region-deployment.yaml with the complete multi-region infrastructure:

# Multi-Region GCP Deployment with Global Load Balancer
# This template creates a highly available infrastructure across multiple regions

imports:
- path: templates/instance-template.jinja
- path: templates/health-check.jinja
- path: templates/backend-service.jinja

resources:
# Global VPC Network
- name: global-vpc
  type: compute.v1.network
  properties:
    autoCreateSubnetworks: false
    routingConfig:
      routingMode: GLOBAL

# Regional Subnets
- name: subnet-us-central1
  type: compute.v1.subnetwork
  properties:
    region: us-central1
    network: $(ref.global-vpc.selfLink)
    ipCidrRange: 10.1.0.0/16
    privateIpGoogleAccess: true
    secondaryIpRanges:
    - rangeName: pods
      ipCidrRange: 10.101.0.0/16
    - rangeName: services
      ipCidrRange: 10.201.0.0/16

- name: subnet-us-east1
  type: compute.v1.subnetwork
  properties:
    region: us-east1
    network: $(ref.global-vpc.selfLink)
    ipCidrRange: 10.2.0.0/16
    privateIpGoogleAccess: true
    secondaryIpRanges:
    - rangeName: pods
      ipCidrRange: 10.102.0.0/16
    - rangeName: services
      ipCidrRange: 10.202.0.0/16

- name: subnet-europe-west1
  type: compute.v1.subnetwork
  properties:
    region: europe-west1
    network: $(ref.global-vpc.selfLink)
    ipCidrRange: 10.3.0.0/16
    privateIpGoogleAccess: true
    secondaryIpRanges:
    - rangeName: pods
      ipCidrRange: 10.103.0.0/16
    - rangeName: services
      ipCidrRange: 10.203.0.0/16

# Global Firewall Rules
- name: allow-health-check
  type: compute.v1.firewall
  properties:
    network: $(ref.global-vpc.selfLink)
    allowed:
    - IPProtocol: TCP
      ports: ["80", "443", "8080"]
    sourceRanges:
    - 130.211.0.0/22
    - 35.191.0.0/16
    targetTags: ["web-server"]

- name: allow-ssh
  type: compute.v1.firewall
  properties:
    network: $(ref.global-vpc.selfLink)
    allowed:
    - IPProtocol: TCP
      ports: ["22"]
    sourceRanges: ["0.0.0.0/0"]
    targetTags: ["ssh-access"]

- name: allow-internal
  type: compute.v1.firewall
  properties:
    network: $(ref.global-vpc.selfLink)
    allowed:
    - IPProtocol: TCP
      ports: ["0-65535"]
    - IPProtocol: UDP
      ports: ["0-65535"]
    - IPProtocol: ICMP
    sourceRanges:
    - 10.1.0.0/16
    - 10.2.0.0/16
    - 10.3.0.0/16
    targetTags: ["internal-access"]

# Instance Templates for each region
- name: instance-template-us-central1
  type: templates/instance-template.jinja
  properties:
    region: us-central1
    zone: us-central1-a
    machineType: e2-standard-2
    network: $(ref.global-vpc.selfLink)
    subnet: $(ref.subnet-us-central1.selfLink)
    tags: ["web-server", "ssh-access", "internal-access", "us-central1"]

- name: instance-template-us-east1
  type: templates/instance-template.jinja
  properties:
    region: us-east1
    zone: us-east1-b
    machineType: e2-standard-2
    network: $(ref.global-vpc.selfLink)
    subnet: $(ref.subnet-us-east1.selfLink)
    tags: ["web-server", "ssh-access", "internal-access", "us-east1"]

- name: instance-template-europe-west1
  type: templates/instance-template.jinja
  properties:
    region: europe-west1
    zone: europe-west1-b
    machineType: e2-standard-2
    network: $(ref.global-vpc.selfLink)
    subnet: $(ref.subnet-europe-west1.selfLink)
    tags: ["web-server", "ssh-access", "internal-access", "europe-west1"]

# Managed Instance Groups
- name: mig-us-central1
  type: compute.v1.regionInstanceGroupManager
  properties:
    region: us-central1
    baseInstanceName: web-server-us-central1
    instanceTemplate: $(ref.instance-template-us-central1.selfLink)
    targetSize: 2
    namedPorts:
    - name: http
      port: 80
    - name: https
      port: 443
    autoHealingPolicies:
    - healthCheck: $(ref.health-check-http.selfLink)
      initialDelaySec: 300

- name: mig-us-east1
  type: compute.v1.regionInstanceGroupManager
  properties:
    region: us-east1
    baseInstanceName: web-server-us-east1
    instanceTemplate: $(ref.instance-template-us-east1.selfLink)
    targetSize: 2
    namedPorts:
    - name: http
      port: 80
    - name: https
      port: 443
    autoHealingPolicies:
    - healthCheck: $(ref.health-check-http.selfLink)
      initialDelaySec: 300

- name: mig-europe-west1
  type: compute.v1.regionInstanceGroupManager
  properties:
    region: europe-west1
    baseInstanceName: web-server-europe-west1
    instanceTemplate: $(ref.instance-template-europe-west1.selfLink)
    targetSize: 2
    namedPorts:
    - name: http
      port: 80
    - name: https
      port: 443
    autoHealingPolicies:
    - healthCheck: $(ref.health-check-http.selfLink)
      initialDelaySec: 300

# Auto Scalers
- name: autoscaler-us-central1
  type: compute.v1.regionAutoscaler
  properties:
    region: us-central1
    target: $(ref.mig-us-central1.selfLink)
    autoscalingPolicy:
      minNumReplicas: 2
      maxNumReplicas: 10
      cpuUtilization:
        utilizationTarget: 0.7
      loadBalancingUtilization:
        utilizationTarget: 0.8
      coolDownPeriodSec: 300

- name: autoscaler-us-east1
  type: compute.v1.regionAutoscaler
  properties:
    region: us-east1
    target: $(ref.mig-us-east1.selfLink)
    autoscalingPolicy:
      minNumReplicas: 2
      maxNumReplicas: 10
      cpuUtilization:
        utilizationTarget: 0.7
      loadBalancingUtilization:
        utilizationTarget: 0.8
      coolDownPeriodSec: 300

- name: autoscaler-europe-west1
  type: compute.v1.regionAutoscaler
  properties:
    region: europe-west1
    target: $(ref.mig-europe-west1.selfLink)
    autoscalingPolicy:
      minNumReplicas: 2
      maxNumReplicas: 10
      cpuUtilization:
        utilizationTarget: 0.7
      loadBalancingUtilization:
        utilizationTarget: 0.8
      coolDownPeriodSec: 300

# Health Checks
- name: health-check-http
  type: templates/health-check.jinja
  properties:
    protocol: HTTP
    port: 80
    requestPath: /health
    checkIntervalSec: 10
    timeoutSec: 5
    healthyThreshold: 2
    unhealthyThreshold: 3

- name: health-check-https
  type: templates/health-check.jinja
  properties:
    protocol: HTTPS
    port: 443
    requestPath: /health
    checkIntervalSec: 10
    timeoutSec: 5
    healthyThreshold: 2
    unhealthyThreshold: 3

# Backend Services
- name: backend-service-http
  type: templates/backend-service.jinja
  properties:
    protocol: HTTP
    port: 80
    healthCheck: $(ref.health-check-http.selfLink)
    backends:
    - group: $(ref.mig-us-central1.instanceGroup)
      balancingMode: UTILIZATION
      maxUtilization: 0.8
      capacityScaler: 1.0
    - group: $(ref.mig-us-east1.instanceGroup)
      balancingMode: UTILIZATION
      maxUtilization: 0.8
      capacityScaler: 1.0
    - group: $(ref.mig-europe-west1.instanceGroup)
      balancingMode: UTILIZATION
      maxUtilization: 0.8
      capacityScaler: 1.0

- name: backend-service-https
  type: templates/backend-service.jinja
  properties:
    protocol: HTTPS
    port: 443
    healthCheck: $(ref.health-check-https.selfLink)
    backends:
    - group: $(ref.mig-us-central1.instanceGroup)
      balancingMode: UTILIZATION
      maxUtilization: 0.8
      capacityScaler: 1.0
    - group: $(ref.mig-us-east1.instanceGroup)
      balancingMode: UTILIZATION
      maxUtilization: 0.8
      capacityScaler: 1.0
    - group: $(ref.mig-europe-west1.instanceGroup)
      balancingMode: UTILIZATION
      maxUtilization: 0.8
      capacityScaler: 1.0

# Global IP Address
- name: global-ip
  type: compute.v1.globalAddress
  properties:
    ipVersion: IPV4

# URL Map
- name: url-map
  type: compute.v1.urlMap
  properties:
    defaultService: $(ref.backend-service-http.selfLink)
    hostRules:
    - hosts: ["*"]
      pathMatcher: path-matcher-1
    pathMatchers:
    - name: path-matcher-1
      defaultService: $(ref.backend-service-http.selfLink)
      pathRules:
      - paths: ["/api/*"]
        service: $(ref.backend-service-http.selfLink)
      - paths: ["/static/*"]
        service: $(ref.backend-service-http.selfLink)

# HTTP(S) Proxy
- name: target-http-proxy
  type: compute.v1.targetHttpProxy
  properties:
    urlMap: $(ref.url-map.selfLink)

# Global Forwarding Rule
- name: global-forwarding-rule-http
  type: compute.v1.globalForwardingRule
  properties:
    IPAddress: $(ref.global-ip.address)
    IPProtocol: TCP
    portRange: 80
    target: $(ref.target-http-proxy.selfLink)

# Cloud Armor Security Policy
- name: security-policy
  type: compute.v1.securityPolicy
  properties:
    description: "Multi-region security policy with DDoS protection"
    rules:
    - priority: 1000
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges: ["*"]
      action: allow
      description: "Allow all traffic by default"
    - priority: 2000
      match:
        expr:
          expression: "origin.region_code == 'CN'"
      action: deny(403)
      description: "Block traffic from specific regions"
    adaptiveProtectionConfig:
      layer7DdosDefenseConfig:
        enable: true
        ruleVisibility: STANDARD

outputs:
- name: global-ip-address
  value: $(ref.global-ip.address)
- name: load-balancer-url
  value: http://$(ref.global-ip.address)
- name: regions-deployed
  value: "us-central1, us-east1, europe-west1"
- name: total-instances
  value: "6 (2 per region)"
- name: auto-scaling-enabled
  value: "2-10 instances per region"
2
Create Instance Template (Jinja2)
Reusable instance template for consistent deployment across regions

Create templates/instance-template.jinja:

# Instance Template Jinja2 Template
# File: templates/instance-template.jinja

resources:
- name: {{ env["name"] }}
  type: compute.v1.instanceTemplate
  properties:
    properties:
      machineType: {{ properties["machineType"] }}
      disks:
      - deviceName: boot
        type: PERSISTENT
        boot: true
        autoDelete: true
        initializeParams:
          sourceImage: projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts
          diskType: pd-ssd
          diskSizeGb: 20
          diskEncryptionKey:
            kmsKeyName: projects/{{ env["project"] }}/locations/{{ properties["region"] }}/keyRings/vm-encryption/cryptoKeys/vm-key
      networkInterfaces:
      - network: {{ properties["network"] }}
        subnetwork: {{ properties["subnet"] }}
        accessConfigs:
        - name: External NAT
          type: ONE_TO_ONE_NAT
      tags:
        items: {{ properties["tags"] }}
      serviceAccounts:
      - email: default
        scopes:
        - https://www.googleapis.com/auth/cloud-platform
      metadata:
        items:
        - key: startup-script
          value: |
            #!/bin/bash
            
            # Update system
            apt-get update && apt-get upgrade -y
            
            # Install required packages
            apt-get install -y \
              nginx \
              ufw \
              fail2ban \
              htop \
              curl \
              wget \
              git \
              vim \
              unattended-upgrades \
              google-cloud-ops-agent \
              certbot \
              python3-certbot-nginx
            
            # Configure UFW firewall
            ufw default deny incoming
            ufw default allow outgoing
            ufw allow ssh
            ufw allow 'Nginx Full'
            ufw allow 8080
            ufw --force enable
            
            # Configure Nginx with health check endpoint
            cat > /etc/nginx/sites-available/default << 'EOF'
            server {
                listen 80 default_server;
                listen [::]:80 default_server;
                server_name _;
                
                # Security headers
                add_header X-Frame-Options DENY;
                add_header X-Content-Type-Options nosniff;
                add_header X-XSS-Protection "1; mode=block";
                add_header X-Region "{{ properties['region'] }}";
                add_header X-Zone "{{ properties['zone'] }}";
                
                root /var/www/html;
                index index.html index.htm;
                
                # Health check endpoint
                location /health {
                    access_log off;
                    return 200 "healthy\n";
                    add_header Content-Type text/plain;
                }
                
                # Status endpoint with region info
                location /status {
                    return 200 '{"status":"ok","region":"{{ properties['region'] }}","zone":"{{ properties['zone'] }}","timestamp":"'$(date -Iseconds)'"}';
                    add_header Content-Type application/json;
                }
                
                location / {
                    try_files \$uri \$uri/ =404;
                }
                
                # Hide server version
                server_tokens off;
            }
            EOF
            
            # Create custom index page with region information
            cat > /var/www/html/index.html << 'EOF'
            <!DOCTYPE html>
            <html>
            <head>
                <title>Multi-Region Ubuntu Server</title>
                <meta charset="utf-8">
                <meta name="viewport" content="width=device-width, initial-scale=1">
                <style>
                    body { 
                        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
                        margin: 0; 
                        padding: 40px; 
                        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                        color: white;
                        min-height: 100vh;
                    }
                    .container { 
                        max-width: 800px; 
                        margin: 0 auto; 
                        background: rgba(255,255,255,0.1); 
                        padding: 40px; 
                        border-radius: 15px; 
                        backdrop-filter: blur(10px);
                        box-shadow: 0 8px 32px rgba(0,0,0,0.3);
                    }
                    .header { text-align: center; margin-bottom: 30px; }
                    .status { 
                        background: rgba(255,255,255,0.2); 
                        padding: 20px; 
                        border-radius: 10px; 
                        margin: 20px 0; 
                        border-left: 4px solid #4CAF50;
                    }
                    .info { 
                        background: rgba(255,255,255,0.1); 
                        padding: 15px; 
                        border-radius: 10px; 
                        margin: 10px 0; 
                    }
                    .region-badge {
                        display: inline-block;
                        background: #4CAF50;
                        color: white;
                        padding: 5px 15px;
                        border-radius: 20px;
                        font-size: 14px;
                        font-weight: bold;
                        margin: 5px;
                    }
                    .metric {
                        display: inline-block;
                        margin: 10px 20px 10px 0;
                    }
                    .metric-value {
                        font-size: 24px;
                        font-weight: bold;
                        color: #4CAF50;
                    }
                    .metric-label {
                        font-size: 12px;
                        opacity: 0.8;
                    }
                </style>
                <script>
                    function updateStatus() {
                        fetch('/status')
                            .then(response => response.json())
                            .then(data => {
                                document.getElementById('timestamp').textContent = new Date(data.timestamp).toLocaleString();
                                document.getElementById('region').textContent = data.region;
                                document.getElementById('zone').textContent = data.zone;
                            })
                            .catch(error => console.error('Error:', error));
                    }
                    
                    setInterval(updateStatus, 30000);
                    window.onload = updateStatus;
                </script>
            </head>
            <body>
                <div class="container">
                    <div class="header">
                        <h1>🌍 Multi-Region Ubuntu Server</h1>
                        <p>High Availability Infrastructure with Global Load Balancing</p>
                        <div class="region-badge">Region: {{ properties['region'] }}</div>
                        <div class="region-badge">Zone: {{ properties['zone'] }}</div>
                    </div>
                    
                    <div class="status">
                        <h3>✅ Server Status: Active</h3>
                        <div class="metric">
                            <div class="metric-value" id="region">{{ properties['region'] }}</div>
                            <div class="metric-label">Current Region</div>
                        </div>
                        <div class="metric">
                            <div class="metric-value" id="zone">{{ properties['zone'] }}</div>
                            <div class="metric-label">Availability Zone</div>
                        </div>
                        <div class="metric">
                            <div class="metric-value" id="timestamp">Loading...</div>
                            <div class="metric-label">Last Updated</div>
                        </div>
                    </div>
                    
                    <div class="info">
                        <h4>🔒 Security Features:</h4>
                        <ul>
                            <li>UFW Firewall configured</li>
                            <li>Fail2Ban intrusion prevention</li>
                            <li>SSH hardening applied</li>
                            <li>Google Cloud Ops Agent monitoring</li>
                            <li>Automatic security updates</li>
                            <li>Cloud Armor DDoS protection</li>
                        </ul>
                    </div>
                    
                    <div class="info">
                        <h4>🚀 Infrastructure Features:</h4>
                        <ul>
                            <li>Global Load Balancer distribution</li>
                            <li>Auto-scaling (2-10 instances per region)</li>
                            <li>Health check monitoring</li>
                            <li>Multi-region deployment</li>
                            <li>Automatic failover capability</li>
                            <li>SSL/TLS termination ready</li>
                        </ul>
                    </div>
                    
                    <div class="info">
                        <h4>📊 Endpoints:</h4>
                        <ul>
                            <li><a href="/health" style="color: #4CAF50;">/health</a> - Health check endpoint</li>
                            <li><a href="/status" style="color: #4CAF50;">/status</a> - Status and region info</li>
                        </ul>
                    </div>
                </div>
            </body>
            </html>
            EOF
            
            # Configure Fail2Ban
            cat > /etc/fail2ban/jail.local << 'EOF'
            [DEFAULT]
            bantime = 3600
            findtime = 600
            maxretry = 3
            
            [sshd]
            enabled = true
            port = ssh
            filter = sshd
            logpath = /var/log/auth.log
            maxretry = 3
            bantime = 3600
            
            [nginx-http-auth]
            enabled = true
            filter = nginx-http-auth
            logpath = /var/log/nginx/error.log
            maxretry = 5
            bantime = 3600
            EOF
            
            # Start and enable services
            systemctl restart nginx
            systemctl enable nginx
            systemctl enable fail2ban
            systemctl start fail2ban
            systemctl enable google-cloud-ops-agent
            systemctl start google-cloud-ops-agent
            
            # Configure automatic security updates
            echo 'Unattended-Upgrade::Automatic-Reboot "false";' >> /etc/apt/apt.conf.d/50unattended-upgrades
            systemctl enable unattended-upgrades
            
            # Log deployment completion
            echo "Multi-region instance deployment completed at $(date)" >> /var/log/deployment.log
            echo "Region: {{ properties['region'] }}, Zone: {{ properties['zone'] }}" >> /var/log/deployment.log
3
Create Health Check Template
Health check configuration for load balancer backend services

Create templates/health-check.jinja:

# Health Check Jinja2 Template
# File: templates/health-check.jinja

resources:
- name: {{ env["name"] }}
  type: compute.v1.healthCheck
  properties:
    type: {{ properties["protocol"] }}
    {{ properties["protocol"].lower() }}HealthCheck:
      port: {{ properties["port"] }}
      requestPath: {{ properties["requestPath"] }}
    checkIntervalSec: {{ properties["checkIntervalSec"] }}
    timeoutSec: {{ properties["timeoutSec"] }}
    healthyThreshold: {{ properties["healthyThreshold"] }}
    unhealthyThreshold: {{ properties["unhealthyThreshold"] }}
    description: "Health check for {{ properties['protocol'] }} on port {{ properties['port'] }}"
    logConfig:
      enable: true
4
Create Backend Service Template
Backend service configuration for global load balancer

Create templates/backend-service.jinja:

# Backend Service Jinja2 Template
# File: templates/backend-service.jinja

resources:
- name: {{ env["name"] }}
  type: compute.v1.backendService
  properties:
    protocol: {{ properties["protocol"] }}
    port: {{ properties["port"] }}
    portName: {{ properties["protocol"].lower() }}
    healthChecks:
    - {{ properties["healthCheck"] }}
    backends: {{ properties["backends"] }}
    loadBalancingScheme: EXTERNAL
    sessionAffinity: NONE
    timeoutSec: 30
    connectionDraining:
      drainingTimeoutSec: 300
    logConfig:
      enable: true
      sampleRate: 1.0
    securityPolicy: $(ref.security-policy.selfLink)
    description: "Backend service for {{ properties['protocol'] }} traffic"
5
Deploy Multi-Region Infrastructure
Execute the deployment across all regions with monitoring
# Multi-Region GCP Deployment Commands

# 1. Set up environment variables
export PROJECT_ID="your-project-id"
export DEPLOYMENT_NAME="multi-region-infrastructure"

# 2. Enable required APIs
gcloud services enable compute.googleapis.com
gcloud services enable deploymentmanager.googleapis.com
gcloud services enable cloudkms.googleapis.com
gcloud services enable logging.googleapis.com
gcloud services enable monitoring.googleapis.com

# 3. Create KMS keys for each region
regions=("us-central1" "us-east1" "europe-west1")
for region in "${regions[@]}"; do
  gcloud kms keyrings create vm-encryption --location=$region
  gcloud kms keys create vm-key --location=$region --keyring=vm-encryption --purpose=encryption
done

# 4. Create the deployment directory structure
mkdir -p multi-region-deployment/templates
cd multi-region-deployment

# 5. Create all template files (instance-template.jinja, health-check.jinja, backend-service.jinja)
# Copy the templates provided in this guide

# 6. Deploy the multi-region infrastructure
gcloud deployment-manager deployments create $DEPLOYMENT_NAME \
    --config=multi-region-deployment.yaml \
    --description="Multi-region Ubuntu infrastructure with global load balancer"

# 7. Monitor deployment progress
gcloud deployment-manager deployments describe $DEPLOYMENT_NAME

# 8. Get the global IP address
GLOBAL_IP=$(gcloud compute addresses describe global-ip --global --format="value(address)")
echo "Global Load Balancer IP: $GLOBAL_IP"

# 9. Test the deployment
curl -H "Host: your-domain.com" http://$GLOBAL_IP/health
curl -H "Host: your-domain.com" http://$GLOBAL_IP/status

# 10. Set up DNS (replace with your domain)
# gcloud dns record-sets transaction start --zone=your-zone
# gcloud dns record-sets transaction add $GLOBAL_IP --name=your-domain.com. --ttl=300 --type=A --zone=your-zone
# gcloud dns record-sets transaction execute --zone=your-zone

Deployment Timeline:

  • • Infrastructure provisioning: ~15-20 minutes
  • • Instance group creation: ~10-15 minutes
  • • Load balancer configuration: ~10-15 minutes
  • • Health check stabilization: ~15-20 minutes
  • • Total deployment time: ~50-70 minutes
6
Monitor & Manage Multi-Region Deployment
Comprehensive monitoring and management commands
# Multi-Region Monitoring and Management Commands

# Check instance groups status across all regions
regions=("us-central1" "us-east1" "europe-west1")
for region in "${regions[@]}"; do
  echo "=== Region: $region ==="
  gcloud compute instance-groups managed describe mig-$region --region=$region
  echo ""
done

# Check auto-scaler status
for region in "${regions[@]}"; do
  echo "=== Auto-scaler status for $region ==="
  gcloud compute instance-groups managed describe mig-$region --region=$region --format="value(status.autoscaler)"
  echo ""
done

# Monitor load balancer backend health
gcloud compute backend-services get-health backend-service-http --global

# Check global forwarding rule status
gcloud compute forwarding-rules describe global-forwarding-rule-http --global

# Monitor traffic distribution
gcloud logging read "resource.type=http_load_balancer" --limit=50 --format=json

# Scale instance groups manually (if needed)
gcloud compute instance-groups managed resize mig-us-central1 --size=5 --region=us-central1

# Update instance template (rolling update)
gcloud compute instance-groups managed rolling-action start-update mig-us-central1 \
    --version=template=instance-template-us-central1-v2 \
    --region=us-central1

# Check SSL certificate status (if configured)
gcloud compute ssl-certificates list

# Monitor Cloud Armor security policy
gcloud compute security-policies describe security-policy

# View metrics in Cloud Monitoring
gcloud alpha monitoring dashboards list
Troubleshooting Multi-Region Issues
# Troubleshooting Multi-Region Deployment

# 1. Check deployment status and errors
gcloud deployment-manager deployments describe $DEPLOYMENT_NAME --format="value(operation.error)"

# 2. Verify network connectivity between regions
for region in "${regions[@]}"; do
  echo "Testing connectivity from $region"
  gcloud compute ssh --zone=$region-a $(gcloud compute instances list --filter="zone:$region-a" --format="value(name)" | head -1) --command="ping -c 3 10.1.1.1"
done

# 3. Check health check failures
gcloud compute operations list --filter="operationType:compute.healthChecks.insert"

# 4. Debug load balancer issues
gcloud compute url-maps validate --url-map=url-map

# 5. Check firewall rules
gcloud compute firewall-rules list --filter="network:global-vpc"

# 6. Monitor instance startup scripts
gcloud compute instances get-serial-port-output INSTANCE_NAME --zone=ZONE

# 7. Check Cloud Armor logs
gcloud logging read "resource.type=http_load_balancer AND jsonPayload.enforcedSecurityPolicy.name=security-policy"

# 8. Verify SSL certificate provisioning
gcloud compute ssl-certificates describe CERT_NAME --global

# 9. Test regional failover
# Temporarily stop instances in one region to test failover
gcloud compute instance-groups managed resize mig-us-central1 --size=0 --region=us-central1

# 10. Check quota limits
gcloud compute project-info describe --format="value(quotas[].limit,quotas[].metric,quotas[].usage)"
Performance & Cost Optimization

Performance Optimization

  • Use SSD persistent disks for better I/O
  • Configure CPU and memory-based auto-scaling
  • Implement connection draining for updates
  • Use preemptible instances for cost savings

Cost Management

  • Set up budget alerts and quotas
  • Use committed use discounts
  • Monitor and optimize instance sizes
  • Implement proper resource tagging
Frequently Asked Questions

What's the estimated cost for this multi-region deployment?

With 6 instances (2 per region) running e2-standard-2, expect $200-500/month depending on traffic and data transfer. Use sustained use discounts and committed use contracts for savings.

How does failover work between regions?

The global load balancer automatically routes traffic away from unhealthy regions based on health checks. Failover typically occurs within 30-60 seconds of detecting issues.

Can I add more regions later?

Yes! You can extend the deployment template to include additional regions. Update the template with new subnets, instance groups, and backend service configurations.

How do I handle data consistency across regions?

This guide focuses on stateless applications. For stateful applications, consider Cloud SQL with read replicas, Cloud Spanner for global consistency, or implement application-level data synchronization.

Ready for Enterprise-Grade Multi-Region Deployment?

Get the complete multi-region deployment package with all templates, monitoring configurations, and enterprise security hardening.