Home Google Cloud Run and GitLab CI/CD
Google Cloud Run and GitLab CI/CD
Cancel

Google Cloud Run and GitLab CI/CD

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:

  1. From the Google Cloud Platform Console, choose “COMPUTE | Cloud Run” from the menu.
  2. Click on the “CREATE SERVICE” link.
  3. For “Service name”, choose “myapp”.
  4. For “Region”, choose “us-west1 (Oregon)”.
  5. Click on the “NEXT” button.
  6. Choose “Deploy one revision from an existing container image”.
  7. For “Container image URL”, enter “gcr.io/PROJECT-ID/myapp”.
  8. Click on the “NEXT” button.
  9. For “Ingress”, choose “Allow all traffic”.
  10. For “Authentication”, choose “Allow unauthenticated invocations”.
  11. Click on the “CREATE” button.
  12. 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:

gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/myapp

You can test the image as follows:

docker run --rm --env PORT=8080 -it -p 8080:8080 gcr.io/$GOOGLE_CLOUD_PROJECT/myapp

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:

gcloud run deploy myapp --image gcr.io/$GOOGLE_CLOUD_PROJECT/myapp --platform managed --region us-west1 --allow-unauthenticated

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:

default:
    image: google/cloud-sdk:alpine
    before_script:
        - gcloud config set project $GOOGLE_CLOUD_PROJECT

build:
    stage: build
    script:
        - gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/myapp

deploy:
    stage: deploy
    script:
        - gcloud run deploy myapp --image gcr.io/$GOOGLE_CLOUD_PROJECT/myapp --platform managed --region us-west1 --allow-unauthenticated

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:

git add .
git commit -m "define initial CI/CI pipeline"
git push

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:

$ gcloud config set project $GOOGLE_CLOUD_PROJECT
ERROR: (gcloud.config.set) argument VALUE: Must be specified.
Usage: gcloud config set SECTION/PROPERTY VALUE [optional flags]
  optional flags may be  --help | --installation
For detailed information on this command and its flags, run:
  gcloud config set --help
Cleaning up file based variables
00:00
ERROR: Job failed: exit code 1

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:

$ gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/myapp
ERROR: (gcloud.builds.submit) You do not currently have an active account selected.
Please run:
  $ gcloud auth login
to obtain new credentials.
If you have already logged in with a different account:
    $ gcloud config set account ACCOUNT
to select an already authenticated account to use.
Cleaning up file based variables
00:01
ERROR: Job failed: exit code 1

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:

- gcloud auth activate-service-account --key-file $GOOGLE_CLOUD_CREDENTIALS

Stage, commit, and push the changes as follows:

git add .
git commit -m "add service account credentials to pipeline"
git push

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.