Promoting pre-prod to production in Cloud Run with Google Cloud Deploy
Anthony Bushong
Developer Relations Engineer
Deploying your first container to Cloud Run is famously intuitive. The magic of typing gcloud run deploy
and watching your container run never really gets old for me.
With that said, even serverless platforms like Cloud Run should have some rigor around how they promote versions of your workload from pre-production environments to production - especially as your service grows in usage and in the number of team members involved with its development.
Let's review two key implementation details you can practice with your services in Cloud Run:
Isolating pre-prod environments like
test
andstaging
as individual Services in Cloud RunUsing Google Cloud Deploy to promote a version of your workload across the environments before promoting to
production
If you want to jump directly into our interactive tutorial on this topic, here you go!
Isolating pre-prod environments in Cloud Run
Now, it might be helpful to start by discussing what you get out of the box when following that golden path of gcloud run deploy
.
By default, every Cloud Run Service has the concept of Revisions, with each Service owning multiple Revisions. Cloud Run provides traffic shaping across these revisions. This is incredibly useful, requiring little configuration to implement patterns such as A/B testing or canary deployments.
But using Revisions as the means of separating pre-prod environments, such as development/test, QA, or staging, from prod can be a bit brittle. Now, in theory, you could find some separation by using this approach to isolate pre-production from prod. In this case, you would deploy a Revision, send 0% of traffic to it, and test it out using traffic tags, giving you a unique URL to test the service.
This might be good for one off testing or simple QA processes. However, when it comes to stronger levels of isolation between your pre-prod and prod environments, along with a larger set of folks involved in development, you may run into trouble.
Consider IAM roles - these at their most granular are scoped to a Service for Cloud Run, not a Revision. Thus with the goal of practicing the principle of least privilege, you stand to gain far more from a guardrail perspective by isolating these pre-production versions of your workload to their own Cloud Run Services.
If you've implemented individual Cloud Run Services as representations of your pre-prod and prod environments - a natural question follows: how do you promote these versions across each environment?
Promoting from pre-prod to prod in Cloud Run with Cloud Deploy
This is where Cloud Deploy comes in. Cloud Deploy provides a serverless continuous delivery platform to run pipelines that can automate and codify how you promote versions of a containerized application through isolated pre-prod and production Cloud Run environments.
In Cloud Deploy, you can define your typical promotion sequence in what's called a Delivery Pipeline. This Pipeline references the different Targets through which you want to promote a new version of your workload (Release). Deploying a new version of your workload to your Targets using this Pipeline is called a Rollout. You can see a visual representation of these resources in the following diagram.
Now of course, as much as we'd love to push the hallowed "dev-prod parity", the reality is that usually there's some config or environment variable you may want to change between these environments. You can signal these differences to Cloud Deploy by using a Skaffold skaffold.yaml
file. In this config, you can specify a profiles
stanza, which Cloud Deploy uses to render the changes as you promote a Release to different targets, creating Rollouts.
In this example, given that Cloud Run is compatible with the Knative API, the Cloud Run Services are defined using the Knative spec and the environment-specific environment variables are defined in the spec.template.spec.containers.env
field of each respective .yaml
file.
You'll notice that each of these profiles matches the Targets of the Cloud Run environments you want to deploy to. Each of these profiles also reference a different .yaml
file under manifests.rawYaml
; this is to make sure that the small changes you want to see in each environment are realized. While we are using this method for the simplicity of the tutorial, in practice you would automate the creation of these environment-specific manifests using tooling such as Kustomize.
Finally, Cloud Deploy also enables you to provide a manual approval process in which you can use IAM roles to designate a specific subset of developers or administrators who can actually promote a Release into production. This buys approvers time to observe how pre-prod environments behave under various tests in your test suite.
With this setup in Cloud Run and Cloud Deploy, you should now be ready to move end-to-end from pre-prod all the way to production!
What next?
We laughed, we cried, and we dove into two key areas you should consider when designing pre-prod and prod environments Cloud Run:
Isolate pre-prod environments like
test
andstaging
as individual Services in Cloud RunUse Cloud Deploy to promote a version of your workload across pre-prod environments before promoting to
production
If you want to test this out in real life, check out our interactive tutorial.
A special thanks to Henry Bell, S. Bogdan, and Rakesh Dhoopar for their review on this blog post.