Set up cross-region load balancing for Microsoft IIS web servers Stay organized with collections Save and categorize content based on your preferences.
This tutorial describes how to use anexternal Application Load Balancer to distribute traffic toMicrosoft Internet Information Services (IIS) web servers running on Compute Engine VMs that are provisioned in different regions.
Objective
This tutorial shows you how to load balance traffic for the sitewww.example.comand ensure that:
- Incoming requests are routed to the closest region.
- If an instance fails or reaches its capacity, the load balancer routes requests to other responsive instances in the same or a different region.
The configuration for this scenario uses an external Application Load Balancer thattakes requests through a single global IP address. ThisIP address can route each incoming request by connectiontype—that is, HTTP or HTTPS. For HTTPS requests, the load balancerimplements SSL/TLS encryption between the client sending therequest and the load balancer.
The following diagram shows the load balancer architecture:
Note that the load balancer includes several components for maximumconfigurability. For a description of what each component does, see theExternal Application Load Balancer overview.
This tutorial shows you how to complete the following tasks to reach your objective:
- Set up the backend instances.
- Create and configure the load balancing service.
- Send traffic to the backends.
- Restrict access to the backends.
- Simulate an outage.
Costs
In this document, you use the following billable components of Google Cloud:
- Compute Engine virtual machine (VM) instances
- Compute Engine persistent disks
- Optional: Google-managed SSL certificate
- Windows Server 2016 machine images
To generate a cost estimate based on your projected usage, use thepricing calculator.
When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, seeClean up.
Before you begin
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
- Create a project: To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission.Learn how to grant roles.
Verify that billing is enabled for your Google Cloud project.
Enable the Compute Engine, BigQuery, and Cloud Firestore APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission.Learn how to grant roles.Install the Google Cloud CLI.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Toinitialize the gcloud CLI, run the following command:
gcloudinit
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
- Create a project: To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission.Learn how to grant roles.
Verify that billing is enabled for your Google Cloud project.
Enable the Compute Engine, BigQuery, and Cloud Firestore APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission.Learn how to grant roles.Install the Google Cloud CLI.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Toinitialize the gcloud CLI, run the following command:
gcloudinit
- Install a Remote Desktop Protocol (RDP) client. For more information, seeMicrosoft Remote Desktop clients. If you already have an RDP client installed, you can skip this task.
- Decide the zones and regions where the you want to provision your resources. The architecture diagram shows resources deployed in the different zones in the US and EU regions. This is just for reference. You can deploy your resources in any regions/zones of your choice.
- Optional: Read and understand theExternal Application Load Balancer overview.
Set up your backend instances
In this section, you create two backend services in differentregions. Each backend service includes two backend instances,each running a Microsoft IIS web server on Windows Server 2016. To avoidlaborious manual configuration of each server, create a diskimage from one server instance, and then use this image to create yourother server instances.
Create and configure a Compute Engine instance
To create the instance to use as a source image:
From Google Cloud Marketplace, launch an instance of Windows Server 2016 runningMicrosoft IIS on Compute Engine in a zone of your choice, and set upfirewall rules to allow external HTTP, HTTPS, and RDP traffic to your source imageinstance:
In the Google Cloud console, go to theASP.NET Framework Cloud Marketplace page.
ClickLaunch.
In theDeployment name field, entersrc-img.
In theZone field, select a zone that you want to deploy the image in.
In theWindows Server OS Version field, select2016.
In theNetworking - Firewall section, select only the following options:
- Allow HTTP traffic
- Allow HTTPS traffic
- Allow RDP traffic
Accept the terms of service and clickDeploy.
Wait for the Compute Engine instance to be created.
Configure your source image instance
To configure your new source image instance, create a new Windows user on thesource image instance and establish an RDP connection:
In the Google Cloud console, go to theVM instances page.
Click the name of your source image instance (
src-img).ClickSet Windows password.
In theSet new Windows password dialog, add your username andclickSet to create the user account on your instance.
Copy the provided password and close the dialog.
Click theRDP dropdown and select theDownload the RDP file option todownload the RDP file for your instance. Use this file to connect to theinstance using an RDP client. For more information, seeMicrosoft Remote Desktop clients.
After you establish an RDP connection with your source image instance,add a default homepage in the IIS default web directory:
On your source image instance, open PowerShell as an administrator.
Create a new homepage in the default IIS web directory
C:\inetpub\wwwroot:Echo '<!doctype html><html><body><h1>Hello World!</h1></body></html>' > C:\inetpub\wwwroot\index.html
Verify that your source image instance can serve content
In the Google Cloud console, go to theVM instances page.
Click the external IP address of your instance to verify that it is servingthe homepage you created earlier.
Create a reusable Windows Server 2016 image from your source image instance
After verifying that your source image instance is properly configuredand able to serve content, create a reusable disk image from the instance'sroot persistent disk:
- On your source image instance, open PowerShell as an administrator.
Run the following command to prepare your system forcloning:
GCESysprep
When the
GCESysprepoperation completes, you are automatically disconnectedfrom your RDP session.On your local machine, run the following command to delete your sourceinstance while retaining its root persistent disk:
gcloud compute instances delete src-img \ --keep-disks=boot \ --zone=INSTANCE_ZONE
Replace
INSTANCE_ZONEwith the zone of your sourceinstance.After the instance is deleted, create a new image from theroot persistent disk you retained:
gcloud compute images create win-be-img \ --source-disk=src-img \ --source-disk-zone=IMAGE_ZONE
Replace
IMAGE_ZONEwith the zone that you want tocreate your source image in.
Create an instance template using your source image
Use the disk image from your configured Windows server as the source image foraninstance template.Later, you'll configure twomanaged instance groups to use this template for new instances.
On your local machine, run the following command to create an instance templatethat useswin-be-img as the source image andrdp-tag andwww-tag asinstance tags:
gcloud compute instance-templates create win-be-tmpl \ --tags=rdp-tag,www-tag \ --image=win-be-img
Create a managed instance group for each region
In each region, create managed instance groups. After you create eachinstance group, the group automatically populates with two identicalinstances based on the instance template you defined earlier. Later,you'll configure your load balancer to treat these instance groupsas backend targets.
To create your managed instance groups:
On your local machine, run the following command to create a newmanaged instance group in the zone that you created the image in andautomatically populate it with two identical instances:
gcloud compute instance-groups managed createMANAGED_INSTANCE_GROUP_NAME_1 \ --base-instance-name=BASE_INSTANCE_NAME_1 \ --size=2 \ --zone=ZONE_1 \ --template=win-be-tmpl
Replace the following:
MANAGED_INSTANCE_GROUP_NAME_1: your managed instance's nameBASE_INSTANCE_NAME_1: your base instance's nameZONE_1: the zone that you want to deploy your managed instance in
Create a managed instance group in the second zone:
gcloud compute instance-groups managed createMANAGED_INSTANCE_GROUP_NAME_2 \ --base-instance-name=BASE_INSTANCE_NAME_2 \ --size=2 \ --zone=ZONE_2 \ --template=win-be-tmpl
Replace the following:
MANAGED_INSTANCE_GROUP_NAME_2: your managed instance's nameBASE_INSTANCE_NAME_2: your base instance's nameZONE_2: the zone that you want to deploy your managed instance in
Verify that your backend instances are running
In the Google Cloud console, go to theVM instances page.
Click the external IP address of each backend to verify that the backend is servingthe homepage you created earlier.
Create and configure your load balancing service
The Compute Engine load balancing service includes severalcomponents. In this section, you'll create these components andconnect them together.
On your local machine, run the following command to create anew health check. Your load balancer uses this checkto check the responsiveness of your backend instances:
gcloud compute http-health-checks create basic-check
Create abackend service:
gcloud compute backend-services createBACKEND_SERVICE_NAME \ --protocol=HTTP \ --http-health-checks=basic-check \ --global
Replace
BACKEND_SERVICE_NAMEwith a name for the backend service.Add your instance groups as backend targets for your backend service:
gcloud compute backend-services add-backendBACKEND_SERVICE_NAME \ --instance-group=MANAGED_INSTANCE_GROUP_NAME_1 \ --instance-group-zone=ZONE_1gcloud compute backend-services add-backendBACKEND_SERVICE_NAME \ --instance-group=MANAGED_INSTANCE_GROUP_NAME_2 \ --instance-group-zone=ZONE_2
Create a default URL map that directs all incoming requeststo all of your instances:
gcloud compute url-maps create lb-map \ --default-service=BACKEND_SERVICE_NAME
Create an SSL certificate resource. Your load balancer uses thisresource to encrypt and decrypt traffic.
If you already have a private key and an SSL certificate from acertificate authority, you can use them to create a new
Note: Skip this step if you choose to use a Google-managed or a self-signedSSL certificate.SSLCertificateresource by running the following command. Otherwise, you can create and use aGoogle-managed SSL certificate or aself-signed certificate for testing. For more information, seeSSL certificates.Run the following command to create your SSL certificate resource:
gcloud compute ssl-certificates create www-cert \ --certificateCRT_FILE_PATH \ --private-keyKEY_FILE_PATH
Replace the following:
CRT_FILE_PATH: your certificate's local filepathKEY_FILE_PATH: your private key's file path
Create target HTTP and HTTPS proxies to route requests to your URL map.The proxy is the portion of the load balancer that holds the SSLcertificate for HTTPS load balancing, so you also load yourcertificate in this step:
gcloud compute target-http-proxies create http-lb-proxy \ --url-map=lb-mapgcloud compute target-https-proxies create https-lb-proxy \ --url-map lb-map \ --ssl-certificateSSL_CERT
Replace SSL_CERT based on the following:
- If you've created an SSLCertificate resource with your SSL certificate andprivate key, then replace
SSL_CERTwithwww-cert. - If you're using a Google-managed or a self-signed SSLcertificate, then replace
SSL_CERTwith the name of your certificate.
- If you've created an SSLCertificate resource with your SSL certificate andprivate key, then replace
For your load balancer to reliably receive traffic, you need to assign aglobal static IP address to the load balancer's global forwarding rule.
To create a global static IP address resource, run the following command:
gcloud compute addresses create lb-ip \ --global \ --network-tier=PREMIUM
Take note of the IP address.
Create two global forwarding rules to handle incoming HTTP and HTTPSrequests. Each forwarding rule sends traffic to one of the targetproxies you created depending on the IP address, IP protocol, andport specified.
- For a global external Application Load Balancer, use the gcloud CLI command with
load-balancing-scheme=EXTERNAL_MANAGED. This setting offersadvanced traffic management capability. - For an classic Application Load Balancer, use
load-balancing-scheme=EXTERNAL.
gcloud compute forwarding-rules create http-fwd-rule \ --load-balancing-scheme=LOAD_BALANCING_SCHEME \ --network-tier=PREMIUM \ --address=lb-ip \ --global \ --target-http-proxy=http-lb-proxy \ --ports=80gcloud compute forwarding-rules create https-fwd-rule \ --load-balancing-scheme=LOAD_BALANCING_SCHEME \ --network-tier=PREMIUM \ --address=lb-ip \ --global \ --target-https-proxy=https-lb-proxy \ --ports=443
- For a global external Application Load Balancer, use the gcloud CLI command with
After you create the global forwarding rules, it can take several minutesfor your configuration to propagate. To check the progress of thepropagation, you can either monitor your configuration in theGoogle Cloud console or run the following command on your local machine:
gcloud compute backend-services get-healthBACKEND_SERVICE_NAME
Send traffic to your backends
Now that you've configured your load balancing service, you can start sendingtraffic to the forwarding rule and watch the traffic be dispersed to differentinstances.
Send traffic to your backends as follows:
In the Google Cloud console, go to theLoad balancing page.
Select theFrontends tab.
To see your default homepage, click the IP addresses in theAddress column.
Note: If you used a self-signed certificate for testing, your browserdisplays a warning and you must manually accept the certificate.
Restrict access to your backends
After you have verified that everything is working as intended, modifyyour firewall rules so that HTTP or HTTPS traffic can only come from your loadbalancing service:
In the Google Cloud console, go to theFirewall page.
Click the name of the firewall rule that permits external access to port
tcp:80.ClickEdit to edit the firewall rule.
In theSource IPv4 ranges field, remove the value
0.0.0.0/0andenter130.211.0.0/22.This restricts the firewall rule's allowed source IPs to the range130.211.0.0/22, which is the HTTPS load balancing health check IP range.ClickSave.
In the Google Cloud console, go to theVM instances page.
Click the external IP address of each instance to verify that the instance is now inaccessible.
Simulate an outage
To see how a load is balanced among the responsive instances, you can simulate anoutage for one or more instances in a region.
To stop an instance from receiving additional requests:
- Establish an RDP connection to the instance.
- On the instance, open PowerShell as an administrator.
Run the following command to create a new firewall rule on theinstance. This command blocks the health check traffic from thehealth checker and prevents all new HTTP connections from theload balancer to the instance:
netsh advfirewall firewall add rule name="Outage Test" protocol=tcp dir=in localport=80 action=block remoteip=130.211.0.0/22
On your local machine, run the following command to verify that theinstance now reports an
UNHEALTHYstatus:gcloud compute backend-services get-healthBACKEND_SERVICE_NAME
After the instance starts reporting an
UNHEALTHYstatus, senda request to your load balancer. Only the responsive instances shouldrespond.After you've finished simulating an outage, you can restore yourinstance's connectivity by deleting the firewall rule. After openingPowerShell as an administrator on the unresponsive instance, run thefollowing command to delete the rule:
netsh advfirewall firewall delete rule name="Outage Test"
Clean up
After you finish the tutorial, you can clean up the resources that you created so that they stop using quota and incurring charges. The following sections describe how to delete or turn off these resources.
Delete the project
The easiest way to eliminate billing is to delete the project that you createdfor the tutorial.
Delete individual resources
You'll need to individually delete all the resources created for the project(images, instance templates, instance groups, health checks, backend services,URL map, http proxy, addresses, forwarding rules). You can't delete the VMinstances until you run the following commands.
Run the following commands on your local machine to delete the resources createdfor the tutorial:
- Delete the HTTP/S forwarding rules:
gcloud compute forwarding-rules delete https-fwd-rule --global
gcloud compute forwarding-rules delete http-fwd-rule --global
- Delete the global static IP address:
gcloud compute addresses delete lb-ip --global
- Delete the HTTP/S proxies:
gcloud compute target-https-proxies delete https-lb-proxy
gcloud compute target-http-proxies delete http-lb-proxy
- Delete the SSL certificate:
gcloud compute ssl-certificates deleteSSL_CERT
- Delete the URL map:
gcloud compute url-maps delete lb-map
- Delete the backend service:
gcloud compute backend-services deleteBACKEND_SERVICE_NAME --global
- Delete the HTTP health check:
gcloud compute http-health-checks delete basic-check
- Delete the managed instance groups:
gcloud compute instance-groups managed deleteMANAGED_INSTANCE_GROUP_NAME_1 --zone=ZONE_1
gcloud compute instance-groups managed deleteMANAGED_INSTANCE_GROUP_NAME_2 --zone=ZONE_2
- Delete the instance template:
gcloud compute instance-templates delete win-be-tmpl
- In the Google Cloud console, go to theImages page.
- Select the checkbox for the image that you want to delete.
- To delete the image, clickDelete.
- In the Google Cloud console, go to theDisks page.
- Select the checkbox for the disk that you want to delete.
- To delete the disk, clickDelete.
What's next
- Work through thedeploying load-balanced IIS web servers tutorial.
- Review the best practices in theGoogle Cloud Well-Architected Framework.
- Explore reference architectures, diagrams, and best practices about Google Cloud.Take a look at ourCloud Architecture Center.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.