Skip to content

Instantly share code, notes, and snippets.

@mikesparr
Last active May 16, 2025 13:08
Show Gist options
  • Save mikesparr/db2f5cb7d7980cf4970c7d5c8b2194e5 to your computer and use it in GitHub Desktop.
Save mikesparr/db2f5cb7d7980cf4970c7d5c8b2194e5 to your computer and use it in GitHub Desktop.

Revisions

  1. mikesparr revised this gist Aug 20, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gcp-global-lb-multi-region-cr-ce.sh
    Original file line number Diff line number Diff line change
    @@ -143,7 +143,7 @@ gcloud compute url-maps set-default-service $APP_NAME-url-map \


    ##########################################################
    # Compute Engine Runtime
    # (OPTIONAL ALTERNATIVE) Compute Engine Runtime
    ##########################################################
    export INSTANCE_TEMPLATE_NAME="$APP_NAME-template"
    export INSTANCE_GROUP_NAME="$APP_NAME-rmig"
  2. mikesparr revised this gist Aug 18, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gcp-global-lb-multi-region-cr-ce.sh
    Original file line number Diff line number Diff line change
    @@ -200,7 +200,7 @@ gcloud compute health-checks create http $HEALTH_CHECK_NAME \
    gcloud compute backend-services create $MIG_BACKEND_NAME \
    --load-balancing-scheme=EXTERNAL \
    --protocol=HTTP \
    --port-name=http \
    --port-name=$APP_NAME \
    --health-checks=$HEALTH_CHECK_NAME \
    --global

  3. mikesparr revised this gist Aug 18, 2023. 1 changed file with 0 additions and 4 deletions.
    4 changes: 0 additions & 4 deletions gcp-global-lb-multi-region-cr-ce.sh
    Original file line number Diff line number Diff line change
    @@ -207,14 +207,10 @@ gcloud compute backend-services create $MIG_BACKEND_NAME \
    # add instance groups to MIG backend for each region
    gcloud compute backend-services add-backend $MIG_BACKEND_NAME \
    --global \
    --balancing-mode=UTILIZATION \
    --max-utilization="80" \
    --instance-group=$INSTANCE_GROUP_NAME \
    --instance-group-region=$APP_REGION_1
    gcloud compute backend-services add-backend $MIG_BACKEND_NAME \
    --global \
    --balancing-mode=UTILIZATION \
    --max-utilization="80" \
    --instance-group=$INSTANCE_GROUP_NAME \
    --instance-group-region=$APP_REGION_2

  4. mikesparr revised this gist Aug 18, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gcp-global-lb-multi-region-cr-ce.sh
    Original file line number Diff line number Diff line change
    @@ -182,7 +182,7 @@ gcloud compute firewall-rules create fw-allow-health-check \
    --direction=ingress \
    --source-ranges=130.211.0.0/22,35.191.0.0/16 \
    --target-tags=allow-health-check \
    --rules=tcp:80
    --rules=tcp
    gcloud compute firewall-rules create fw-allow-ssh \
    --network=default \
    --action=allow \
  5. mikesparr revised this gist Aug 17, 2023. 1 changed file with 14 additions and 2 deletions.
    16 changes: 14 additions & 2 deletions gcp-global-lb-multi-region-cr-ce.sh
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    # - https://cloud.google.com/run/docs/multiple-regions
    # - https://cloud.google.com/compute/docs/instance-groups/distributing-instances-with-regional-instance-groups
    # - https://cloud.google.com/load-balancing/docs/https/setup-global-ext-https-compute
    # - https://cloud.google.com/load-balancing/docs/backend-service#named_ports
    #####################################################################

    export PROJECT_ID=$(gcloud config get-value project)
    @@ -168,10 +169,10 @@ gcloud compute instance-groups managed create $INSTANCE_GROUP_NAME \

    # add named port (internal)
    gcloud compute instance-groups set-named-ports $INSTANCE_GROUP_NAME \
    --named-ports http:80 \
    --named-ports http:80,$APP_NAME:8080 \
    --region $APP_REGION_1
    gcloud compute instance-groups set-named-ports $INSTANCE_GROUP_NAME \
    --named-ports http:80 \
    --named-ports http:80,$APP_NAME:8080 \
    --region $APP_REGION_2

    # enable firewall rules
    @@ -182,6 +183,13 @@ gcloud compute firewall-rules create fw-allow-health-check \
    --source-ranges=130.211.0.0/22,35.191.0.0/16 \
    --target-tags=allow-health-check \
    --rules=tcp:80
    gcloud compute firewall-rules create fw-allow-ssh \
    --network=default \
    --action=allow \
    --direction=ingress \
    --source-ranges=0.0.0.0/0 \
    --target-tags=allow-ssh \
    --rules=tcp:22

    # create health check
    gcloud compute health-checks create http $HEALTH_CHECK_NAME \
    @@ -199,10 +207,14 @@ gcloud compute backend-services create $MIG_BACKEND_NAME \
    # add instance groups to MIG backend for each region
    gcloud compute backend-services add-backend $MIG_BACKEND_NAME \
    --global \
    --balancing-mode=UTILIZATION \
    --max-utilization="80" \
    --instance-group=$INSTANCE_GROUP_NAME \
    --instance-group-region=$APP_REGION_1
    gcloud compute backend-services add-backend $MIG_BACKEND_NAME \
    --global \
    --balancing-mode=UTILIZATION \
    --max-utilization="80" \
    --instance-group=$INSTANCE_GROUP_NAME \
    --instance-group-region=$APP_REGION_2

  6. mikesparr created this gist Aug 17, 2023.
    214 changes: 214 additions & 0 deletions gcp-global-lb-multi-region-cr-ce.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,214 @@
    #!/usr/bin/env bash

    #####################################################################
    # REFERENCES
    # - https://cloud.google.com/run/docs/multiple-regions
    # - https://cloud.google.com/compute/docs/instance-groups/distributing-instances-with-regional-instance-groups
    # - https://cloud.google.com/load-balancing/docs/https/setup-global-ext-https-compute
    #####################################################################

    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_USER=$(gcloud config get-value core/account) # set current user
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
    export IDNS=${PROJECT_ID}.svc.id.goog # workflow identity domain

    export GCP_REGION="us-central1" # CHANGEME (OPT)
    export GCP_ZONE="us-central1-a" # CHANGEME (OPT)
    export NETWORK_NAME="default"

    # enable apis
    gcloud services enable compute.googleapis.com \
    storage.googleapis.com \
    cloudbuild.googleapis.com \
    run.googleapis.com \
    artifactregistry.googleapis.com

    # configure gcloud sdk
    gcloud config set compute/region $GCP_REGION
    gcloud config set compute/zone $GCP_ZONE


    ##########################################################
    # Demo App Initialization
    ##########################################################
    # declare demo app name
    export APP_NAME="my-app"
    export APP_REGION_1="us-central1"
    export APP_REGION_2="australia-southeast1"
    export APP_IMAGE_URL="gcr.io/google-samples/zone-printer:0.2"


    ##########################################################
    # Load Balancing
    ##########################################################
    export DOMAIN="my-app.msparr.com" # CHANGE ME TO DESIRED DOMAIN
    export EXT_IP_NAME="global-ip"
    export BACKEND_NAME="$APP_NAME-backend"
    export SERVERLESS_NEG_NAME_1="$APP_NAME-neg-us-2"
    export SERVERLESS_NEG_NAME_2="$APP_NAME-neg-aus-2"
    export HTTP_KEEPALIVE_TIMEOUT_SEC="610" # default

    # create global public IP
    gcloud compute addresses create --global $EXT_IP_NAME
    export EXT_IP=$(gcloud compute addresses describe $EXT_IP_NAME --global --format="value(address)")
    echo "** remember to update DNS for $DOMAIN -> $EXT_IP **"

    # create backend service
    gcloud compute backend-services create $BACKEND_NAME \
    --global

    # create URL map
    gcloud compute url-maps create $APP_NAME-url-map \
    --default-service=$BACKEND_NAME

    # create managed SSL cert
    gcloud beta compute ssl-certificates create $APP_NAME-cert \
    --domains $DOMAIN

    # create target HTTPS proxy
    gcloud compute target-https-proxies create $APP_NAME-https-proxy \
    --ssl-certificates=$APP_NAME-cert \
    --url-map=$APP_NAME-url-map

    # create forwarding rule using static IP (classic LB, use EXTERNAL_MANAGED for global ALB)
    gcloud compute forwarding-rules create $APP_NAME-fwd-rule \
    --load-balancing-scheme=EXTERNAL \
    --target-https-proxy=$APP_NAME-https-proxy \
    --global \
    --ports=443 \
    --address=$EXT_IP_NAME

    # create target HTTP proxy
    gcloud compute target-http-proxies create $APP_NAME-http-proxy \
    --url-map=$APP_NAME-url-map

    # create forwarding rule using static IP (classic LB, use EXTERNAL_MANAGED for global ALB)
    gcloud compute forwarding-rules create $APP_NAME-fwd-rule-http \
    --load-balancing-scheme=EXTERNAL \
    --target-http-proxy=$APP_NAME-http-proxy \
    --global \
    --ports=80 \
    --address=$EXT_IP_NAME


    ##########################################################
    # Cloud Run Serverless Runtime
    ##########################################################
    export SERVERLESS_NEG_NAME="$APP_NAME-neg"
    export SERVERLESS_BACKEND_NAME="$APP_NAME-run-backend"

    # deploy app to 2 regions
    gcloud run deploy $APP_NAME \
    --allow-unauthenticated \
    --ingress=internal-and-cloud-load-balancing \
    --image=$APP_IMAGE_URL \
    --region=$APP_REGION_1
    gcloud run deploy $APP_NAME \
    --allow-unauthenticated \
    --ingress=internal-and-cloud-load-balancing \
    --image=$APP_IMAGE_URL \
    --region=$APP_REGION_2

    # create serverless network endpoint groups for each region
    gcloud compute network-endpoint-groups create $SERVERLESS_NEG_NAME \
    --network-endpoint-type=serverless \
    --cloud-run-service=$APP_NAME \
    --region=$APP_REGION_1
    gcloud compute network-endpoint-groups create $SERVERLESS_NEG_NAME \
    --network-endpoint-type=serverless \
    --cloud-run-service=$APP_NAME \
    --region=$APP_REGION_2

    # add custom backend for Cloud Run apps (assuming legacy)
    gcloud compute backend-services create $SERVERLESS_BACKEND_NAME \
    --global

    # add serverless negs to backend for each region
    gcloud compute backend-services add-backend $SERVERLESS_BACKEND_NAME \
    --global \
    --network-endpoint-group=$SERVERLESS_NEG_NAME \
    --network-endpoint-group-region=$APP_REGION_1
    gcloud compute backend-services add-backend $SERVERLESS_BACKEND_NAME \
    --global \
    --network-endpoint-group=$SERVERLESS_NEG_NAME \
    --network-endpoint-group-region=$APP_REGION_2

    # update existing load balancer URL map to point to new backend
    gcloud compute url-maps set-default-service $APP_NAME-url-map \
    --default-service=$SERVERLESS_BACKEND_NAME \
    --global

    # test from different regions and confirm backend switches


    ##########################################################
    # Compute Engine Runtime
    ##########################################################
    export INSTANCE_TEMPLATE_NAME="$APP_NAME-template"
    export INSTANCE_GROUP_NAME="$APP_NAME-rmig"
    export MIG_BACKEND_NAME="$APP_NAME-rmig-backend"
    export HEALTH_CHECK_NAME="http-basic-check"

    # create instance template that runs container image
    gcloud compute instance-templates create-with-container $INSTANCE_TEMPLATE_NAME \
    --container-image $APP_IMAGE_URL \
    --tags "$APP_NAME,allow-health-check,allow-ssh"

    # create regional migs for each region
    gcloud compute instance-groups managed create $INSTANCE_GROUP_NAME \
    --base-instance-name $INSTANCE_GROUP_NAME \
    --size 1 \
    --template $INSTANCE_TEMPLATE_NAME \
    --region $APP_REGION_1
    gcloud compute instance-groups managed create $INSTANCE_GROUP_NAME \
    --base-instance-name $INSTANCE_GROUP_NAME \
    --size 1 \
    --template $INSTANCE_TEMPLATE_NAME \
    --region $APP_REGION_2

    # add named port (internal)
    gcloud compute instance-groups set-named-ports $INSTANCE_GROUP_NAME \
    --named-ports http:80 \
    --region $APP_REGION_1
    gcloud compute instance-groups set-named-ports $INSTANCE_GROUP_NAME \
    --named-ports http:80 \
    --region $APP_REGION_2

    # enable firewall rules
    gcloud compute firewall-rules create fw-allow-health-check \
    --network=default \
    --action=allow \
    --direction=ingress \
    --source-ranges=130.211.0.0/22,35.191.0.0/16 \
    --target-tags=allow-health-check \
    --rules=tcp:80

    # create health check
    gcloud compute health-checks create http $HEALTH_CHECK_NAME \
    --use-serving-port \
    --global

    # create custom backend for MIGs
    gcloud compute backend-services create $MIG_BACKEND_NAME \
    --load-balancing-scheme=EXTERNAL \
    --protocol=HTTP \
    --port-name=http \
    --health-checks=$HEALTH_CHECK_NAME \
    --global

    # add instance groups to MIG backend for each region
    gcloud compute backend-services add-backend $MIG_BACKEND_NAME \
    --global \
    --instance-group=$INSTANCE_GROUP_NAME \
    --instance-group-region=$APP_REGION_1
    gcloud compute backend-services add-backend $MIG_BACKEND_NAME \
    --global \
    --instance-group=$INSTANCE_GROUP_NAME \
    --instance-group-region=$APP_REGION_2

    # update existing load balancer URL map to point to MIG backend
    gcloud compute url-maps set-default-service $APP_NAME-url-map \
    --default-service=$MIG_BACKEND_NAME \
    --global

    # test from different regions and confirm backend switches