1. Introduction
Private Service Connect enables service producers to expose services privately from one VPC network to another. Consumers can access producer services through either PSC endpoints or PSC Backends.
The focus of this codelab is PSC Backends. PSC Backends are used in conjunction with Google Cloud proxy load balancers (either Application or Network). Using PSC Backends provides more granular consumer side controls such as:
- Deeper observability and logging
- Cloud Armor Integration
- Custom URLs
- Advanced Traffic Management
- Custom TLS certificates
In this codelab, you will learn how to create a Private Service Connect Backend with the Global External Application Load Balancer to privately access a producer service in another network.
What you'll learn
- Create and configure a PSC Backend associated with the Global External Application Load Balancer
- Configure an Apache managed web service and expose it as a PSC service through a Service Attachment
- Create SSL certificates to terminate SSL on Internal and External Application Load Balancers
- Configure a Cloud DNS public zone for accessing the PSC service
What you'll need
- A Google Cloud project with owner permissions
2. Test Environment
The environment that you will create will consist of a Consumer VPC and Producer VPC. In the Producer VPC, you will deploy a managed instance group from an instance template that builds an open source Apache web service. You'll also deploy a test-vm to ensure proper local functionality of the service. You'll expose the Apache service as a PSC Producer service via a Service Attachment.
In the Consumer VPC you'll deploy a Global External Application Load Balancer with a PSC Backend service pointing to the Apache service. You'll then set up a public DNS zone to access the PSC service on the public Internet.
3. Setup and Requirements
Self-paced environment setup
- Sign-in to the Google Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one.
- The Project name is the display name for this project's participants. It is a character string not used by Google APIs. You can always update it.
- The Project ID is unique across all Google Cloud projects and is immutable (cannot be changed after it has been set). The Cloud Console auto-generates a unique string; usually you don't care what it is. In most codelabs, you'll need to reference your Project ID (typically identified as
PROJECT_ID
). If you don't like the generated ID, you might generate another random one. Alternatively, you can try your own, and see if it's available. It can't be changed after this step and remains for the duration of the project. - For your information, there is a third value, a Project Number, which some APIs use. Learn more about all three of these values in the documentation.
- Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab won't cost much, if anything at all. To shut down resources to avoid incurring billing beyond this tutorial, you can delete the resources you created or delete the project. New Google Cloud users are eligible for the $300 USD Free Trial program.
Start Cloud Shell
While Google Cloud can be operated remotely from your laptop, in this codelab you will be using Google Cloud Shell, a command line environment running in the Cloud.
From the Google Cloud Console, click the Cloud Shell icon on the top right toolbar:
It should only take a few moments to provision and connect to the environment. When it is finished, you should see something like this:
This virtual machine is loaded with all the development tools you'll need. It offers a persistent 5GB home directory, and runs on Google Cloud, greatly enhancing network performance and authentication. All of your work in this codelab can be done within a browser. You do not need to install anything.
4. Before you begin
Enable APIs
Inside Cloud Shell, make sure that your project id is set up
gcloud config list project gcloud config set project [YOUR-PROJECT-NAME] export project=YOUR-PROJECT-NAME export region=us-central1 echo $project echo $region
Enable all necessary services
gcloud services enable compute.googleapis.com gcloud services enable servicedirectory.googleapis.com gcloud services enable dns.googleapis.com
5. Producer VPC Setup
Create VPC Network
From Cloud Shell
gcloud compute networks create producer-vpc --subnet-mode custom
Create Subnets
Two general purpose subnets will be deployed in the producer-vpc. The service-subnet will be used to deploy the Apache web service VMs as well as the load balancer forwarding rule. The test-client-subnet will be in a different region and will be used to deploy a VM to test the Apache service with Global Access enabled.
From Cloud Shell
gcloud compute networks subnets create service-subnet \ --network=producer-vpc \ --range=10.0.0.0/28 \ --region=$region
From Cloud Shell
gcloud compute networks subnets create test-client-subnet \ --network=producer-vpc \ --range=10.0.1.0/28 \ --region=us-east4
We must also deploy a proxy only subnet to be used with the Regional Internal Application Load Balancer.
From Cloud Shell
gcloud compute networks subnets create central-proxy-subnet \ --network=producer-vpc \ --range=10.100.101.0/24 \ --region=$region \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE
When a PSC service is deployed, each unique service needs a corresponding PSC NAT subnet to be associated with the Service Attachment. This subnet should be sized appropriately depending on the number of expected connected endpoints.
From Cloud Shell
gcloud compute networks subnets create psc-nat-subnet \ --network=producer-vpc \ --region=$region \ --range=10.100.100.0/24 \ --purpose=PRIVATE_SERVICE_CONNECT
Create Cloud NAT
A Cloud NAT is required to install the proper packages for our producer services.
From Cloud Shell
gcloud compute routers create central-cr \ --network=producer-vpc \ --region=$region
From Cloud Shell
gcloud compute routers nats create central-nat \ --router=central-cr \ --region=$region \ --nat-all-subnet-ip-ranges \ --auto-allocate-nat-external-ips
Create Network Firewall Policy and Rules
From Cloud Shell
gcloud compute network-firewall-policies create producer-vpc-policy --global gcloud compute network-firewall-policies associations create \ --firewall-policy producer-vpc-policy \ --network producer-vpc \ --name network-producer-vpc \ --global-firewall-policy
To allow IAP to connect to your VM instances, create a firewall rule that:
- Applies to all VM instances that you want to be accessible by using IAP.
- Allows ingress traffic from the IP range 35.235.240.0/20. This range contains all IP addresses that IAP uses for TCP forwarding.
From Cloud Shell
gcloud compute network-firewall-policies rules create 1000 \ --action ALLOW \ --firewall-policy producer-vpc-policy \ --description "SSH with IAP" \ --direction INGRESS \ --src-ip-ranges 35.235.240.0/20 \ --layer4-configs tcp:22 \ --global-firewall-policy
Two additional firewall rules will be needed to allow ingress traffic to the load balancer backends sourced from the load balancer proxy only subnet (2000), as well as a rule to allow load balancer healthchecks on the back end instances (2001).
From Cloud Shell
gcloud compute network-firewall-policies rules create 2000 \ --action ALLOW \ --firewall-policy producer-vpc-policy \ --description "allow traffic from load balancer proxy subnet" \ --direction INGRESS \ --src-ip-ranges 10.100.101.0/24 \ --layer4-configs tcp:443 \ --global-firewall-policy gcloud compute network-firewall-policies rules create 2001 \ --action ALLOW \ --firewall-policy producer-vpc-policy \ --description "allow load balancer health checks" \ --direction INGRESS \ --src-ip-ranges 130.211.0.0/22,35.191.0.0/16 \ --layer4-configs tcp:443 \ --global-firewall-policy
6. Create Apache Web Service
We'll create a simple Apache Web Service that displays "PSC Service."
Create Instance Template
From Cloud Shell
gcloud compute instance-templates create apache-service-template \ --network producer-vpc \ --subnet service-subnet \ --region $region \ --no-address \ --metadata startup-script='#! /bin/bash sudo apt-get update apt-get install apache2 -y a2enmod ssl sudo a2ensite default-ssl echo "PSC Service" | \ tee /var/www/html/index.html systemctl restart apache2'
Create Health Check for MIG
From Cloud Shell
gcloud compute health-checks create https service-mig-healthcheck \ --port=443 \ --global
Create Managed Instance Group
From Cloud Shell
gcloud compute instance-groups managed create psc-service-mig \ --region $region \ --size=2 \ --template=apache-service-template \ --health-check=service-mig-healthcheck gcloud compute instance-groups managed set-named-ports psc-service-mig \ --named-ports=https:443 \ --region=$region
7. Create a Self Signed Certificate
Complete Step 1 of the directions here to create a self signed certificate. You can run all of the commands in Cloud Shell. Return to this place when Step 1 is completed. YOUR COMMON NAME MUST BE CONFIGURED WITH EXAMPLE.COM.
Create a certificate resource to associate with your load balancer. Replace the certificate and private-key parameters with your specific file names.
From Cloud Shell
gcloud compute ssl-certificates create producer-service-cert \ --certificate=<your-producer-certfile.cert> \ --private-key=<your-producer-keyfile.pem> \ --region=$region
8. Create the Internal Regional Application Load Balancer
Next we'll create the load balancer components for the service. We're using the Internal Regional Application Load Balancer, but you have the option of using any Google Cloud internal load balancer. Follow the appropriate load balancer documentation for TLS handling.
Create the internal IP address that will be used for the forwarding rule of your load balancer and make note of the IP to be used later when you make a test call to the service.
From Cloud Shell
gcloud compute addresses create apache-service-ip \ --region=$region \ --subnet=service-subnet gcloud compute addresses describe apache-service-ip \ --format="get(address)" \ --region=$region
Create the load balancer health check.
From Cloud Shell
gcloud compute health-checks create https lb-apache-service-hc \ --region=$region \ --port-name=https
Create the backend service.
From Cloud Shell
gcloud compute backend-services create apache-bes\ --load-balancing-scheme=INTERNAL_MANAGED \ --protocol=HTTPS \ --port-name=https \ --health-checks=lb-apache-service-hc \ --health-checks-region=$region \ --region=$region gcloud compute backend-services add-backend apache-bes \ --balancing-mode=UTILIZATION \ --instance-group=psc-service-mig \ --region=$region
Create the URL Map.
From Cloud Shell
gcloud compute url-maps create producer-url-map \ --default-service=apache-bes \ --region=$region
Create the target HTTPS proxies.
From Cloud Shell
gcloud compute target-https-proxies create https-proxy \ --url-map=producer-url-map \ --region=$region \ --ssl-certificates=producer-service-cert
Create the Forwarding Rule.
From Cloud Shell
gcloud compute forwarding-rules create apache-fr \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=producer-vpc \ --subnet=service-subnet \ --address=apache-service-ip \ --ports=443 \ --region=$region \ --target-https-proxy=https-proxy \ --target-https-proxy-region=$region \ --allow-global-access
9. Create a Test VM and Test the Service Locally
Before we create the Service Attachment, we'll create a test client vm in a different region to test that the load balancer is configured correctly with Global Access and TLS.
From Cloud Shell
gcloud compute instances create vm-client \ --zone=us-east4-a \ --subnet=test-client-subnet \ --no-address
Wait about a minute for the provisioning to complete and then SSH into the instance.
From Cloud Shell
gcloud compute ssh \ --zone "us-east4-a" "vm-client" \ --tunnel-through-iap \ --project $project
Test the Apache Service by connecting over 443 through the load balancer. The internal IP address is the one you reserved and noted down earlier.
curl https://example.com:443 -k --connect-to example.com:443:<YOUR-INTERNAL-IP>:443
EXPECTED RESULT
PSC Service
Exit from the VM.
From vm-client
exit
10. Create the Service Attachment
For this example, we are configuring our Service Attachment to only allow PSC connections from this project. This can be configured to accept one or more specific projects or networks, but not both. We've set our maximum connection limit to 5 connections. Each project or network must have a limit set.
From Cloud Shell
gcloud compute service-attachments create apache-service-attachment \ --region=$region \ --producer-forwarding-rule=apache-fr \ --connection-preference=ACCEPT_MANUAL \ --consumer-accept-list=$project=5 \ --nat-subnets=psc-nat-subnet
You should note down the Service Attachment URI (selfLink) as you will need it in the next step for the PSC Backend configuration. You can obtain it by executing the following in Cloud Shell.
From Cloud Shell
gcloud compute service-attachments describe apache-service-attachment \ --region $region
Copy the URI starting from projects
Example: projects/$project/regions/$region/serviceAttachments/apache-service-attachment
11. Consumer VPC Setup
Create VPC Network
From Cloud Shell
gcloud compute networks create consumer-vpc --subnet-mode custom
Create Subnet
A subnet is needed on the consumer side where the Private Service Connect Network Endpoint Group (NEG) will be deployed.
From Cloud Shell
gcloud compute networks subnets create consumer-subnet \ --network=consumer-vpc \ --region=$region \ --range=10.0.0.0/28
12. Reserve External IP and Create Consumer Side Self-Signed Certificate
External IP
Create the external static IP address that will be used later for our load balancer forwarding rule and capture the IP address in a Cloud Shell variable.
From Cloud Shell
gcloud compute addresses create external-psc-ip \ --network-tier=PREMIUM \ --ip-version=IPV4 \ --global export externalip=$(gcloud compute addresses describe external-psc-ip \ --format="get(address)" \ --global) echo $externalip
Consumer Self-Signed Certificate
For a second time, complete Step 1 of the directions here to create a self signed certificate. You can run all of the commands in Cloud Shell. Return to this place when Step 1 is completed. We will be using an open source public wildcard DNS service called nip.io in place of owning our own public DNS zone. The public URL of your PSC service will use the external IP address you just configured. YOUR COMMON NAME MUST BE CONFIGURED WITH <YOUR-EXTERNAL-IP.nip.io>
Create a certificate resource to associate with your external load balancer. Replace the certificate and private-key parameters with your specific file names.
From Cloud Shell
gcloud compute ssl-certificates create consumer-service-cert \ --certificate=<your-consumer-certfile.cert> \ --private-key=<your-consumer-keyfile.pem> \ --global
13. Create the Load Balancer Components
We'll create a Global External Application Load Balancer with a PSC NEG pointing to our newly created Service Attachment as a Backend Service.
Have handy the Service Attachment URI we noted in the last step. Replace the psc-target-service below with your URI.
From Cloud Shell
gcloud compute network-endpoint-groups create apache-psc-neg \ --network-endpoint-type=private-service-connect \ --psc-target-service=projects/$project/regions/$region/serviceAttachments/apache-service-attachment \ --region=$region \ --network=consumer-vpc \ --subnet=consumer-subnet
Create the Backend Service.
From Cloud Shell
gcloud compute backend-services create apache-pscneg-bes \ --load-balancing-scheme=EXTERNAL_MANAGED \ --protocol=HTTPS \ --global gcloud compute backend-services add-backend apache-pscneg-bes \ --network-endpoint-group=apache-psc-neg \ --network-endpoint-group-region=$region \ --global
Create the URL Map
From Cloud Shell
gcloud compute url-maps create consumer-url-map \ --default-service=apache-pscneg-bes \ --global
Create the target HTTPS proxies.
From Cloud Shell
gcloud compute target-https-proxies create psc-https-proxy \ --url-map=consumer-url-map \ --ssl-certificates=consumer-service-cert
Create the Forwarding Rule
From Cloud Shell
gcloud compute forwarding-rules create external-fr \ --load-balancing-scheme=EXTERNAL_MANAGED \ --network-tier=PREMIUM \ --address=external-psc-ip \ --global \ --target-https-proxy=psc-https-proxy \ --ports=443
14. Create Public DNS Zone
From Cloud Shell
gcloud dns managed-zones create "psc-service" \ --dns-name=$externalip.nip.io. \ --description="public dns for psc service" \ --visibility=public
From Cloud Shell
gcloud dns record-sets transaction start \ --zone="psc-service" gcloud dns record-sets transaction add $externalip \ --name=$externalip.nip.io \ --ttl=300 \ --type=A \ --zone="psc-service" gcloud dns record-sets transaction execute \ --zone="psc-service"
15. Test the Consumer PSC Connection
Wait 7 to 10 minutes before testing to let the public DNS propagate.
From Cloud Shell
curl https://$externalip.nip.io -k
You can also test from your browser by inputting https://<YOUR-EXTERNAL-IP>.nip.io into your browser or desktop terminal.
EXPECTED RESULT
PSC Service
16. Cleanup steps
From a single Cloud Shell terminal delete lab components
gcloud dns record-sets delete $externalip.nip.io --zone="psc-service" --type=A -q gcloud dns managed-zones delete "psc-service" -q gcloud compute forwarding-rules delete external-fr --global -q gcloud compute target-https-proxies delete psc-https-proxy -q gcloud compute url-maps delete consumer-url-map --global -q gcloud compute backend-services delete apache-pscneg-bes --global -q gcloud compute network-endpoint-groups delete apache-psc-neg --region=$region -q gcloud compute ssl-certificates delete consumer-service-cert --global -q gcloud compute addresses delete external-psc-ip --global -q gcloud compute networks subnets delete consumer-subnet --region $region -q gcloud compute networks delete consumer-vpc -q gcloud compute instances delete vm-client --zone=us-east4-a -q gcloud compute service-attachments delete apache-service-attachment --region $region -q gcloud compute forwarding-rules delete apache-fr --region $region -q gcloud compute target-https-proxies delete https-proxy --region $region -q gcloud compute url-maps delete producer-url-map --region $region -q gcloud compute backend-services delete apache-bes --region $region -q gcloud compute health-checks delete lb-apache-service-hc --region $region -q gcloud compute addresses delete apache-service-ip --region $region -q gcloud compute ssl-certificates delete producer-service-cert --region $region -q gcloud compute instance-groups managed delete psc-service-mig --region $region -q gcloud compute health-checks delete service-mig-healthcheck --global -q gcloud compute instance-templates delete apache-service-template -q gcloud compute network-firewall-policies rules delete 2001 --firewall-policy producer-vpc-policy --global-firewall-policy -q gcloud compute network-firewall-policies rules delete 2000 --firewall-policy producer-vpc-policy --global-firewall-policy -q gcloud compute network-firewall-policies rules delete 1000 --firewall-policy producer-vpc-policy --global-firewall-policy -q gcloud compute network-firewall-policies associations delete --firewall-policy=producer-vpc-policy --name=network-producer-vpc --global-firewall-policy -q gcloud compute network-firewall-policies delete producer-vpc-policy --global -q gcloud compute routers nats delete central-nat --router=central-cr --region $region -q gcloud compute routers delete central-cr --region $region -q gcloud compute networks subnets delete psc-nat-subnet --region $region -q gcloud compute networks subnets delete service-subnet --region $region -q gcloud compute networks subnets delete test-client-subnet --region us-east4 -q gcloud compute networks subnets delete central-proxy-subnet --region $region -q gcloud compute networks delete producer-vpc -q
17. Congratulations!
Congratulations for completing the codelab.
What we've covered
- Create a configure a PSC Backend associated with the Global External Application Load Balancer
- Configure an Apache managed web service and expose it as a PSC service through a Service Attachment
- Create SSL certificates to terminate SSL on Internal and External Application Load Balancers
- Configure a Cloud DNS public zone to access the PSC service