In the preceding article titled Store application code on Gitlab, we successfully relocated the code for our Nest.js API application to the GitLab repository.

Now, let’s proceed with the next steps to finalize our journey by deploying the API for user access through the Google Cloud service Cloud Run.

To begin, we must navigate to the Google Cloud Platform (GCP) console. It is assumed that the GCP account and the required project have already been created, as mentioned in the article.

Prepare the Google Cloud environment

In the GCP console’s search field, look for “Enable APIs & services” and click on it:

Click on the button “+ Enable APIS and Services” close to “APIs & Services” title:

In the search field let’s look for “Cloud Run API” and let’s click on the first result:

To enable the API, click the blue button “Enable”

Once the API is enabled, the screen below will appear:

Next, in the “search field” look for “IAM & Admin” and click on it:

and click on “Service accounts” on the left column:

then on the button “+ Create Service Account”

Let’s enter the “Service account” name (anything which make sense) and click “Done” to move to the next step.

In the Role field select “Cloud Run > Cloud Run Admin.” Click the “Add another role” button and add “Cloud Build > Cloud Build Service Agent”.

Repeat the process to add the following roles:

  • “Service Account > Service Account User”
  • “Project > Viewer”
The final list of GCP roles to add

Click “Done” and after a while you will be moved to the screen with the list of the service accounts which will include the new one.

Select it, click on the three dots on the right and choose “Manage keys”:

Then click “Create new key”:

Choose the JSON type and click “Create”:

After a while, the key file can be downloaded to the computer.

The Gitlab CI/CD Pipeline

Now, we need to implement the pipeline to build and deploy our code.

First, we’ll configure the environment variables and the needed secrets in the project. They will be used in the pipeline execution.

Then, we’ll add the pipeline file to our source code.

Configure the Gitlab environment variables for the pipeline

On the Gitlab left menu, select “Settings” > “CI/CD”:

Scroll to “Variables” section and click “Expand”:

Click the button “Add variable” and add the first one, with “BASE64_GOOGLE_CLOUD_CREDENTIALS” as name and paste the result of the following command from the terminal of your laptop

cat path/to/service_account°key.json | base64

in the “value” field:

Be sure to mask it to avoid the value to be printed in the output console of the pipeline.

Repeat the process for the other following variables:

  • PROJECT_ID: putting the project ID from the GCP console
  • SERVICE_ID: we enter the value “my-sport-world” in our case.

The pipeline

The pipeline steps are defined adding the file .gitlab-ci.yml in the root of our project.

The content of the file is:

include:
- template: Auto-DevOps.gitlab-ci.yml

variables:
DAST_WEBSITE: ""
DAST_FULL_SCAN_ENABLED: "true"
DAST_BROWSER_SCAN: "true"
REGION: us-central1

javascript:
image: node:latest
stage: test
before_script:
- 'yarn global add jest'
- 'yarn add --dev jest-junit'
script:
- 'jest --ci --reporters=default --reporters=jest-junit'
artifacts:
when: always
reports:
junit:
- junit.xml

deploy:
stage: deploy
image: google/cloud-sdk:latest
script:
- export GOOGLE_CLOUD_CREDENTIALS=$(echo $BASE64_GOOGLE_CLOUD_CREDENTIALS | base64 -d)
- echo $GOOGLE_CLOUD_CREDENTIALS > service-account-key.json
- gcloud auth activate-service-account --key-file service-account-key.json
- gcloud config set project $PROJECT_ID
- gcloud auth configure-docker
- gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE_ID
- gcloud run deploy $SERVICE_ID --port 3000 --image gcr.io/$PROJECT_ID/$SERVICE_ID --region=$REGION --platform managed --allow-unauthenticated
- export DAST_WEBSITE=$(gcloud run services describe $SERVICE_ID --region=$REGION --platform=managed --format='value(status.url)')
- echo $DAST_WEBSITE > environment_url.txt
artifacts:
paths:
- environment_url.txt

The first directive

include:
- template: Auto-DevOps.gitlab-ci.yml

allow to automatically configure the pipeline with the settings optimized for the project. As described athttps://docs.gitlab.com/ee/topics/autodevops/:

“Auto DevOps detects your programming language and uses CI/CD templates to create and run default pipelines to build and test your application.”

Afterwards, some variables that will be used in the pipeline are declared. DAST_WEBSITE will be filled with the URL of the application once it is deployed (see “deploy” stage below). The DAST step will be the last one of the pipeline: it will test the security of our system.

variables:
DAST_WEBSITE: ""
DAST_FULL_SCAN_ENABLED: "true"
DAST_BROWSER_SCAN: "true"
REGION: "us-central1"

Before the deploy stage the pipeline executes the tests saving the report:

javascript:
image: node:latest
stage: test
before_script:
- 'yarn global add jest'
- 'yarn add --dev jest-junit'
script:
- 'jest --ci --reporters=default --reporters=jest-junit'
artifacts:
when: always
reports:
junit:
- junit.xml

The last step is the “deploy” stage which:

  • retrieve the GCP credentials from the project variables (configured in the previous paragraph), set the service account for our pipeline and configure the correct PROJECT_ID
- export GOOGLE_CLOUD_CREDENTIALS=$(echo $BASE64_GOOGLE_CLOUD_CREDENTIALS | base64 -d)    
- echo $GOOGLE_CLOUD_CREDENTIALS > service-account-key.json
- gcloud auth activate-service-account --key-file service-account-key.json
- gcloud config set project $PROJECT_ID
- gcloud auth configure-docker
  • build and push the image
- gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE_ID
- gcloud run deploy $SERVICE_ID --image gcr.io/$PROJECT_ID/$SERVICE_ID --region=$REGION --platform managed --allow-unauthenticated
  • deploy the application to Cloud Run
- gcloud run deploy $SERVICE_ID --image gcr.io/$PROJECT_ID/$SERVICE_ID --region=$REGION --platform managed --allow-unauthenticated
  • extract the URL for the DAST step and store in the artifact allowing the next steps to use it
- export DAST_WEBSITE=$(gcloud run services describe $SERVICE_ID --region=$REGION --platform=managed --format='value(status.url)')  
- echo $DAST_WEBSITE > environment_url.txt
artifacts:
paths:
- environment_url.txt

The deployment

Pushing the changes to the repository, the pipeline will run. If everything goes well, the “Pipeline” section of Gitlab will show something like that:

The line with the pipeline successfully executed

Clicking on it the steps will be visible:

The pipeline steps

and a clicking on one of the step will show the detail with the console output.

The “Deploy” section

We can explore the “Tests” section where we have the results and go in to the details clicking on the “javascript” job:

“Tests” section
Tests details

An interesting section is also “Security” where the vulnerabilities, found in all the available scans, are listed:

The “Security” section

And finally, the “Licenses” section with an overview of all the types of license of the dependencies and the packages associated to them.

The “Licenses” section

Check the deployment

Now that the pipeline is executed, the Cloud Run screen on GCP shows the deployed application:

and in the details (visible clicking on the service) we can find the URL at the top of the screen (https://my-sport-world-mpuopvwoga-uc.a.run.app in our case):

Now executing the call GET https://my-sport-world-mpuopvwoga-uc.a.run.app/sports we get our result:

--

--

Emanuele Pecorari

Cloud Architect and Tech Product Owner. Soccer player and coach in the free time.