About this codelab
1. Objectives
In this tutorial you will create three GKE clusters named preview, canary and prod. Then, create a Cloud Deploy target corresponding to each cluster and a Cloud Deploy pipeline that will define the sequence of steps to perform deployment in those targets.
The deployment flow will be triggered by a cloudbuild pipeline that will create Cloud Deploy release and perform the deployment in the preview cluster. After you have verified that the deployment in preview was successful and working as expected, you will manually promote the release in the canary cluster. Promotion of the release in the prod cluster will require approval, you will approve the prod pipeline in Cloud Deploy UI and finally promote it.
The objectives of this tutorial can be broken down into the following steps:
- Prepare your workspace
- Define Cloud Deploy targets
- Define Cloud Deploy pipeline
- Create a Release
- Promote a deployment
- Approve a production release
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, and 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 (and it is typically identified as
PROJECT_ID
), so if you don't like it, generate another random one, or, you can try your own and see if it's available. Then it's "frozen" after the project is created. - 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 in order 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, follow any "clean-up" instructions found at the end of the codelab. New users of Google Cloud are eligible for the $300 USD Free Trial program.
2. Platform Setup
Preparing your workspace
We will set up our environment here required to run this tutorial. When this step is completed, we will have a GKE cluster created where we can run the deployments.
- Set gcloud config defaults
gcloud config set project <your project>
gcloud config set deploy/region us-central1
- Clone Repo
git clone https://github.com/gushob21/software-delivery-workshop
cd software-delivery-workshop/labs/cloud-deploy/
cloudshell workspace .
rm -rf deploy && mkdir deploy
- Set environment variables
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects list --filter="$PROJECT_ID" --format="value(PROJECT_NUMBER)")
- Enable APIs
gcloud services enable \
cloudresourcemanager.googleapis.com \
`container.googleapis.com \`
`cloudbuild.googleapis.com \`
`containerregistry.googleapis.com \`
`secretmanager.googleapis.com \`
`clouddeploy.googleapis.com`
- Create GKE clusters
`gcloud container clusters create preview \`
--zone=us-central1-a --async
`gcloud container clusters create canary \`
--zone=us-central1-b --async
`gcloud container clusters create prod \`
--zone=us-central1-c
Defining Cloud Deploy Targets
- Create a file in the deploy directory named preview.yaml with the following command in cloudshell:
cat <<EOF >deploy/preview.yaml
apiVersion: deploy.cloud.google.com/v1beta1
kind: Target
metadata:
name: preview
annotations: {}
labels: {}
description: Target for preview environment
gke:
cluster: projects/$PROJECT_ID/locations/us-central1-a/clusters/preview
EOF
As you noticed, the "kind" tag is "Target". It allows us to add some metadata to the target, a description and finally the GKE cluster where the deployment is supposed to happen for this target.
- Create a file in the deploy directory named canary.yaml with the following command in cloudshell:
cat <<EOF >deploy/canary.yaml
apiVersion: deploy.cloud.google.com/v1beta1
kind: Target
metadata:
name: canary
annotations: {}
labels: {}
description: Target for canary environment
gke:
cluster: projects/$PROJECT_ID/locations/us-central1-b/clusters/canary
EOF
- Create a file in the deploy directory named prod.yaml with the following command in cloudshell:
cat <<EOF >deploy/prod.yaml
apiVersion: deploy.cloud.google.com/v1beta1
kind: Target
metadata:
name: prod
annotations: {}
labels: {}
description: Target for prod environment
requireApproval: true
gke:
cluster: projects/$PROJECT_ID/locations/us-central1-c/clusters/prod
EOF
Notice the tag requireApproval which is set to true. This will not allow promotion into prod target until the approval is granted. You require roles/clouddeploy.approver role to approve a release.
- Create the Deploy Targets
`gcloud config set deploy/region us-central1`
gcloud beta deploy apply --file deploy/preview.yaml
gcloud beta deploy apply --file deploy/canary.yaml
gcloud beta deploy apply --file deploy/prod.yaml
3. App Creation
As part of the creation of a new application the CICD pipeline is typically setup to perform automatic builds, integration testing and deployments. The following steps are considered part of the setup process for a new app. Each new application will have a deployment pipeline configured.
Defining Cloud Deploy pipeline
- Create a file in the deploy directory named pipeline.yaml with the following command in cloudshell:
cat <<EOF >>deploy/pipeline.yaml
apiVersion: deploy.cloud.google.com/v1beta1
kind: DeliveryPipeline
metadata:
name: sample-app
labels:
`app: sample-app`
description: delivery pipeline
serialPipeline:
stages:
- targetId: preview
`profiles:`
`- preview`
- targetId: canary
`profiles:`
`- canary`
- targetId: prod
`profiles:`
`- prod`
EOF
As you noticed, the "kind" tag is "DeliveryPipeline". It lets you define the metadata for the pipeline, a description and an order of deployment into various targets via serialPipeline tag.
serialPipeline
tag contains a tag named stages which is a list of all targets to which this delivery pipeline is configured to deploy.
targetId
identifies the specific target to use for this stage of the delivery pipeline. The value is the metadata.name property from the target definition.
profiles
is a list of zero or more Skaffold profile names, from skaffold.yaml. Cloud Deploy uses the profile with skaffold render when creating the release.
- Apply Pipeline
gcloud beta deploy apply --file deploy/pipeline.yaml
4. Development Phase
As the applications are developed automated CICD toolchains will build and store assets. The following commands are executed to build the application using skaffold and store assets for deployment with Cloud Deploy. This step would be performed by your CICD process for every application build.
- Build and store the application with skaffold
skaffold build \
--file-output=artifacts.json \
--default-repo gcr.io/$PROJECT_ID \
--push=true
5. Release Phase
At the end of your CICD process, typically when the code is Tagged for production, you will initiate the release process by calling the cloud deploy release
command. Later once the deployment has been validated and approved you'll move the release through the various target environments by promoting and approving the action through automated processes or manual approvals.
Creating a release
We created Cloud Deploy files in this tutorial earlier to get an understanding of how Cloud Deploy works. For the purpose of demo, we have created the same Cloud Deploy files and pushed them to a github repo with a sample go application and we will use Cloud Deploy to do the release of that application.
export REL_TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
gcloud beta deploy releases create \
sample-app-release-${REL_TIMESTAMP} \
--delivery-pipeline=sample-app \
--description="Release demo" \
--build-artifacts=artifacts.json \
--annotations="release-id=rel-${REL_TIMESTAMP}"
Review the release
When a Cloud Deploy release is created, it automatically rolls it out in the first target which is preview.
- Go to <Cloud Deploy> in Google cloud console
- Click on "sample-app"
On this screen you will see a graphic representation of your pipeline.
- Confirm a green outline on the left side of the preview box which means that the release has been deployed to that environment.
- Optionally review additional details about the release by clicking on the release name under Release Details in the lower section of the screen
- Verify that the release successfully deployed the application, run the following command it cloushell
gcloud container clusters get-credentials preview --zone us-central1-a && kubectl port-forward --namespace default $(kubectl get pod --namespace default --selector="app=cloud-deploy-tutorial" --output jsonpath='{.items[0].metadata.name}') 8080:8080
- Click on the web preview icon in the upper right of the screen.
- Select Preview on port 8080
This will take you to a new page which shows the message "Hello World!"
- Use
ctrl+c
in the terminal to end the port-forward.
Promoting a release
Now that your release is deployed to the first target (preview) in the pipeline, you can promote it to the next target (canary). Run the following command to begin the process.
gcloud beta deploy releases promote \
--release=sample-app-release-${REL_TIMESTAMP} \
--delivery-pipeline=sample-app \
--quiet
Review the release promotion
- Go to the sample-app pipeline in the Google Cloud console
- Confirm a green outline on the left side of the Canary box which means that the release has been deployed to that environment.
- Verify the application is deployed correctly by creating a tunnel to it
gcloud container clusters get-credentials canary --zone us-central1-b && kubectl port-forward --namespace default $(kubectl get pod --namespace default --selector="app=cloud-deploy-tutorial" --output jsonpath='{.items[0].metadata.name}') 8080:8080
- Click on the web preview icon in the upper right of the screen.
- Select Preview on port 8080
This will take you to a new page which shows the message "Hello World!"
- Use
ctrl+c
in the terminal to end the port-forward.
Approving a production release
Remember when we created prod target via prod.yaml, we specified the tag requireApproval as true. This will force a requirement of approval for promotion in prod.
- Promote the canary release to production with the following command
gcloud beta deploy releases promote \
--release=sample-app-release-${REL_TIMESTAMP} \
--delivery-pipeline=sample-app \
--quiet
- Go to the sample-app pipeline in the Google Cloud console
- Notice the yellow indicator noting "1 pending".
This message indicates there is a release queued for deployment to production but requires review and approval.
- Click on the "Review" button just below the yellow notice.
- In the next screen click "Review" again to access the approval screen for production
- Optionally review the Manifest Diff to review the changes. In this case a whole new file.
- Click on the "Approve" button
- Return to the sample-app pipeline page where you will see the release to prod in progress.
Review the production release
As with the other environments you can review the deployment when it completes using the steps below.
- Run the following command it cloudshell to create the port-forward
gcloud container clusters get-credentials prod --zone us-central1-c && kubectl port-forward --namespace default $(kubectl get pod --namespace default --selector="app=cloud-deploy-tutorial" --output jsonpath='{.items[0].metadata.name}') 8080:8080
- Click on the web preview icon in the upper right of the screen.
- Select Preview on port 8080
This will take you to a new page which shows the message "Hello World!"
- Use
ctrl+c
in the terminal to end the port-forward.