Learning Outcomes
- define continuous integration (CI)
- define continuous delivery (CD)
- define continuous deployment(CD)
- distinguish between development, testing (or staging), and production environments
- construct a CI / CD pipeline to deliver a simple work product
Resources
- Continuous Integration & Continuous Deployment: CI/CD (video)
- What is Continuous Integration
- Gitlab CI pipeline tutorial for beginners
- slides
- narated slides (video)
Lab
Video walkthrough of this lab.
Create a Pipeline to Build and Deploy an Express Application to Google Cloud Run
Build and Deploy the Application by Hand
Fork this project in GitLab: https://gitlab.com/langara/cicd2
.
After forking, go to “Settings | General | Advanced” and remove the fork relationship.
Go to “Settings | General | Visibility …” and make the project visibility private and save the changes.
Start up your Google Cloud Shell.
Clone the project using “git clone {your project SSH URL}”.
In the Containers lab exercise, we built the container image and pushed it to a container registry using “docker build …” and “docker push …”. Unfortuneately, we can’t use the docker commands insid 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 cicd2
.
Instead of “docker build …” and “docker push …” use “gcloud builds …” as follows:
You will have to replace PROJECT-ID
with your actual GCP project ID.
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 GitLap CI/CD pipeline.
Create a .gitlab-ci.yml
file in the project directory that defines the pipeline as follows:
Don’t forget to replace PROJECT-ID
with your actual GCP project ID.
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:
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.
Using GCP Credentials in a GitLab CI/CD Pipeline
First, use the GCP Console to create a service account with the appropriate permissions to 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. For “Service account permisisons”, 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 “CREATE KEY” button. 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 “DONE” 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 “GCP_SERVICE_CREDS”. For the “Value” field, pasted 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 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 a visible change to the views/index.ejs
file. Stage, commit, and push the change. Confirm that the change appears on the running application.
Assignment
- For the “calculator” project from the previous assignment, implement CI/CD.
- Modify the pipeline so that the GCP project ID isn’t hard-coded in the scripts but instead comes from a CI/CD variable.
- Create additional jobs in the
.gitlab-ci.yml
file that build and deploy tocalculator
for commits to themaster
branch and tocalculator-test
for commits to any other branches. Userules:if
clauses. Hint: the $CI_COMMIT_REF_NAME variable has the name of the branch for a commit. - Create a separate branch to confirm that the rules work.