agi-t
Una
tlab
a-git
La quête
Du code à la Prod !
Du passé, faisons
table en marbre.
Kamil Trzciński�
@ayufanpl
Unofficial runner becomes official one
May 3, 2015 - Kamil Trzciński
Kevin DAVIN
@davinkevin
Stack Labs CTO
Gitlab Heroes
Google Developer Expert
Logan WEBER
@Neonox31
Software Automation Engineer @AirbusSpace
Comment démarrer ?
Mon projet n’est pas sur Gitlab...
C’est pas grave !
Gitlab - Runners
gitlab-ci.yml pour les nuls
surtout n’ayez pas peur !
Un job c’est quoi ?
install :
script: "mvn clean install"
Ceci est un Job
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
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
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
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 :
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
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
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
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
La recette du .gitlab-ci.yaml est prête...
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
C’est quoi ce bordel ?!
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
CI linter
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
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
L’important c’est les variables
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
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
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 :
Variables
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
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 -
Aller + loin avec le YAML
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
Quelques fois, c’est long...
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...
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 -
Globalement spécifique...
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...
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...
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 !
Et avec un système de cache efficace
Vous pouvez être sûr que si Joseph d’Arimathie a pas été trop con
le graal, c’est un bocal à anchois !
Artifacts
Artifacts
install :
script: "mvn clean install"
artifacts:
paths:
- target/app.jar
expire_in: 1 week
Artifacts
Artifacts
Artifacts
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 :
Suivi des tests unitaires
C’est pas clair ?
Suivi des tests unitaires
C’est pas clair ?
Suivi des tests unitaires
unit test:
stage: test
script:
- mvn test
artifacts:
reports:
junit:
- target/surefire-reports/TEST-*.xml
Suivi des tests unitaires
Suivi des tests unitaires
Analyses de sécurité
Analyses de sécurité
Analyses de sécurité
include:
template: SAST.gitlab-ci.yml
sast:
stage: security
variables:
SAST_EXCLUDED_PATHS: "foo/bar/not-scanned"
Analyses de sécurité
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
Service
Service
Service
?
Service
unit:
stage: tests
services:
- postgres:alpine
variables:
POSTGRES_DB: postgres
POSTGRES_USER: proxyuser
POSTGRES_PASSWORD: test-password
script:
- ./mvnw $MAVEN_CLI_OPTS test
J’ai rien compris !
Gitlab Auto-Devops est là !
Et il peut faire plein de choses !
Et il peut faire plein de choses !
Et il peut faire plein de choses !
Et si on parlait OPS ?
Et comment on installe un runner ?
Installation d’un runner sous debian
Tout ça en moins de 3 minutes...la preuve...
La CI est trop lente
Voici ce que vous pouvez faire...
Et si on voyait plus grand ?
C’est possible !
Installer un runner Kubernetes en 3 clics depuis Gitlab !
Adapter les ressources à la demande !
On Demand’ !!!
Merci
Questions ?
Le prochain qui l'ouvre je l'envoie aux galères pendant 3 ans
Sans déconner, je le fais...