
Overview
By default, a Cloud Run service will connect to external endpoints on the internet using a dynamic IP address pool. This method is not suitable if the Cloud Run service needs to connect to an external endpoint that requires connections originating from a static IP address, for example, as a database or API using an IP address-based firewall. For those types of connections, you must configure your Cloud Run service to route requests through a static IP address.
This lab teaches the process of configuring a Cloud Run service to send requests using a static IP address.
Prerequisites
These labs are based on intermediate knowledge of Google Cloud. While the steps required are covered in the content, it would be helpful to have familiarity with any of the following products:
- Static IP Addresses
- Cloud Run
Objectives
In this lab, you learn to:
- Build and publish a sample Cloud Run service and image using code from the Buildpack samples repository.
- Create a subnetwork and a VPC access connector.
- Configure network address translation (NAT).
- Route your Cloud Run traffic through the VPC network.
Setup and requirements
Before you click the Start Lab button
Note: Read these instructions.
Labs are timed and you cannot pause them. The timer, which starts when you click Start Lab, shows how long Google Cloud resources will be made available to you.
This Qwiklabs hands-on lab lets you do the lab activities yourself in a real cloud environment, not in a simulation or demo environment. It does so by giving you new, temporary credentials that you use to sign in and access Google Cloud for the duration of the lab.
What you need
To complete this lab, you need:
- Access to a standard internet browser (Chrome browser recommended).
- Time to complete the lab.
Note: If you already have your own personal Google Cloud account or project, do not use it for this lab.
Note: If you are using a Pixelbook, open an Incognito window to run this lab.
How to start your lab and sign in to the Console
-
Click the Start Lab button. If you need to pay for the lab, a pop-up opens for you to select your payment method.
On the left is a panel populated with the temporary credentials that you must use for this lab.

-
Copy the username, and then click Open Google Console.
The lab spins up resources, and then opens another tab that shows the Choose an account page.
Note: Open the tabs in separate windows, side-by-side.
-
On the Choose an account page, click Use Another Account. The Sign in page opens.

-
Paste the username that you copied from the Connection Details panel. Then copy and paste the password.
Note: You must use the credentials from the Connection Details panel. Do not use your Google Cloud Skills Boost credentials. If you have your own Google Cloud account, do not use it for this lab (avoids incurring charges).
- Click through the subsequent pages:
- Accept the terms and conditions.
- Do not add recovery options or two-factor authentication (because this is a temporary account).
- Do not sign up for free trials.
After a few moments, the Cloud console opens in this tab.
Note: You can view the menu with a list of Google Cloud Products and Services by clicking the Navigation menu at the top-left.
Activate Google Cloud Shell
Google Cloud Shell is a virtual machine that is loaded with development tools. It offers a persistent 5GB home directory and runs on the Google Cloud.
Google Cloud Shell provides command-line access to your Google Cloud resources.
-
In Cloud console, on the top right toolbar, click the Open Cloud Shell button.

-
Click Continue.
It takes a few moments to provision and connect to the environment. When you are connected, you are already authenticated, and the project is set to your PROJECT_ID. For example:

gcloud is the command-line tool for Google Cloud. It comes pre-installed on Cloud Shell and supports tab-completion.
- You can list the active account name with this command:
gcloud auth list
Output:
Credentialed accounts:
- @.com (active)
Example output:
Credentialed accounts:
- google1623327_student@qwiklabs.net
- You can list the project ID with this command:
gcloud config list project
Output:
[core]
project =
Example output:
[core]
project = qwiklabs-gcp-44776a13dea667a6
Note:
Full documentation of gcloud is available in the
gcloud CLI overview guide
.
Task 1. Enable the Cloud Run API and configure your Shell environment for flexibility
-
From Cloud Shell, enable the Cloud Run API :
gcloud services enable run.googleapis.com
If you are asked to authorize the use of your credentials, do so. You should then see a successful message similar to this one:
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
Note: You can also enable the API using the APIs & Services section of the console.
-
Create a LOCATION environment variable:
LOCATION={{{project_0.default_region|REGION}}}
-
Set the compute region:
gcloud config set compute/region $LOCATION
Task 2. Create a service
Clone the buildpack-samples repository
Copy a sample application
Edit the sample application
-
Change to the sample code folder:
cd buildpack-samples/sample-go
-
Using any editor, edit the file hello.go
in the sample-go
folder, and add the /service
http handler to the main
function:
http.HandleFunc("/service", func(w http.ResponseWriter, r *http.Request) {
serviceURL := os.Getenv("SERVICE_B_URL")
if serviceURL == "" {
log.Fatalln("Service URL environment variable is not set.")
}
resp, err := http.Get(serviceURL)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
fmt.Fprint(w, string(body))
})
The function uses a URL from an environment variable to invoke another internal Cloud Run service.
-
Update the import
statement to add the io/ioutil
package:
import (
"fmt"
"log"
"net/http"
"os"
"io"
)
-
Build an application container for your sample application with the pack
command.
If asked to provide authorization for the Shell, give it permission to run.
pack build --builder=gcr.io/buildpacks/builder sample-go
Run your new container in Docker
-
Run the command below to bind the sample app created in the previous step to port 8080, so that it can be accessed via the browser:
docker run -it -e PORT=8080 -p 8080:8080 sample-go
-
In the Cloud Shell window, click on the Web Preview icon and select Preview on port 8080.
A new browser window or tab will open showing the "hello, world" message. Success!
-
Back in the console window, click Control C
(Control and C key held down at the same time) to stop the web service and return control of the command line to the Cloud Shell.
Publish the image
-
First, set up authentication to Docker repositories:
gcloud auth configure-docker
-
When prompted, type Y.
-
Set the default Buildpacks builder:
pack config default-builder gcr.io/buildpacks/builder:v1
-
Publish your container image:
pack build --publish gcr.io/$GOOGLE_CLOUD_PROJECT/sample-go
You are now ready for the next part of the lab.
Task 3. Create a subnetwork
Creating a subnetwork for your Serverless VPC Access connector to reside in ensures that other compute resources in your VPC, such as Compute Engine VMs or Google Kubernetes Engine clusters, do not accidentally use the static IP you have configured to access the internet.
-
First, you will need to find the name of your VPC network by calling up a list of the networks associate with your account, using Cloud shell:
gcloud compute networks list
You should see something like the following in the output, identifying the networks you can use when attaching your Serverless VPC Access connector. For this lab, the only network that will be available is the default
network, so the information returned will be similar to the output shown below:
NAME: default
SUBNET_MODE: AUTO
BGP_ROUTING_MODE: REGIONAL
IPV4_RANGE:
GATEWAY_IPV4:
-
Create a subnetwork called mysubnet
with a range of 192.168.0.0/28
specified in CIDR format, to be used for your Serverless VPC Access connector.
To create this subnetwork in the project's default
network (note also that ), run the command:
gcloud compute networks subnets create mysubnet \
--range=192.168.0.0/28 --network=default --region=$LOCATION
Note: To avoid errors later in the process, use a netmask of 28 for subnets that are used for VPC connectors.
Task 4. Create a serverless VPC Access connector
To route your Cloud Run service's outbound traffic to a VPC network, you first need to set up a Serverless VPC Access connector.
-
Create a Serverless VPC Access connector named myconnector
with your previously created subnetwork named mysubnet
using the command:
gcloud compute networks vpc-access connectors create myconnector \
--region=$LOCATION \
--subnet-project=$GOOGLE_CLOUD_PROJECT \
--subnet=mysubnet
-
If prompted to enable the vpcaccess.googleapis.com
on your project, type y.
Wait for the process to complete before proceeding.
Task 5. Configure network address translation (NAT)
To route outbound requests to external endpoints through a static IP (which is the main goal of this lab), you must first configure a Cloud NAT gateway.
-
Create a new Cloud Router to program your NAT gateway:
gcloud compute routers create myrouter \
--network=default \
--region=$LOCATION
-
Next, reserve a static IP address using the command below, where myoriginip
is the name being assigned to your IP address resource.
A reserved IP address resource retains the underlying IP address when the resource it is associated with is deleted and re-created. Using the same region as your Cloud NAT router will help to minimize latency and network costs.
gcloud compute addresses create myoriginip --region=$LOCATION
To route outbound requests to external endpoints through a static IP, you must configure a Cloud NAT gateway.
-
Bring all of the resources you've just created together to create a Cloud NAT gateway named mynat
.
To configure your router to route the traffic originating from the VPC network, run the command:
gcloud compute routers nats create mynat \
--router=myrouter \
--region=$LOCATION \
--nat-custom-subnet-ip-ranges=mysubnet \
--nat-external-ip-pool=myoriginip
Task 6. Route Cloud Run traffic through the VPC network
-
After NAT has been configured, deploy your Cloud Run service with the Serverless VPC Access connector, and set VPC egress to route all traffic through the VPC network:
gcloud run deploy sample-go \
--image=gcr.io/$GOOGLE_CLOUD_PROJECT/sample-go \
--vpc-connector=myconnector \
--vpc-egress=all-traffic \
--region $LOCATION \
--allow-unauthenticated
-
If prompted to enable run.googleapis.com
for your project, type y.
If successful, after a few minutes you should see output similar to that below:
Deploying container to Cloud Run service [sample-go] in project [qwiklabs-gcp-01-825e0adf46fc] region {{{project_0.default_region|REGION}}}
✓ Deploying new service... Done.
✓ Creating Revision...
✓ Routing traffic...
✓ Setting IAM Policy...
Done.
Service [sample-go] revision [sample-go-00002-yax] has been deployed and is serving 100 percent of traffic.
Service URL: https://sample-go-lawvw7teya-uc.a.run.app
-
Store the service URL in an environment variable for use later:
SERVICE_A_SAMPLE_GO=[Service URL]
Replace [Service URL] with the value of the Service URL
from the output of the previous step.
-
Navigate to the Service URL
in a separate browser tab.
You should see the same "hello, world" message that you saw displayed in the web preview pane in Task 1.
Task 7. Create a receiving service
To test service to service communication, you create a second service that will respond to requests on its service URL. The service will be configured to only serve internal traffic routed to it using the VPC service connector.
Create the service
-
Change to the sample code folder:
cd ~/buildpack-samples/sample-go-service
-
Using any editor, edit the file hello.go
in the sample-go-service
folder, and update the /
http handler in the main
function:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "hello, from service B")
})
-
Edit the go.mod
file in this folder to update the module entry:
module github.com/GoogleCloudPlatform/buildpack-samples/sample-go-service
Build and deploy the service to Cloud Run
-
Build the second service from source, and deploy it to Cloud Run with the Serverless VPC Access connector allowing internal traffic only:
gcloud run deploy sample-go-service \
--source . \
--port=8081 \
--vpc-connector=myconnector \
--ingress=internal \
--region $LOCATION \
--allow-unauthenticated
-
To create the Artifact registry repository, type Y at the prompt.
If successful, after a few minutes you should see output from the command that contains the service URL.
-
Store the service URL in an environment variable for use later:
SERVICE_B_SAMPLE_GO_SERVICE=[Service URL]
Replace [Service URL] with the value of the Service URL
from the output of the previous step.
-
Navigate to the Service URL
in a separate browser tab.
You should not receive any response from the service since the service is configured to accept internal requests only from within the VPC network or VPC service control perimeter.
Task 8. Test service communication
To verify internal service communication, test the services by making a request to the original Cloud Run service.
You'll also verify the originating IP address of the calling service.
Verify service to service communication
-
First, update the original Cloud Run service with an environment variable that contains the URL of the second Cloud Run sample-go-service
:
gcloud run services update sample-go \
--region $LOCATION \
--set-env-vars=SERVICE_B_URL=$SERVICE_B_SAMPLE_GO_SERVICE
-
Use curl with the original sample-go
service URL, and append the /service
request path:
curl ${SERVICE_A_SAMPLE_GO}/service
The output from the curl command contains the response from the second Cloud Run sample-go-service
, which was invoked by the original calling service sample-go
:
hello, from service B
Verify the originating IP address of the calling service
-
Update the service URL environment variable to a service that verifies the originating IP address:
gcloud run services update sample-go \
--region $LOCATION \
--set-env-vars=SERVICE_B_URL=http://curlmyip.org
-
Use curl with the original sample-go
service URL, and append the /service
request path:
curl ${SERVICE_A_SAMPLE_GO}/service
The output from the curl command contains the originating IP address.
-
In the Google Cloud console, use the Navigation menu (
), and navigate to VPC Network > IP Addresses.
-
Verify that the myoriginip
static IP address value matches the IP address in the output of the curl command.
Congratulations!
After completing the above steps, you have:
- Set up Cloud NAT on your VPC network with a predefined static IP address.
- Routed all of your Cloud Run service's outbound traffic into your VPC network.
- Send requests from your Cloud Run service to internal resources (another Cloud Run service) in your VPC network.
- Confirmed that 100% of your traffic for the sample-go service is now flowing through your new VPC connector.
Follow the Serverless Expeditions video series to learn more about how to utilise these products within your project.
- Cloud Run.
- Cloud Tasks.
- Cloud Functions.
Manual Last Updated February 22, 2024
Lab Last Tested February 22, 2024
Copyright 2022 Google LLC All rights reserved. Google and the Google logo are trademarks of Google LLC. All other company and product names may be trademarks of the respective companies with which they are associated.