Learning Outcomes
- deploy an application to a managed container service (e.g. Google Cloud Run)
- implement CI/CD for an application using a 3rd party service (e.g. GitLab CI/CD)
Resources
Lab
Video walkthrough of this lab.
Deploying a Container to Cloud Run
Running the container in the Cloud Shell environment is fine for development but only you can access it and only while the shell is running. You can deploy a container to a virtual machine but you still have to manage the VM. Alternatively, you can use a container runtime service like Google Cloud Run which abstracts away the underlying VMs and also handles scaling automatically.
You can deploy the container image to Google Cloud Run as follows:
- From the Google Cloud Platform Console, choose “COMPUTE | Cloud Run” from the menu.
- Click on the “CREATE SERVICE” link.
- For “Service name”, choose “myapp”.
- For “Region”, choose “us-west1 (Oregon)”.
- Click on the “NEXT” button.
- Choose “Deploy one revision from an existing container image”.
- For “Container image URL”, enter “gcr.io/PROJECT-ID/myapp”.
- Click on the “NEXT” button.
- For “Ingress”, choose “Allow all traffic”.
- For “Authentication”, choose “Allow unauthenticated invocations”.
- Click on the “CREATE” button.
- In a few minutes, you should get a URL for your app that you can try out.
Automate Deployment of a Container to Cloud Run using GitLab CI/CD
Build and Deploy the Application Using the CLI Tools
Start up your Google Cloud Shell.
In the Containers lab exercise, we built the container image and pushed it to a container registry using “docker build …” and “docker push …”. Unfortunately, we can’t use the docker commands inside the CI/CD pipeline inside GitLab. Instead we’ll use Google Cloud Build to build the container image. Before building the pipeline, we’ll do everything by hand first to make sure it is going to work.
Change to the project directory with cd myapp
.
Make a visible change to either the “index” route or view so that you will know the application has changed.
Instead of “docker build …” and “docker push …” use “gcloud builds …” as follows:
You can test the image as follows:
Test the app using “Web Preview” in the Cloud Shell environment. When you are satisfied that everything is working, stop the container with CTRL-C.
Finally, deploy the app to Cloud Run as follows:
The command will output the URL for the deployed app. Test it out in your browser.
Build the GitLab CI/CD Pipeline
The next step is the to automate the build and deploy steps with a GitLab CI/CD pipeline.
Create a .gitlab-ci.yml
file in the project directory that defines the pipeline as follows:
The defualt image identifies the default container image to use for the jobs in the pipeline. In this case, we are using the google/cloud-sdk:alpine
image because it contains the gcloud
command.
The default “before_script” contains the list of commands to execute before each job. In this case, we just set the default GCP project.
This pipleine has two jobs named “build” and “deploy”. The “build” job is run during the “build” stage and the “deploy” job is run during the “deploy” stage. “script” lists the commands to be run for the job.
Stage, commit, and push the changes as follows:
If you look at the GitLab log for the “build” stage of the pipeline, you will see that it failed with a message similar to this:
This is because in the Google Cloud Shell, the $GOOGLE_CLOUD_PROJECT
variable is already set for us. This variable is not part of the GitLab CI/CD environment, so we will have to set it manually.
Go to the “Settings | CI/CD” page for the project in GitLab. Expand the “Variables” section. Click on the “Add Variable” button. For the “Key” field, enter “GOOGLE_CLOUD_PROJECT”. For the “Value” field, enter your project ID. Click on the “Add Variable” button. Now if you go back to the “CI/CD | Pipelines” page, you can retry the pipeline.
The “build” stage still fails with a message similar to the following:
When we built the app in the Cloud Shell environment, we never had to supply authentication credentials because we were already logged into the GCP environment. Because GitLab is external to Google Cloud Platform, we are going to have supply credentials to allow GitLab CI/CD to access GCP resources.
Use GCP Credentials in a GitLab CI/CD Pipeline
First, use the GCP Console to create a service account with the appropriate permissions to build and deploy an app that we can use in the GitLab CI/CD Pipeline.
From the GCP menu, choose “IAM & Admin | Service Accounts”. Click on the “CREATE SERVICE ACCOUNT” link. For “Service account name”, type “gitlab”. The “Service account ID” field should get filled in automatically. For “Service account description”, enter “GitLab CI/CD”. Click on the “CREATE” button. Add the following roles:
- Project | Viewer
- Cloud Build | Cloud Build Service Account
- Cloud Run | Cloud Run Admin
- Service Management | Cloud Run Service Agent
Click on the “CONTINUE” button. Click on the “DONE” button.
You should see the new service account listed. At the end of the row, click on the three dots and choose “Manage keys” from the menu. Click on the “ADD KEY” button. Choose “Create new key”. Make sure “JSON” is selected and click on the “CREATE” button. The private key will be downloaded to your computer, probably in the “Downloads” folder. Click on the “CLOSE” button.
Open up the downloaded private key in a text editor.
Go to the “Settings | CI/CD” page for the project in GitLab. Expand the “Variables” section. Click on the “Add Variable” button. For the “Key” field, enter “GOOGLE_CLOUD_CREDENTIALS”. For the “Value” field, paste the contents of the private key file. For “Type”, choose “File”. Under “Flags”, check “Protect” variable. Click on the “Add Variable” button.
Now we have to go back to the CI/CD pipeline definition and incorporate the service credentials. In the “before_script” section of the .gitlab-ci.yml
file, add:
Stage, commit, and push the changes as follows:
Both jobs should complete successfully now. Check that the application is still running. Make another visible change to the “index” route or view. Stage, commit, and push the change. Confirm that the change appears on the running application.