Gitlab CI Course Notes: Release March 2020
Gitlab CI Course Notes: Release March 2020
1 About 1
2 Introduction 3
2.1 Your first pipeline in Gitlab CI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Gitlab architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Why Gitlab / Gitlab CI? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 How much does Gitlab cost? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4 Gitlab CI Fundamentals 15
4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2 Predefined environment variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.3 Pipeline triggers / Retrying failed jobs / Pipeline schedules . . . . . . . . . . . . . . . . . . . . . . . 16
4.4 Using caches to optimize the build speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.5 Cache vs Artifacts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.6 Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.7 Defining variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.8 Manual deployments / Manually triggering jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.9 Merge Requests: Using Branches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.10 Merge requests: Configuring Gitlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.11 Merge requests: Your first merge request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.12 Dynamic environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.13 Destroying environments (Clean-up after the Merge Request) . . . . . . . . . . . . . . . . . . . . . 22
i
5 YAML Basics 23
5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.2 Understanding YAML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.3 Using anchors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6 Using Gitlab CI to build and deploy a Java application to AWS Elastic Beanstalk 25
6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.2 Introduction to the Java application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.3 Running the application in Postman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
6.4 Continuous Integration (CI) pipeline overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
6.5 Smoke test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6.6 CI/CD pipeline recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6.7 Brief introduction to Amazon Web Services (AWS) . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
6.8 Serverless computing with AWS Elastic Beanstalk . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
6.9 Manually deploying a Java application to AWS Elastic Beanstalk . . . . . . . . . . . . . . . . . . . 29
6.10 How to deploy to AWS from GitLab CI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
6.11 Getting started with AWS S3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
6.12 GitLab Group settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
6.13 How to upload a file to AWS S3 from GitLab CI . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6.14 How to deploy a Java application to AWS Elastic Beanstalk using the AWS CLI . . . . . . . . . . . 30
6.15 Create an application version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6.16 Verify the application version after deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6.17 Ensuring coding standards with tools for codestyle checking . . . . . . . . . . . . . . . . . . . . . . 31
6.18 Introduction to unit testing in CI pipelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
6.19 Unit test stage: Run JUnit tests with GitLab CI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
6.20 How to structure a CI/CD pipeline in GitLab CI? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
6.21 API test stage: Run Postman API tests in GitLab CI . . . . . . . . . . . . . . . . . . . . . . . . . . 32
6.22 GitLab Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
ii
CHAPTER 1
About
I have created these course notes for the students of the “Gitlab CI: Pipelines, CI/CD and DevOps for Beginners”
online course on Udemy. If you are not a student yet, consider registering so that you can take full advantages of this
material.
It is additional material for the students that prefer to take notes. You can easily print the entire course content and add
your notes.
I did my best to put this together, but it is not perfect. If you spot any spelling mistakes or would like to contribute and
make this better, feel free to send me a Pull Request on github.com
Enjoy!
- Valentin
1
Gitlab CI Course Notes, Release March 2020
2 Chapter 1. About
CHAPTER 2
Introduction
• In this first video, we are going to create a very simple pipeline in Gitlab
• what is a pipeline anyway?
• the analogy to an assembly line needed to build a car
• notice a few characteristics:
– a series of steps that need to be done on a certain order
– the steps are connected
– the output from the previous step is the input for the next step
– some steps could be done in parallel (wheels)
• many more steps are required to build the final product
• not only the production part is important but also the final testing part before the car goes to the consumer
• the goal is to get the product out of the factory
• you will later see that building and delivering software is, in some regard, quite similar to the step needed to
manufacture a car
• let’s try to build something similar with Gitlab CI and have two major stages:
– build & test
– Build a car assembly line using Gitlab CI
– Add chassis
– Add engine
3
Gitlab CI Course Notes, Release March 2020
– Add wheels
• later in the test phase, we will test it.
• to get started with Gitlab CI you do not need to download any software or anything similar
• create a free account at gitlab.com
• create a new project. This will we a normal Git repository with nothing inside
• new file .gitlab-ci.yaml
• as in the car assembly, in a software pipeline, we also have a series of steps or jobs what we need to perform
• always use spaces for indentation, not tabs.
• after committing, Gitlab will create the pipeline for us
• every time we make a change in the repository, the pipeline will start
• GitLab will execute your scripts with the tool called GitLab Runner, which runs similarly to your terminal
• Gitlab does not save anything unless told so
• we will use artifacts to save the car.txt file
• inspect final artifact
• where is the build folder in the repository?
• nothing is automatically committed to the repository
4 Chapter 2. Introduction
Gitlab CI Course Notes, Release March 2020
• Gitlab is a modern tool, and Gitlab will probably become one of the market leaders in the next years
• Gitlab offers:
– a modern, scalable architecture
– you can easily work with Docker
– pipeline as a code
– partially open source
• you need to try it on your own and see if it solves YOUR problems
6 Chapter 2. Introduction
CHAPTER 3
* making sure it can be installed (by actually installing the package on a system similar to pro-
duction)
* run additional tests to check if the package integrates with other systems
– after a manual check/decision, the package can be installed on a production system as well
• CD can also stand for Continuous Deployment
– CD goes a step further and automatically installs every package to production
7
Gitlab CI Course Notes, Release March 2020
• the advantages of CI
– detecting errors early in the development process
– reduces integration errors
– allow developers to work faster
• the advantages of CD
– ensure that every change is releasable
– reduces the risk of a new deployment
– delivers value much faster (changes are released more often)
• we can use the alpine Docker image to optimize our build speed
• alpine images are only 5MB in size and are faster to download and start
• we can use Gatsby to start a server from the production build (the public folder)
• when we start a server with the website, we can run other kinds of tests
• we use gatsby server to start a local server
• we want to start a server with our website and check if it works
• we can use curl to download a copy of the website using HTTP (similar to what a standard browser does)
• pipes (|) are used to use the output from one command as the input for another
• assigning two jobs to the same stage makes them run in parallel
• when planning to run parallel jobs, you need to make sure there are no dependencies between them
YOUR NOTES
• do not store any credentials (username, passwords, tokens) in your pipeline OR project files
• with Gitlab you can define environment variables that contain secrets
• environment variables will be available when running the pipeline
• in order to deploy with surge from Gitlab, we need to generate a token: surge token
• we do not want to give Gitlab our username (email) and password, so a token is a better alternative
• to create an environment variable from your project to Settings > CI/CD
• the variables that we will use are SURGE_LOGIN and SURGE_TOKEN
• the name of the variables is given by Surge, as Surge will automatically detect them
YOUR NOTES
• every time you want to use a tool, you need to make sure it is installed
• the node Docker image that we use does not include surge, so we use npm to install surge
• alternatively, we could use a Docker image that already has surge installed
• to deploy a project run: surge –project ./public –domain SOMENAME.surge.sh
YOUR NOTES
• if you use a predefined name for the variable, Surge will automatically look for the variables and use them
• this makes the configuration much easier
• it also reduces the temptation of including credentails in the pipeline
Gitlab CI Fundamentals
This section provides an overview of the most essential features available in Gitlab CI.
4.1 Overview
15
Gitlab CI Course Notes, Release March 2020
• let’s try to add a version to your website so that we know which version is currently deployed
• Gitlab comes with a large list of predefined variables
• Full list at https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
• Try the following in your pipeline to see how variables look like: echo $CI_COMMIT_SHORT_SHA
• the dollar sign $ indicates that this is a variable
• we will add a “version” to the website by replacing a marker
• edit the file src/pages/index.js
• we will use %%VERSION%% as a marker, but you can use whatever you like
• sed tool - stream editor
– sed -i ‘s/word1/word2/g’ inputfile
– s is for substitute
– use /g at the end for a global replace
– -i option for edit in place
– sed -i “s/%%VERSION%%/$CI_COMMIT_SHORT_SHA/” ./public/index.html
– don’t forget to use double quotes when using variables, as they won’t be replaced
• adapt jobs / tests to reflect the new information
• curl -s “instazone.surge.sh” | grep “$CI_COMMIT_SHORT_SHA”
YOUR NOTES
– you can use one of the predefined options or define your own using the cron syntax
– you can wait for the pipeline to run or you can manually run it (in case you want to test the configu-
ration)
– you can run some jobs using the condition only/except: - schedules
– see the full documentation at https://docs.gitlab.com/ee/user/project/pipelines/schedules.html
YOUR NOTES
• you probably have noticed that some of the jobs do need a lot of time to run
• especially the build job which needs to download some dependencies before it can run
• if you are used with other more “traditional” CI servers like Jenkins, this extra time might seem like “forever”
• this behavior occurs because each job is started using a clean environment and only the code within Git is
available
• rest assured, there is a solution for this and it is called “cache”
• using caches it is possible to speed up the execution of the job by instructing Gitlab to hold onto some files that
we might need
• What to cache?
– ideal candidates for caching are the external project dependencies that are not stored in Git and that
need to be downloaded
– in our case, the project dependencies are defined in the packages.json file as npm dependencies
– the folder that npm uses is called node_modules
• Usage in .gitlab-ci.yml:
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
YOUR NOTES
• let’s clarify one thing: the difference between cache and artifacts
• they might seem very similar but they are not the same thing and serve different purposes
• artifacts
– is usually the output from the build process (the package that we want to deploy)
– an artifact can be partial (if the final package is built across multiple stages)
– artifacts can be used to pass data between jobs/stages
• cache
– should not be used for storing artifacts (even if technically possible)
– should only be used as temporary storage for project dependencies
• read the official documentation: https://docs.gitlab.com/ee/ci/caching/#cache-vs-artifacts
YOUR NOTES
4.6 Environments
• you can view your environments from your project page by going to Operations > Environments
YOUR NOTES
• it is not a good idea to duplicate information that can change (for example the domain name)
• you can define variables in the jobs or globally
• you can specify a variable like this:
variables:
STAGING_DOMAIN: somedomain.surge.sh
• now if you need to change the domain name, you only have to do it in one place
YOUR NOTES
4.6. Environments 19
Gitlab CI Course Notes, Release March 2020
only:
- master
• to implement our new workflow, we need to do a few settings for your project
• no longer allow pushing to master
– go to Settings > Repository > Protected branches
– set Allow to push to “No one”
– nobody will be able to push a change directly to master
– all the changes must go through the process of creating a Merge Request
• configuring Merge Requests
– go to Settings > General > Merge Requests
– set Merge method to Fast-forward merge
– under Merge checks, check Pipelines must succeed
YOUR NOTES
• right now we don’t have an environment where we can inspect the merge requests
• we can automatically spin up a dynamic environment for each merge request
• this allows us to review the changes on an actual system
• we can also run more advanced tests if we want to
• this can not only be a good thing for developers but for testers or product owners/project managers and so on
• we can make a dynamic environment by using predefined Gitlab variables
• we can use the following variables
– $CI_COMMIT_REF_NAME to have the branch name as the environment name
– $CI_ENVIRONMENT_SLUG for a url-friendly environment name
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://instazone-$CI_ENVIRONMENT_SLUG.surge.sh
YOUR NOTES
• with so many potential branches, once they are merged, the environments that were created are no longer needed
• we need to tell surge to delete the environments when we don’t need them anymore
• surge documentation: https://surge.sh/help/tearing-down-a-project
• by setting the variable GIT_STRATEGY to none inside a job, you will disable git cloning for that job
• this is needed for the “stop review” which needs to run even if the branch was deleted
• if the branch is deleted, it does not make sense to clone the repository and try to open that branch
• “deploy review” needs to have a link to the “stop review” job
• the link is setting on_stop
• “stop review” will be automatically triggered by Gitlab one the branch was merged
YOUR NOTES
YAML Basics
5.1 Overview
• we will discuss the most relevant YAML features that are necessary when using GiLlab CI
23
Gitlab CI Course Notes, Release March 2020
6.1 Overview
You will learn: - how build advanced CI pipeline with: codestyle checks, unit tests, API tests, performance tests &
security checks - learn about cloud services and how to use AWS for deployments
• we increase the complexity of the application we are building and deploying
• we will be building and testing a Java application and we will deploy it to Amazon Web Services (AWS)
• the pipeline is more complex, mostly the same GitLab CI principles will be used.
• this course is focused on building pipelines
• check the Resourced for links to articles and other video tutorials
About the project - simple Java application that represents a simple car fleet management solution. - use IDE called
IntelliJ - check the Resources for some tutorials that can help you get started - together we will be building the CI/CD
pipeline - you can work on the .gitlab-ci.yml file without IntelliJ - to run the project from IntelliJ click on Gradle >
cars-api > Tasks > application > bootRun - the app exposes an API that allows you to add, view, and remove cars from
a database.
25
Gitlab CI Course Notes, Release March 2020
What is an API? - an API is a program that does not have a graphical interface, like a website, for example - an API
offers raw data, typicall form a database - an API can use used by a front-end application to display the data in the
browser - work with the API by using Postman
• if you have started the application in IntelliJ, you cannot view this in a browser as it does not have a user interface
(UI)
• use a software development tool called Postman, which is free to download and install
• you will find the Postman collection attached to this lecture
• can click on “Import” and select both the collection and the environment
26 Chapter 6. Using Gitlab CI to build and deploy a Java application to AWS Elastic Beanstalk
Gitlab CI Course Notes, Release March 2020
• for this project, build process will translate source code into Java bytecode that can be executed on the Java
Virtual Machine (JVM)
• the output is a jar file (which is an archive) that contains this bytecode
• to run the build process locally, I will use a tool called Gradle, which is just a build tool
• Gradle helps make the build process much simpler
Now we have an artifact (or a package of software) and we are ready for deployment.
So what to do next?
There are two oppisite directions in which we can go:
• deploy on your own intrastructure (aka server that we control and manage)
• deploy using a cloud provider, like Amazon AWS, Google Cloud, Microsoft Azure and many
The advantage using a cloud provider is that you only rent the infrastructure for the time you are using it. Let’s take
this example:
If you build an ecommerce shop and you want to host it, you will need to buy a server, place it somewhere save,
make backups, handle software updates, fix any hardware failures and so on. During peak times (for example before
Christmas), you may need to buy an additional server that will stay idle for the rest of the year.
Using a cloud provider, you can focus on actually building and maintaining the application and forget about the
hardware and scalability issues.
Which option makes more sense, it is up to you. For some of the reasons mentioned above, cloud services have risen
grately in popularity in the last years.
The following lectures will show to use use Amazon AWS to deploy the Java application.
• Amazon Web Services (AWS) is a cloud platform offering over 170 services available in data centers located all
over the world
• AWS offers services that include virtual servers, managed databases, file storage, content delivery, and many
others
• while creating an account is free, AWS is a paid service
• a basic usage of many services is free in the first year
• adding a debit/credit card is mandatory
• with AWS you rent a virtual machine that has a dedicated CPU, memory and disk
• with a virtual server you still need to handle software updates, back-ups, monitoring, and any other aspects that
ensure your application is running as expected
• AWS Elastic Beanstalk is a way to deploy an application but let AWS handle the hardware and software needed
to run it
• AWS Elastic Beanstalk has a serverless architecture
• serverless architecture: you don’t care about the hardware and software needed to run your application
• using a serverless architecture is the easiest way to deploy an application in the cloud
28 Chapter 6. Using Gitlab CI to build and deploy a Java application to AWS Elastic Beanstalk
Gitlab CI Course Notes, Release March 2020
• AWS S3 is the main storage service for the entire AWS platform
• we will use S3 to upload the artifact
• the GitLab group functionality is a way to organize similar projects into group
• having a group allows you to configure environment variables that are available in multiple projects
• deploying to AWS EB involves two steps - creating a new application version referencing the artifact from S3 -
updating the production environment with the latest application version
• the Java application allows us to insert the application version in one of the info endpoints
• this allows us to check which version is currently deployed
30 Chapter 6. Using Gitlab CI to build and deploy a Java application to AWS Elastic Beanstalk
Gitlab CI Course Notes, Release March 2020
• Most projects want to have a consistent code style and to follow some conventions
• automated tools are used to assist with this task
• some do static code analysis, as the inspection performed without actually running the code
• other tools do a dynamic code analysis, which will actually run the code in order to perform the inspection
• one simple one that can be used for Java projects is PMD
• PMD is a static code analysis tool
• PMD can help find unused variables, problematic code blocks and overall to enforce generally accepted best
practices
• PMD already has a large set of predefined rules but will also allow you to configure or add new rules, as needed
• when structuring a pipeline, you need to take into account multiple factors
• what is the logical flow of the pipeline
• which jobs can be grouped together and which not
• run jobs that have a similar execution time in parallel
• put jobs that are easy to run in the beginning (fail fast principle)
• for this application, API tests are the highest level of tests we can execute
• you can use Postman to write tests
• Newman is the CLI tool from Postman
• Newman allows you to run Postman tests from the CLI
32 Chapter 6. Using Gitlab CI to build and deploy a Java application to AWS Elastic Beanstalk
CHAPTER 7
This course notes have been created for the students of the “Gitlab CI: Pipelines, CI/CD and DevOps for Beginners”
online course on Udemy. If you are not a student yet, consider registering so that you can take full advantages of this
material.
Here to sign-up to the course on >> .. _Udemy: https://www.udemy.com/
gitlab-ci-pipelines-ci-cd-and-devops-for-beginners/?couponCode=COURSE_NOTES
33
Gitlab CI Course Notes, Release March 2020
• genindex
• modindex
• search
35