Deploying Cloud Run Application with Cloud Deploy

1. Overview

In this lab, you will deploy a .Net application to Cloud Run using Cloud Deploy. You will build a container image with Cloud Build without using Dockerfile. You will set up a pipeline with three target environments with Cloud Deploy and go through the steps to promote the release through environments. Finally you will approve the release to be deployed to the production environment.

916a54f51af5ee54.png

What is Cloud Build?

With Cloud Build you can build software quickly across all programming languages.

What is Cloud Deploy?

Cloud Deploy is a fully managed continuous delivery service. With Cloud Deploy you can create deployment pipelines for GKE, Anthos and Cloud Run.

What is Cloud Run?

With Cloud Run you can deploy scalable containerized applications written in any language (including Go, Python, Java, Node.js, .NET, and Ruby) on a fully managed platform.

What is Skaffold?

Skaffold is a command-line tool that enables continuous development for Kubernetes-native applications. Cloud Deploy uses Skaffold for render and deploy operations.

What you will learn

In this lab, you will learn how to do the following:

  • Create Cloud Deploy pipeline
  • Create container image for .Net application with Cloud Build without using Dockerfile
  • Deploy application to Cloud Run with Cloud Deploy
  • Promote Cloud Deploy releases

Prerequisites

  • This lab assumes familiarity with the Cloud Console and shell environments.

2. Setup and Requirements

Cloud Project setup

  1. 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.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • The Project name is the display name for this project's participants. It is a character string not used by Google APIs. You can update it at any time.
  • The Project ID must be 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 the Project ID (it is typically identified as PROJECT_ID). If you don't like the generated ID, you may generate another random one. Alternatively, you can try your own and see if it's available. It cannot be changed after this step and will remain 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.
  1. Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab shouldn't cost much, if anything at all. To shut down resources so you don't incur billing beyond this tutorial, you can delete the resources you created or delete the whole project. New users of Google Cloud are eligible for the $300 USD Free Trial program.

Environment Setup

Activate Cloud Shell by clicking on the icon to the right of the search bar.

eb0157a992f16fa3.png

From the Cloud Shell, run the following command to set project environment variables:

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
export REGION=us-central1

Enable APIs:

gcloud services enable \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  clouddeploy.googleapis.com \
  artifactregistry.googleapis.com

Create Artifact Registry repository to store application container images:

gcloud artifacts repositories create containers-repo \
  --repository-format=docker \
  --location=${REGION} \
  --description="Containers repository"

3. Review configuration files

29c2533441779de0.png

Clone application source code:

git clone https://github.com/gitrey/deploy-cloudrun-app-with-clouddeploy.git
cd deploy-cloudrun-app-with-clouddeploy

Review Cloud Deploy pipeline config:

clouddeploy.yaml

apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
 name: cloud-run-pipeline
description: application deployment pipeline
serialPipeline:
 stages:
 - targetId: dev-env
   profiles: [dev]
 - targetId: qa-env
   profiles: [qa]
 - targetId: prod-env
   profiles: [prod]
---

apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
 name: dev-env
description: Cloud Run development service
run:
 location: projects/_PROJECT_ID/locations/us-west1
---

apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
 name: qa-env
description: Cloud Run QA service
run:
 location: projects/_PROJECT_ID/locations/us-central1
---

apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
 name: prod-env
description: Cloud Run PROD service
run:
 location: projects/_PROJECT_ID/locations/us-south1

Review skaffold.yaml file that defines three environments, and it's using Cloud Run as target service.

skaffold.yaml

apiVersion: skaffold/v3alpha1
kind: Config
metadata: 
  name: cloud-run-app
profiles:
- name: dev
  manifests:
    rawYaml:
    - deploy-dev.yaml
- name: qa
  manifests:
    rawYaml:
    - deploy-qa.yaml
- name: prod
  manifests:
    rawYaml:
    - deploy-prod.yaml
deploy:
  cloudrun: {}

Review service configuration files.

deploy-dev.yaml

kind: Service
metadata:
  name: app-dev
spec:
  template:
    spec:
      containers:
      - image: app
        resources:
          limits:
            cpu: 1000m
            memory: 128Mi

deploy-qa.yaml

kind: Service
metadata:
  name: app-dev
spec:
  template:
    spec:
      containers:
      - image: app

deploy-prod.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: app-prod
spec:
  template:
    spec:
      containers:
      - image: app

Review cloudbuild.yaml file with steps to build a container image and to create Cloud Deploy release:

cloudbuild.yaml

steps:
- name: 'gcr.io/k8s-skaffold/pack'
  entrypoint: 'pack'
  args: ['build',
         '--builder=gcr.io/buildpacks/builder',
         '--publish', '${_REGION}-docker.pkg.dev/${PROJECT_ID}/containers-repo/app:$BUILD_ID']
  id: Build and package .net app
- name: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
  args: 
      [
        "deploy", "releases", "create", "release-$_RELEASE_TIMESTAMP",
        "--delivery-pipeline", "cloud-run-pipeline",
        "--region", "${_REGION}",
        "--images", "app=${_REGION}-docker.pkg.dev/${PROJECT_ID}/containers-repo/app:$BUILD_ID"
      ]
  entrypoint: gcloud

4. Create Cloud Deploy Pipeline

Replace _PROJECT_ID value in the clouddeploy.yaml:

sed -i "s/_PROJECT_ID/$PROJECT_ID/g" clouddeploy.yaml

Create Cloud Deploy pipeline:

gcloud deploy apply \
  --file=clouddeploy.yaml \
  --region=${REGION} \
  --project=${PROJECT_ID}

Review created pipeline in Cloud Deploy.

5. Build Container image and create a release

Add Cloud Deploy Operator permissions to Cloud Build service account:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
    --role=roles/clouddeploy.operator

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
    --role=roles/iam.serviceAccountUser

Create container image and Cloud Deploy release:

export RELEASE_TIMESTAMP=$(date '+%Y%m%d-%H%M%S')

gcloud builds submit \
  --config cloudbuild-plus.yaml \
  --substitutions=_REGION=${REGION},_RELEASE_TIMESTAMP=${RELEASE_TIMESTAMP}

Review created release in Cloud Deploy. Wait until deployment to the Dev environment is complete.

6. Promote release to QA and PROD environments

Using Cloud Console or Cloud Shell, promote release to the next target(qa-env).

Promote the release with Cloud Shell, run gcloud command to promote the release.

gcloud beta deploy releases promote \
    --release="release-${RELEASE_TIMESTAMP}" \
    --delivery-pipeline=cloud-run-pipeline \
    --region=${REGION} \
    --quiet

Wait until deployment to QA environment is done. Promote release to the next target(prod-env).

gcloud beta deploy releases promote \
    --release="release-${RELEASE_TIMESTAMP}" \
    --delivery-pipeline=cloud-run-pipeline \
    --region=${REGION} \
    --quiet

Open Cloud Deploy in Cloud Console and approve the release for production deployment.

4c838b60770e9691.png

Review Cloud Deploy pipeline state and available DORA metrics ("deployment count", "deployment frequency", "deployment failure rate").

Metric

Description

Number of deployments

The total number of successful and failed deployments to the final target in your delivery pipeline.

Deployment frequency

How often the delivery pipeline deploys to the final target in your delivery pipeline.One of the four key metrics defined by the DevOps Research and Assessment (DORA) program.

Deployment failure rate

The percentage of failed rollouts to the final target in your delivery pipeline.

Review deployed applications in Cloud Run:

d6372b5350f10875.png

7. Congratulations!

Congratulations, you finished the codelab!

What we've covered:

  • How to create Cloud Deploy pipeline
  • How to create container image for .Net application with Cloud Build
  • How to deploy application to Cloud Run with Cloud Deploy
  • How to promote Cloud Deploy release

Clean up

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.

Deleting the project

The easiest way to eliminate billing is to delete the project that you created for the tutorial.