1 of 95

agi-t

Una

tlab

a-git

2 of 95

3 of 95

La quête

Du code à la Prod !

4 of 95

Du passé, faisons

table en marbre.

5 of 95

Kamil Trzciński

@ayufanpl

6 of 95

7 of 95

Apr 17, 2015 - Kamil Trzciński

Unofficial GitLab CI Runner

8 of 95

Unofficial runner becomes official one

May 3, 2015 - Kamil Trzciński

9 of 95

Kevin DAVIN

@davinkevin

  • Fan de Kaamelott !
  • Agile Addict
  • Champion du monde Sloubi 2012
  • Fils de pécore...

Stack Labs CTO

Gitlab Heroes

Google Developer Expert

10 of 95

Logan WEBER

@Neonox31

Software Automation Engineer @AirbusSpace

  • Roi de l’automatisation
  • Ne comprend pas encore tout à Kaamelott
  • Le gras c’est la vie

11 of 95

Comment démarrer ?

12 of 95

Mon projet n’est pas sur Gitlab...

13 of 95

C’est pas grave !

14 of 95

Gitlab - Runners

15 of 95

gitlab-ci.yml pour les nuls

16 of 95

surtout n’ayez pas peur !

17 of 95

Un job c’est quoi ?

install :

script: "mvn clean install"

Ceci est un Job

18 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

script

le de votre job

doit contenir le ou les scripts propres à la fonction de votre job

19 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

image

nom de l’image docker à utiliser pour le job

utile uniquement pour un runner docker

20 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

before_script /

after_script

permet d'exécuter des scripts avant ou après vos scripts

utile pour préparer ou nettoyer l’environnement d'exécution

21 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

only / except

permet de définir sur quel(s) évènement(s) déclencher ou non le job

exemples :

  • tags
  • branches
  • master
  • /^\d+.\d+.\d+-rc.\d+$/
  • schedules
  • web
  • ….

22 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

allow_failure

donne l’autorisation à votre job d’échouer sans faire échouer le pipeline complet

23 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

when

force le job à être déclenché manuellement

24 of 95

Paramètres

deploy continuous:

image: google/cloud-sdk

only:

- master

before_script:

- gcloud -v

- echo $CI_DEPLOYMENT_DEV > /tmp/auth.json

- gcloud auth activate-service-account --key-file /tmp/auth.json

script:

- gcloud app deploy dist/ --version continuous --no-promote

after_script:

- rm -rf /tmp/$CI_PIPELINE_ID.json

allow_failure: true

when: manual

needs: [📦packaging]

needs

force le job à être déclenché manuellement

25 of 95

Paramètres

Et pleins d’autres sur...

"C’est pour ça : j’lis jamais rien. C’est un vrai piège à cons c’t’histoire-là. En plus j’sais pas lire." - Perceval

26 of 95

La recette du .gitlab-ci.yaml est prête...

27 of 95

Organisation

lint:

script:

- ./mvnw lint

test:

script:

- ./mvnw test

test-integration:

script:

- ./mvnw test -p integration

build:

script:

- ./mvnw compile jib:build

deploy:

image: google/cloud-sdk

script:

- gcloud authenticate

- helm template template.yml | kubectl apply -f -

build

deploy

lint

test

test-integration

28 of 95

C’est quoi ce bordel ?!

29 of 95

Organisation par Stages

lint:

stage: check

script:

- ./mvnw lint

test:

stage: test

script:

- ./mvnw test

test-integration:

stage: test

script:

- ./mvnw test -p integration

build:

stage: build

script:

- ./mvnw compile jib:build

deploy:

image: google/cloud-sdk

stage: deploy

script:

- gcloud authenticate

- helm template template.yml | kubectl apply -f -

lint job: stage parameter should be build, test, deploy

30 of 95

CI linter

31 of 95

32 of 95

Organisation des Stages

stages:

- check

- test

- build

- deploy

lint:

stage: check

script:

- ./mvnw lint

test:

stage: test

script:

- ./mvnw test

test-int:

stage: test

script:

- ./mvnw test -p integration

build:

stage: build

script:

- ./mvnw compile jib:build

deploy:

image: google/cloud-sdk

stage: deploy

script:

- kustomize build . | kubectl apply -f -

check

test

build

deploy

lint

test

test-int

build

deploy

33 of 95

Organisation des Stages

check

stages:

- check

- test

- build

- deploy

lint:

stage: check

script:

- ./mvnw lint

test:

stage: test

script:

- ./mvnw test

test-int:

stage: test

script:

- ./mvnw test -p integration

build:

stage: build

script:

- ./mvnw compile jib:build

needs: [lint]

deploy:

stage: deploy

script:

- kustomize build . | kubectl apply -f -

needs: [build]

test

build

deploy

lint

test

test-int

build

deploy

34 of 95

L’important c’est les variables

35 of 95

Variables

variables:

GCP_PROJECT: “my-gcp-project”

deploy dev:

image: google/cloud-sdk

stage: deploy

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_SHA

deploy prod:

image: google/cloud-sdk

stage: deploy

only:

- tags

variables:

GCP_PROJECT: “my-gcp-project-prod”

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_TAG

Globales

définies par l’utilisateur

accessibles depuis n’importe quel job du pipeline

36 of 95

Variables

variables:

GCP_PROJECT: “my-gcp-project”

deploy dev:

image: google/cloud-sdk

stage: deploy

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_SHA

deploy prod:

image: google/cloud-sdk

stage: deploy

only:

- tags

variables:

GCP_PROJECT: “my-gcp-project-prod”

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_TAG

Locales

définies par l’utilisateur

accessibles uniquement dans le job

37 of 95

Variables

variables:

GCP_PROJECT: “my-gcp-project”

deploy dev:

image: google/cloud-sdk

stage: deploy

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_SHA

deploy prod:

image: google/cloud-sdk

stage: deploy

only:

- tags

variables:

GCP_PROJECT: “my-gcp-project-prod”

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_TAG

Environnement

prédéfinies par le runner

peuvent être utilisées dans tout le pipeline

examples :

  • $CI_COMMIT_SHA
  • $CI_COMMIT_TAG
  • $CI_COMMIT_REF_NAME
  • $CI_COMMIT_REF_SLUG
  • ….

38 of 95

Variables

39 of 95

Variables

variables:

GCP_PROJECT: “my-gcp-project”

deploy dev:

image: google/cloud-sdk

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_SHA

deploy prod:

image: google/cloud-sdk

variables:

GCP_PROJECT: “my-gcp-project-prod”

before_script:

- gcloud auth $SSH_TOKEN

script:

- gcloud deploy -proj $GCP_PROJECT -version $CI_COMMIT_TAG

Environnement

définies par l’utilisateur dans l’UI de gitlab au niveau du groupe ou du projet

Utile pour les variables sensibles

peuvent être protégées

40 of 95

DRY

41 of 95

Aller + loin avec le YAML

deploy qual:

image: google/cloud-sdk

stage: deploy-qual

script:

- gcloud authenticate --login $LOGIN --password $PASS --project $GCP_PROJECT

- kustomize build . | kubectl apply -f -

deploy pre-prod:

image: google/cloud-sdk

stage: deploy-pre-prod

script:

- gcloud authenticate --login $LOGIN --password $PASS --project $GCP_PROJECT

- kustomize build . | kubectl apply -f -

deploy prod:

image: google/cloud-sdk

stage: deploy-prod

script:

- gcloud authenticate --login $LOGIN --password $PASS --project $GCP_PROJECT

- kustomize build . | kubectl apply -f -

42 of 95

Aller + loin avec le YAML

43 of 95

DRY

.cicd_utils: &cicd_utils |

function deploy_to_gcp() {

gcloud authenticate --login $LOGIN --password $PASS --project $GCP_PROJECT

kustomize build . | kubectl apply -f -

}

deploy qual:

image: google/cloud-sdk

stage: deploy-qual

script:

- *cicd_utils

- deploy_to_gcp

44 of 95

Quelques fois, c’est long...

45 of 95

46 of 95

Utilisons du cache !

default:

cache:

paths:

- .m2/repository

lint:

script:

- ./mvnw lint

test:

script:

- ./mvnw test

test-integration:

script:

- ./mvnw test -p integration

build:

script:

- ./mvnw compile jib:build

deploy:

image: google/cloud-sdk

script:

- gcloud authenticate

- kustomize build . | kubectl apply -f -

Global...

47 of 95

Utilisons du cache !

default:

cache:

key: $CI_PIPELINE_ID # Par pipeline

paths:

- .m2/repository

lint:

script:

- ./mvnw lint

test:

script:

- ./mvnw test

test-integration:

script:

- ./mvnw test -p integration

build:

script:

- ./mvnw compile jib:build

deploy:

image: google/cloud-sdk

script:

- gcloud authenticate

- kustomize build . | kubectl apply -f -

  • $CI_COMMIT_REF_NAME # Par Branche|tag
  • $CI_PIPELINE_ID # Par pipeline
  • $CI_JOB_ID # Par job
  • $CI_JOB_STAGE # Par Stage

Globalement spécifique...

48 of 95

Utilisons du cache !

stages:

- test

- build

test-ui:

stage: test

script:

- npm test

cache:

key: ui-cache”

paths:

- node_modules

test-backend:

stage: test

script:

- ./mvnw test

cache:

key: “backend-cache”

paths:

- .m2/repository

Spécifiquement global...

49 of 95

Utilisons du cache !

stages:

- test

- build

test-ui:

stage: test

script:

- npm test

cache:

key: $CI_PIPELINE_ID-ui

paths:

- node_modules

build:

stage: build

script:

- ./mvnw install

cache:

key: $CI_PIPELINE_ID-backend

paths:

- .m2/repository

Spécifiquement spécifique...

50 of 95

Utilisons du cache !

stages:

- download

- test

backend dep:

stage: download

script:

- ./mvnw install

cache:

key: $CI_PIPELINE_ID-backend

policy: push

test-ui:

stage: test

script:

- npm test

cache:

key: $CI_PIPELINE_ID-ui

paths:

- node_modules

policy: pull

Récupérons le de manière intelligente !

51 of 95

Et avec un système de cache efficace

52 of 95

Vous pouvez être sûr que si Joseph d’Arimathie a pas été trop con

le graal, c’est un bocal à anchois !

Artifacts

53 of 95

Artifacts

install :

script: "mvn clean install"

artifacts:

paths:

- target/app.jar

expire_in: 1 week

54 of 95

Artifacts

55 of 95

Artifacts

56 of 95

Artifacts

57 of 95

Un artifact bien particulier

pages:

stage: deploy

script:

- mkdir .public

- cp -r * .public

- mv .public public

artifacts:

paths:

- public

only:

- master

Autres templates : Hugo, Doxygen, Jekyll, ...

HTML simple :

58 of 95

Suivi des tests unitaires

C’est pas clair ?

59 of 95

Suivi des tests unitaires

C’est pas clair ?

60 of 95

Suivi des tests unitaires

unit test:

stage: test

script:

- mvn test

artifacts:

reports:

junit:

- target/surefire-reports/TEST-*.xml

61 of 95

Suivi des tests unitaires

62 of 95

Suivi des tests unitaires

63 of 95

Analyses de sécurité

64 of 95

Analyses de sécurité

65 of 95

Analyses de sécurité

include:

template: SAST.gitlab-ci.yml

sast:

stage: security

variables:

SAST_EXCLUDED_PATHS: "foo/bar/not-scanned"

66 of 95

Analyses de sécurité

67 of 95

Analyses de sécurité

DAST

Container Analysis

include:

template: SAST.gitlab-ci.yml

sast:

stage: security

include:

template: container-scanning.gitlab-ci.yml

container_scanning:

stage: security

68 of 95

Service

69 of 95

Service

70 of 95

Service

?

71 of 95

Service

unit:

stage: tests

services:

- postgres:alpine

variables:

POSTGRES_DB: postgres

POSTGRES_USER: proxyuser

POSTGRES_PASSWORD: test-password

script:

- ./mvnw $MAVEN_CLI_OPTS test

72 of 95

J’ai rien compris !

73 of 95

Gitlab Auto-Devops est là !

74 of 95

75 of 95

Et il peut faire plein de choses !

76 of 95

Et il peut faire plein de choses !

77 of 95

Et il peut faire plein de choses !

78 of 95

Et si on parlait OPS ?

79 of 95

Et comment on installe un runner ?

80 of 95

Installation d’un runner sous debian

Tout ça en moins de 3 minutes...la preuve...

81 of 95

82 of 95

La CI est trop lente

Voici ce que vous pouvez faire...

  • Limiter l'exécution de vos jobs
  • Utiliser les stages pour exécuter vos jobs en //
  • Améliorer la vitesse d'exécution de vos jobs en utilisant le cache
  • Planifier au maximum vos jobs pendant les heures creuses
  • Utiliser vos runners avec des repository managers (Gitlab ou autre)
  • Baisser le nombre de jobs concurrents
  • Suivre le REX des autres prez 😍

83 of 95

Et si on voyait plus grand ?

84 of 95

C’est possible !

85 of 95

Installer un runner Kubernetes en 3 clics depuis Gitlab !

86 of 95

87 of 95

  • Activer l'auto scaling sur le cluster
  • Patcher le déploiement du runner
  • Lancer des jobs, encore et encore...

Adapter les ressources à la demande !

88 of 95

89 of 95

On Demand’ !!!

90 of 95

Merci

91 of 95

92 of 95

93 of 95

94 of 95

Questions ?

95 of 95

Le prochain qui l'ouvre je l'envoie aux galères pendant 3 ans

Sans déconner, je le fais...