About this codelab
1. Introduction
Overview
Cloud Run revisions allows you to specify which revisions should receive traffic and what percentage of traffic to send to each revision. Revisions allows you to rollback to a previous revision, gradually roll out a revision, and split traffic between multiple revisions.
This codelabs show you how to use revisions to manage traffic to your Cloud Run service. You can learn more about revisions in the Cloud Run documentation.
What you'll learn
- How to to split traffic between two or more revisions for a Cloud Run service
- How to roll out a new revision gradually
- How to rollback to a previous revision
2. Setup and Requirements
Prerequisites
- You are logged into the Cloud Console.
- You have previously deployed a Cloud Run service. For example, you can follow the deploy a Cloud Run service to get started.
Set Environment Variables
You can set environment variables that will be used throughout this codelab.
PROJECT_ID=YOUR-PROJECT-ID
REGION=YOUR_REGION
BG_COLOR=darkseagreen
SERVICE_NAME=traffic-revisions-color
AR_REPO=traffic-revisions-color-repo
Create an artifact registry repository for the Service
gcloud artifacts repositories create $AR_REPO \
--repository-format=docker \
--location=$REGION \
--description="codelab for finetuning using CR jobs" \
--project=$PROJECT_ID
3. Traffic Splitting
This sample shows you how to create a Cloud Run service that reads a color environment variable and responds back with the revision name using that background color.
Although this codelab uses python, you can use any runtime.
Set Environment Variables
You can set environment variables that will be used throughout this codelab.
REGION=<YOUR_REGION> PROJECT_ID=<YOUR-PROJECT-ID> BG_COLOR=darkseagreen SERVICE_NAME=traffic-revisions-color AR_REPO=traffic-revisions-color-repo
Create the service
First, create a directory for the source code and cd into that directory.
mkdir traffic-revisions-codelab && cd $_
Then, create a main.py
file with the following content:
import os from flask import Flask, render_template_string app = Flask(__name__) TEMPLATE = """ <!doctype html> <html lang="en"> <head> <title>Cloud Run Traffic Revisions</title> <style> body { display: flex; justify-content: center; align-items: center; min-height: 50vh; background-color: {{ bg_color }}; /* Set by environment variable */ font-family: sans-serif; } .content { background-color: rgba(255, 255, 255, 0.8); /* Semi-transparent white background */ padding: 2em; border-radius: 8px; text-align: center; box-shadow: 0 4px 8px rgba(0,0,0,0.1); } </style> </head> <body> <div class="content"> <p>background color: <strong>{{ color_name }}</strong></p> </div> </body> </html> """ @app.route('/') def main(): """Serves the main page with a background color from the ENV.""" # Get the color from the 'BG_COLOR' environment variable. # Default to 'white' if the variable is not set. color = os.environ.get('BG_COLOR', 'white').lower() return render_template_string(TEMPLATE, bg_color=color, color_name=color) if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(debug=True, host='0.0.0.0', port=port)
Next, create a requirements.txt
file with the following content:
Flask>=2.0.0 gunicorn>=20.0.0
Lastly create a Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
ENV PYTHONPATH /app
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]
Create the image in Artifact Registry using Buildpacks by using Cloud Build:
gcloud builds submit \
--tag $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME
And deploy the first revision to Cloud Run with a darkseagreen color:
gcloud run deploy $SERVICE_NAME \
--image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \
--region $REGION \
--allow-unauthenticated \
--set-env-vars BG_COLOR=darkseagreen
To test the service, you can open the endpoint directly in your web browser to see the background color as dark sea green.
Now deploy a second revision with a tan background color.
# update the env var BG_COLOR=tan gcloud run deploy $SERVICE_NAME \ --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \ --region $REGION \ --set-env-vars BG_COLOR=tan
Now when you refresh the website, you'll see the tan background color.
Split the traffic 50-50
To split the traffic between the deep sea green and tan revisions, you need to find the revision IDs of the underlying Cloud Run services. You can see the revision IDs by running this command:
gcloud run revisions list --service $SERVICE_NAME \ --region $REGION --format 'value(REVISION)'
You should see results similar to those below
traffic-revisions-color-00003-qoq traffic-revisions-color-00002-zag
You can split the traffic 50/50 between the two revisions by running the following command with your revisions:
gcloud run services update-traffic $SERVICE_NAME \ --region $REGION \ --to-revisions YOUR_REVISION_1=50,YOUR_REVISION_2=50
Test the traffic splitting
You can test the service by refreshing the page in your browser.
Half of the time, you should see the dark sea green revision and, the other half, you'll see the tan revision. You will also see the revision name listed in the output, e.g.
<html><body style="background-color:tan;"><div><p>Hello traffic-revisions-color-00003-qoq</p></div></body></html>
4. Gradual Rollouts
In this section, you'll learn how to gradually rollout changes to a new Cloud Service revision. You can learn more about gradual rollouts in the documentation.
You will use the same code as the previous section, but you will deploy it as a new Cloud Run service.
First, set the background color to beige
and deploy the function with the name gradual-rollouts-colors
.
To deploy a Cloud Run function directly onto Cloud Run, run the following command:
# update the env var BG_COLOR=beige gcloud beta run deploy gradual-rollouts-colors \ --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \ --region $REGION \ --allow-unauthenticated \ --update-env-vars BG_COLOR=$BG_COLOR
Now let's say we want to gradually roll out a new revision with the background color lavender.
First, let's set the current revision beige to receive 100% traffic. This will ensure that your future revisions do not receive any traffic. By default, Cloud Run sets 100% traffic to the revision with the latest
flag. By manually specifying that this current revision beige should receive all the traffic, the revision with the latest
flag will no longer receive 100% traffic. See documentation.
# get the revision name BEIGE_REVISION=$(gcloud run revisions list --service gradual-rollouts-colors \ --region $REGION --format 'value(REVISION)') # now set 100% traffic to that revision gcloud run services update-traffic gradual-rollouts-colors \ --to-revisions=$BEIGE_REVISION=100 \ --region $REGION
You'll see output similar to Traffic: 100% radual-rollouts-colors-00001-yox
Now you can deploy a new revision that will not receive any traffic. Instead of making any code changes, you can update the BG_COLOR environment variable for this revision.
To deploy a Cloud Run function directly onto Cloud Run, run the following command:
# update color BG_COLOR=lavender # deploy the function that will not receive any traffic gcloud beta run deploy gradual-rollouts-colors \ --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \ --region $REGION \ --allow-unauthenticated \ --update-env-vars BG_COLOR=$BG_COLOR
and now when you visit the website in your browser, you'll see the you will see the beige color, even though lavender was the most recently deployed revision.
Test a Revision serving 0% traffic
Suppose you have verified that your revision deployed successfully and that it is serving 0% traffic. Even though it has passed health checks, you still want to verify that this revision is using the lavender background color.
To test the lavender revision, you can apply a tag to that revision. Tagging allows you to directly test the new revision at a specific URL, without serving traffic.
First, get the image URL for that latest revision (which is lavender).
IMAGE_URL_LAVENDER=$(gcloud run services describe gradual-rollouts-colors --region $REGION --format 'value(IMAGE)')
And now tag that image with its associated color.
gcloud run deploy gradual-rollouts-colors --image $IMAGE_URL_LAVENDER --no-traffic --tag $BG_COLOR --region $REGION
You will see output similar to the following:
The revision can be reached directly at https://lavender---gradual-rollouts-colors-<hash>-<region>.a.run.app
Now when you visit that specific revision URL, you'll see the lavender color.
Gradually increasing traffic
Now, you can start sending traffic to the lavender revision. The example below shows how to send 1% of traffic to lavender.
gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-tags lavender=1
To send 50% of traffic to lavender, you can use the same command, but specify 50% instead.
gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-tags lavender=50
You should see a list of how much traffic each revision is receiving.
Traffic: 50% gradual-rollouts-colors-00001-hos 50% gradual-rollouts-colors-00004-mum lavender: https://lavender---gradual-rollouts-colors-<hash>-<region>.a.run.app
When you're ready to fully roll out lavender, you can set lavender to 100% to replace beige.
gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-tags lavender=100
and now when you visit the website, you will only see lavender.
5. Rollbacks
Suppose early UX feedback has come in, indicating the customers prefer beige to lavender, and you need to rollback to beige.
You can roll back to the previous revision (beige) by running this command:
gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-revisions $BEIGE_REVISION=100
and now when you visit the website, you'll see beige as the background color.
You can learn more about rollbacks in the docs.
6. Congratulations!
Congratulations for completing the codelab!
We recommend reviewing the documentation on rollouts, rollbacks, and traffic migration
What we've covered
- How to to split traffic between two or more revisions for a Cloud Run service
- How to roll out a new revision gradually
- How to rollback to a previous revision
7. Clean up
To avoid inadvertent charges, (for example, if this Cloud Run function is inadvertently invoked more times than your monthly Cloud Run invokement allocation in the free tier), you can either delete the Cloud Run service or delete the project you created in Step 2.
To delete a Cloud Run service, go to Cloud Run in the Cloud Console at https://console.cloud.google.com/run/ and delete the functions you created in this codelab.
If you choose to delete the entire project, you can go to https://console.cloud.google.com/cloud-resource-manager, select the project you created in Step 2, and choose Delete. If you delete the project, you'll need to change projects in your Cloud SDK. You can view the list of all available projects by running gcloud projects list
.