Intro to GitLab CI/CD
For teams Getting Started with GitLab CI/CD
Agenda
● What is CI/CD?
● GitLab CI/CD Overview
● GitLab CI/CD Setup
● GitLab CI/CD Runners
● Q&A
What is GitLab?
● DevOps Lifecycle Tool
○ Bridge dev and Ops.
● Git Repository Manager
○ Integrate code provided by your
team in a shared repository.
● CI/CD
○ Empowers all teams to work
together efficiently.
○ Powerful, scalable, end-to-end
automation.
What is CI/CD?
● Continuous Integration (CI)
○ Integrate code provided by your team in a shared repository.
● Continuous Delivery
○ Software released to production automatically.
● Continuous Deployment
○ Pushes changes to production.
Why use CI/CD?
CI/CD encourages collaboration across all departments and makes code creation and management
easy, as well as provides the following specific benefits.
CI Detects Errors Quickly
Fix errors while they are fresh in your mind
01
CD Delivers Value Quickly and More Often 02
CI Reduces Integration Problems
05
Get fast feedback on what your end users care Smaller problems are easier to digest and it
about ensures the problems don’t compound
04 03
CD Ensures Every Change is Releasable CI Allows Teams to Develop Faster
This lowers the risk of each release- allows More confidence among the developers allows for
releases to be “boring” less bottlenecking
GitLab Recommended Process
Manage Plan Create Verify Package Secure Release Configure Monitor Protect
Epics
Review App
Milestones
Push Fixes
Issues Push Code Approval
Automated Collaboration &
Create Merge Scan
Build / Test Review
Request
Assign Issue Merge Release Deploy
Accepted
GitLab CI/CD Overview
Anatomy of a CI/CD Pipeline
3 4
1 2
GitLab Pipeline Graph
● Jobs define what we want to accomplish in our pipeline.
○ Executed by Runners
○ Executed in Stages
● Stages define when and how to run jobs.
○ Stages that run tests after stages that compile the code.
● Jobs in each stage are executed in parallel
○ If all jobs in a stage succeed, the pipeline moves on to the next stage.
○ if one job in a stage fails, the next stage is not (usually) executed
Ways to trigger GitLab pipeline
● Push your code to GitLab repository*
● Run it manually from the UI
● Schedule it to run at later time
● “Trigger”ed by upstream pipeline
● Use API to launch a pipeline with “trigger”
GitLab CI/CD Set-up
.gitlab-ci.yml Example
image:
registry.gitlab.com/gitlab-examples/kubernete
s-deploy
stages:
- build
- deploy
variables:
KUBE_DOMAIN: example.com
build:
stage: build
script:
- command build
only:
- main
deploy:
stage: deploy
script:
- command deploy
environment:
name: production
url: http://production.example.com
variables:
DISABLE_POSTGRES: "yes"
only:
- main
GitLab CI/CD pipeline configuration reference
● A job is defined as a list of keywords that ● image
define the job’s behavior. ● services
● Configuration options for your GitLab ● script
.gitlab-ci.yml file. ● before_script &
after_script
● The keywords available for jobs are:
● variables
○ https://docs.gitlab.com/ee/ci/yaml/
● Environment
● cache
● artifacts
● rules
● tags
● when
Stages
Default Stages: Build,
Test, Review, & Deploy
User can define
The code is put
custom stages & any The final product is
Automated tests are through review apps
number of jobs per Source code and deployed to a
run to validate the for peer review and
stage other dependencies designated
code and behavior final approvals
are combined and environment
built
stages: Build Test Review Deploy
- build
- test
- review
- deploy
Stages seperate jobs into logical sections while Jobs perform the
actual tasks
Jobs and Scripts
build-code:
Each Stage Can Have stage: build
Multiple Jobs script: build-it.sh
build-other-code:
Jobs Run In Parallel stage: build
script: src/other/code/build-it.sh
Scripts Can Be
Defined Several script: command build
Different Ways
script:
Script Examples - npm install
- npm build
script:
- scripts/build_script.sh
Basic Parameters
test:
script:
- apt-get update -qy
- bundle install --path /cache
- bundle exec rake test
staging:
stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=ruby-test-staging --api-key=$HEROKU_KEY
only:
- main
production:
stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=ruby-prod --api-key=$HEROKU_PROD_KEY
only:
- tags
Image
Images are pulled from Docker Images stored in the GitLab
Hub by default Container Registry
Use of a public image: Use of a custom image:
2. OPTION TWO
image: ruby:2.3 image:
'registry.gitlab.com/gitl
ab-org/ci-training-sample
:latest'
.gitlab-ci.yml
build so far image: registry.example.com/k8-deploy:latest
Services & Variables
variables:
services:
- POSTGRES_DB:
- postgres
i ab l es rails-sample-1_test
ce s Var
Servi - POSTGRES_USER: root
- POSTGRES_PASSWORD: ”xyzzy”
Services lines tell the
Runner that additional Variables also defined in Project >
images are needed Settings > CI/CD > Variables
image: registry.example.com/k8-deploy:latest
services:
.gitlab-ci.yml - postgres
build so far variables:
- POSTGRES_DB: rails-sample-1_test
What Our .gitlab-ci.yml looks like so far...
image: registry.example.com/k8-deploy:latest
services:
- postgres
variables:
- POSTGRES_DB: rails-sample-1_test
stages:
- build
- test
- deploy
deploy-code:
stage: deploy
script:
- command deploy
Environments
The environment keyword defines where the app is deployed and is defined by 3
parts.
environment:
name: prod
url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN
when: manual
When triggers jobs & stages manually (e.g. deploy to
production)
Name When
URL
Only & Except- Restricting When a Job is Executed
pseudo-deploy:
stage: deploy
script:
- command deploy_review
only:
- branches
except: Only Except
- main
environment: The name of branch Branches NOT to
name: review to execute on (in execute on with
url: http://$CI_PROJECT_NAME-review.$KUBE_DOMAIN this case all exception to the
branches) main Branch
The rules syntax is an improved, more powerful solution for defining when jobs should
run or not. Consider using rules instead of only/except to get the most out of your pipelines.
Rules - Restricting When a Job is Executed
pseudo-deploy:
stage: deploy
script:
- command deploy_review
rules:
- if: '$CI_COMMIT_REF_NAME == "main"'
when: never
- when: always
environment:
name: review
url: http://$CI_PROJECT_NAME-review.$KUBE_DOMAIN
before_script & after_script
Run before and after the script defined in before_script
each job is used to define a command that should be
run before each job, including deploy jobs,
○ Can update the image with the but after the restoration of any artifacts
latest version of components before_script:
- echo $CI_BUILD_STAGE
○ They run within the job and can
- apt-get update
interact with the job - apt-get install node-js -y
- bundle install
- npm install
after_script:
- rm temp/*.tmp
after_script
is used to define the command that will be run
after each job, including failed ones.
Cache & Artifacts
Cache is used to pass information between jobs & stages by storing project
dependencies
cache:
paths:
- binary/
- .config
There may be build artifacts you want to save
artifacts:
when: on_success
paths:
- bin/target
What Our .gitlab-ci.yml looks like so far...
image: registry.example.com/k8-deploy:latest
services:
- postgres
variables:
build-it:
- POSTGRES_DB: rails-sample-1_test
cache: stage: build
paths: script:
- binary/ - command build
stages: only:
- build - main
- test
- deploy artifacts:
deploy-code: when: on_success
stage: deploy paths:
script: - bin/target
- command deploy
environment:
name: production
url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN
when: manual
only:
- main
Tags
● Tags are used to select a specific runner
○ CI tags are different from Git tags
● Runners with the required tags can pick-up the job
○ If a Runner has more tags than required, it can still run that particular
job; including if the job requires no tags at all
job-name:
tags:
- ruby
- test
What Our .gitlab-ci.yml looks like so far...
image: registry.example.com/k8-deploy:latest
services:
- postgres
variables:
- POSTGRES_DB: rails-sample-1_test build-it:
cache: stage: build
paths: script:
- binary/ - command build
stages: only:
- build - main
- test tags:
- deploy - osx
deploy-code: - ios
stage: deploy artifacts:
script: when: on_success
- command deploy paths:
environment: - bin/target
name: production
url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN
when: manual
only:
- main
GitLab CI/CD Runners
Configuration File + Runner
● .gitlab-ci.yml file
○ Instructions for GitLab CI/CD jobs.
○ Lives in the root of the repository
● GitLab Runner
○ Lightweight agent that runs CI/CD jobs. I need to run
the job Alright let’s
“build” before build this
“test” code then I
can test it!
.gitlab-ci.yml GitLab Runner
Runner Architecture
● The GitLab runner can be installed on any platform where you build Go
binaries.
○ Linux, macOS, Windows, FreeBSD, Cloud Provider, Bare Metal, Your work station and
Docker
● The GitLab runner can test any programming language
○ .Net, Java, Python, C, PHP and others.
● Created by an Administrator
A Runner Can Be….
Shared or Specific Tagged or Untagged Protected or Not Protected
Shared vs. Specific Runners
Shared Runners Specific Runners
Available to every project with
Tied to one or more specific
similar requirements
projects
Description Description
VS
Typically Typically for specialized
Included in the pool Managed by GitLab In the pool for ONLY Managed by Runner
auto-scaling or builds, or if an org needs
for all projects Admin specific projects Owner(s)
otherwise scaled to do so for billing
Tagged vs. Untagged
Tagged Untagged
Only used to run jobs tagged with Used to run jobs with no tags
same tag
Protected vs. Non-Protected
Protected Non-Protected
Characteristics Characteristics
ONLY runs jobs from VS ● Runs jobs from
● Protected Branches ANY branch
● Protected Tags ● Used for ANY
Typically used for runners build
containing deploy keys or
other sensitive capabilities
Additional Runner Options
Executors: Common
Shell
Directly run commands as if writing them into terminal
(bash or sh) or command prompt (cmd) or powershell ��
��
Docker Machine
Docker
“Main” machine scales up runners with
*any* executor on demand Execute inside of a docker image
Typical in cloud deployments
�� Most common!
��
Kubernetes
Runs as a pod in a K8s cluster
Can also feature auto-scaling
Executors: Less Common
1. VirtualBox
Base VM for runner
“Main” creates a new VM for each needed runner
2. Parallels
Hint: Parallels is a nice platform on top of
VirtualBox
3. SSH
Similar to shell, but not as many features (bash only, no caching)
Does allow you to SSH and execute commands on a machine you
might not want to install runner on
Q&A