DEV Community đŸ‘©â€đŸ’»đŸ‘šâ€đŸ’»

Jean-Phi Baconnais
Jean-Phi Baconnais

Posted on • Updated on • Originally published at jeanphi-baconnais.gitlab.io

Commencer simplement avec GitLabCI

Tout le monde connait GitLab, et beaucoup de monde connait son outil d'intĂ©gration et de dĂ©ploiement continus : GitLabCI 🩊.

Avec l'arrivĂ©e d'une application ne possĂ©dant aucun outil de CI/CD dans notre Ă©quipe, nous avons pu manipuler GitLabCI. C'est d'ailleurs le sujet d'une prĂ©sentation sur laquelle nous avons travaillĂ© avec un collĂšgue (Jean-Baptiste Martin pour ne pas le citer 🙂).

C'est cette approche que je vais vous présenter dans cet article.

Sommaire

1 - Création d'un pipeline
2 - Notre premier job
3 - Le registry
4 - Les environnements
5 - GitLab Pages
6 - Kubernetes
The (happy) end

🛠 CrĂ©ation d'un pipeline

Pour créer un pipeline GitLabCI, c'est tout simple, il suffit de créer un fichier .gitlab-ci.yml à la racine de votre projet.

Les pipelines sont disponibles via le menu "CI/CD" > "Pipelines".

Notre premier pipeline

Un pipeline est un élément assez simple, ayant un status : in progress, pending, passed et (je ne vous le souhaite pas) failed.

En consultant un pipeline, nous pouvons voir sa structuration, il est constitué de 1 ou plusieurs jobs, organisés dans différentes colonnes. Tout cela se configure dans le fameux fichier .gitlab-ci.yml.

Je vous entend déjà raler en voyant l'extension yml, mais rassurez vous, GitLab a mis un outil CI Lint qui vous permet de valider vos pipelines. Utile pour éviter de voir vos pipelines planter car le yaml est invalide ! Il est disponible dans la page des pipelines :

Structuration du fichier .gitlab-ci.yml

Le fichier .gitlab-ci.yml commence généralement par les définitions de nos "colonnes". Il s'agit de stage. Un pipeline peut contenir autant de stage qu'il nous semble utile. Les différents traitements se feront de maniÚre séquentielle.
Dans cet exemple il y a 5 Ă©tapes dans la construction de notre projet :

stages:
  - build_and_push
  - deploy_tis
  - deploy_re7
  - notif_prepa_liv_prod
  - deploy_prod
Enter fullscreen mode Exit fullscreen mode
  • La premiĂšre Ă©tape permet de builder une image docker de notre projet et le pusher sur un repository.
  • La seconde deploie notre composant sur un environnement de fabrication.
  • La troisiĂšme sur un environnement de recette.
  • la quatriĂšme envoie une notification dans slack qu'une livraison en production est en prĂ©vision.
  • La derniĂšre dĂ©ploie notre application en production.

Voila graphiquement Ă  quoi cela ressemble :

Pipeline

L'enchainement des diffĂ©rents stages se fait automatiquement si tous les jobs se font sans erreur. Dans l'exemple, il a Ă©tĂ© (heureusement) mis en place un systĂšme d'exĂ©cution manuelle. Notre application n'ayant trĂšs peu de tests automatisĂ©, il est prĂ©fĂ©rable de faire quelques tests avant d'envoyer une nouvelle version en production đŸ€­. Il est donc possible de spĂ©cifier qu'un stage est Ă  exĂ©cuter uniquement aprĂšs une action manuelle : when: manual
Ce qui visuellement dans notre pipeline est repérable grùce à la flÚche noire en haut du stage :

Comment s'exécute le pipeline ?

Sur chaque Ă©tape, il est possible de mentionner la branche qui va enclencher notre pipeline.

 only:
    - dev
    - master
Enter fullscreen mode Exit fullscreen mode

Dans cet exemple, dÚs qu'un push est effectué sur la branche dev et master, le pipeline définit va s'exécuter.

Afin d'optimiser le temps de traitement de notre pipeline, il est possible (voire conseillĂ©) de parallĂ©liser les traitements. Pour cela plusieurs jobs peuvent ĂȘtre associĂ©s Ă  un stage. Dans cet exemple, tous les jobs de build de composants sont rĂ©alisĂ©s en parallĂšle.

Au niveau du fichier .gitlab-ci.yml cela se traduit de cette façon :

  • 1 stage
stages:
       - build
Enter fullscreen mode Exit fullscreen mode
  • chaque job reçoit la configuration suivante :
📩 front :
       stage: build

📩 api_go :
       stage: build

📩 node :
       stage: build
Enter fullscreen mode Exit fullscreen mode

NB : Un pipeline peut Ă©galement ĂȘtre programmĂ© via la partie "Schedule". Accessible via le menu, un pipeline peut ĂȘtre programmĂ©.

🛠 Les jobs

Notre premier job

Un job est ce qui va permettre de rĂ©aliser une ou plusieurs tĂąches. Le job le plus simple doit ĂȘtre composĂ© d'une action dans une partie script :

job:
  script : 
     - echo "Voici mon premier job"
Enter fullscreen mode Exit fullscreen mode

Il existe d'autres mots clĂ©s qui vont nous permettre de faire des actions plus complexes qu'un simple echo 😁

L'attribut stage

Tout d'abord un stage peut lui ĂȘtre attribuĂ©, permettant ainsi de classifier nos jobs comme montrĂ© dans le paragraphe ci-dessus. Si on dĂ©finit 2 stages tels que :

stages:
  - first_stage
  - second_stage
Enter fullscreen mode Exit fullscreen mode

Nous pourrions avoir plusieurs jobs définis tels que :

job1:
  stage: first_stage
  script : 
     - echo "Voici mon premier job"
job2:
  stage: second_stage
  script : 
     - echo "Voici mon second job"
Enter fullscreen mode Exit fullscreen mode

et nous pourrions avoir plusieurs jobs associĂ©s au mĂȘme stage :

job1:
  stage: first_stage
  script : 
     - echo "Voici mon premier job"
job2:
  stage: second_stage
  script : 
     - echo "Voici mon second job"
job3:
  stage: first_stage
  script : 
     - echo "Voici mon troisiÚme job exécuté lors du premier stage"
Enter fullscreen mode Exit fullscreen mode

L'attribut image

Il y a ensuite le mot clĂ© image. Il permet d'effectuer une action Ă  l'aide d'image docker. Il peut ĂȘtre positionnĂ© pour l'ensemble des jobs dans la premiĂšre ligne du fichier .gitlab-ci.yml, ou pour chaque job.

Commun Ă  tous les jobs :

image: alpine

job1:
  stage: first_stage
  script : 
     - echo "Voici mon premier job"
job2:
  stage: second_stage
  script : 
     - echo "Voici mon second job"

Enter fullscreen mode Exit fullscreen mode

ou pour chaque job :

job1:
  image: alpine
  stage: first_stage
  script : 
     - echo "Voici mon premier job"
job2:
  image: alpine
  stage: second_stage
  script : 
     - echo "Voici mon second job"

Enter fullscreen mode Exit fullscreen mode

Si on a notre pipeline qui contient la plupart de job qui utilisent une image, il vaut mieux spécifier l'image comme globale à notre pipeline, puis à surcharger les jobs avec des images spécifiques :

image: alpine

job1: # utilisera l'image de base alpine
  script : 
     - echo "Voici mon premier job"
job2:
  image: seconde_image_docker # ce job spécifie l'image qu'il a besoin pour effectuer une action spécifique.
  stage: second_stage
  script : 
     - echo "Voici mon second job"

Enter fullscreen mode Exit fullscreen mode

En choisissant l'image, on peut imaginer par exemple lancer des commandes maven pour pouvoir exécuter les tests et poursuivre le pipeline si tous les tests sont passés.

test:
  stage: test
  script:
    - mvn clean verify
Enter fullscreen mode Exit fullscreen mode

L'attribut only

L'attribut only est simple à comprendre, il permet d'éxécuter votre job seulement sur une branche ou une typologie de branche. Par exemple un déclenchement de job sur la branche master s'écrit comme ceci :

  only:
    - master
Enter fullscreen mode Exit fullscreen mode

On peut également définir une liste de branches :

  only:
    - dev
    - master
Enter fullscreen mode Exit fullscreen mode

ou un pattern de branches :

  only:
    - features*
Enter fullscreen mode Exit fullscreen mode

L'attribut when

L'attribut when permet de conditionné l'exécution d'un job. Cinq valeurs sont disponibles et permettent de conditionner l'exécution d'un job. Elles sont assez parlantes : on_success, on_failure, always, manual et la derniÚre arrivée manual.

Pour plus de détail sur les différents états, se référer à la doc GitLab https://docs.GitLab.com/ee/ci/yaml/#when

La premiÚre utilisation que j'ai utilisée, c'est celle spécifiée précédemment, c'est le manual. En effet, avec cette description, ce job ne s'exécutera qu'aprÚs intervention manuelle d'un utilisateur :

job1: 
  image: alpine
  stage: second_stage
  script : 
     - echo "Voici mon second job"
  when: manual
Enter fullscreen mode Exit fullscreen mode

L'attribut artifact

Un artifact est un moyen de récupérer des fichiers générés par un job. Cela peut servir à récupérer un rapport de test par exemple. Afin de ne pas trop surcharger les infrastructures et ne garder indéfiniement des fichiers, la notion d'expiration est possible.

expire_in: 1 week
Enter fullscreen mode Exit fullscreen mode

Par exemple, pour ce site réalisé avec l'outil gohugo, j'exécute dans un job la commande hugo qui permet de générer le site statique. Tous les fichiers vont dans le répertoire public :

  artifacts:
    paths:
    - public

Enter fullscreen mode Exit fullscreen mode

Sous l'interface du pipeline il est possible de récupérer les sources :

Artefact

L'attribut variables

Dans un pipeline il est possible de créer des variables propres à un job :

  variables:
    DATA: "{'text':'une donnée json que vous voulez utilisez plus tard'}"
Enter fullscreen mode Exit fullscreen mode

Cette variable pourra ĂȘtre simplement utilisĂ©e dans la partie script :

script:  
    - curl -X POST -H "${CONTENT}"  --data "${DATA}" "${WEBHOOK_LIVRAISON}"
Enter fullscreen mode Exit fullscreen mode

Pour intĂ©grer et rĂ©utiliser une variable dans plusieurs jobs, c'est exactement la mĂȘme chose mais Ă  l'extĂ©rieur d'un job 😉.

Il existe encore un niveau au dessus en terme de variable, notamment utilisé pour stocker les mots de passe qui ne doivent pas se trouver dans votre code source ! Dans le menu "Settings" > "CI / CD" plusieurs options sont disponibles, dont les variables.

Dans cet exemple on voit deux variables créées et masquées qui sont utilisables dans le pipeline comme une variable créée dans le fichier .gitlab-ci.yml.

Registry images

GitLab met également des variables prédéfinies, comme l'identifiant du pipeline CI_PIPELINE_ID, le user CI_REGISTRY_USER, le message du commit utilisé CI_COMMIT_MESSAGE, des informations sur l'utilisateur exécutant le pipeline, etc.

Plus de détail sur cette page : https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

L'attribut tags

L'attribut tag permet de sĂ©lectionner un Runner, un quoi ? đŸ€”

Rapidement un runner est ce qui permet d'interpréter les fichiers .gitlab-ci.yml. Si vous utilisez l'instance publique GitLab.com, des runners sont configurés et sont ceux utilisés par défaut, ce sont les Shared runner, les runners partagés avec tout le monde. Si on est administrateur de son instance GitLab privée, on peut s'amuser à créer des Specified Runner, c'est-à-dire des runners spécifiés à un projet ou un groupe de projet. Cela permet de partager les ressources machines en fonction des projets ou groupement de projet.

Le registry

Le container registry de GitLab permet de stocker des images dans votre projet, que ce soit via GitLabCI ou mĂȘme manuellement en ligne de commande ou par d'autres outils. Simple Ă  comprendre et Ă  utiliser !

C'est disponible dans le menu "Packages" > "Container Registry".

Il permet mĂȘme de stocker plusieurs niveaux. Par exemple dans ce projet je stocke 4 images pour lesquelles je peux dĂ©ployer plusieurs tags.

Registry images

Registry images

Vos images seront accessibles facilement avec un

docker pull registry.gitlab.com/jeanphi-baconnais/arbregen/front:master_133030344
Enter fullscreen mode Exit fullscreen mode

On peut ainsi imaginer un job qui build l'image docker de votre composant via :

🐳  build_and_deploy: 
  stage: build
  image: docker:stable
  services:
    - docker:dind
  script:
    - docker login -u GitLabci -p "$CI_SECRET"  registry.GitLab.com
    - docker build -t <your image name> .
    - docker push <your image name>:latest
Enter fullscreen mode Exit fullscreen mode

Cette tache est encore plus facile avec l'utilisation de l'outil Kaniko (https://github.com/GoogleContainerTools/kaniko) de Google :

🐳 build_push_image_docker:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE
Enter fullscreen mode Exit fullscreen mode

Kaniko s'occupe de builder l'image à partir d'un dockerfile et de le pusher dans le repository renseigné.

Les environnements

La partie environnement n'est pas un Ă©lĂ©ment que j'ai approfondi Ă  fond. Cela permet de dĂ©clarer des environnements, et de les voir dans la partie environnement disponible dans le menu de GitLab. Un environnement peut ĂȘtre nommĂ©, une url peut y ĂȘtre affectĂ©e et cela alimentĂ© automatiquement le menu environnement.

Environnements

En configurant un cluster kubernetes, il est possible de consulter directement les métriques, avoir accÚs à un terminal ou alors rejouer votre stage.

Environnements

GitLab Pages

GitLab met à disposition un outil bien pratique, GitLab Pages, qui permet d'héberger gratuitement un site basé sur votre repository. C'est exactement avec cet outil que j'ai pu avoir mon site perso http://jeanphi-baconnais.gitlab.io.

Lors de la création de votre projet, il est possible de partir de templates, et ceux préfixés par "Pages" permettent de générer un projet possédant directement la configuration nécessaire pour vous permettre d'avoir un site disponible.

Le nom du projet doit contenir votre user.gitlab.io. Contrainte imposée par GitLab.

Create project

Pour mon site, je me base sur le framework GoHugo (cf https://gohugo.io/).

Le fichier .gitlab-ci.yml généré est le suivant :

image: registry.GitLab.com/pages/hugo:latest

pages:
  script:
  - hugo
  artifacts:
    paths:
    - public
  only:
    refs:
    - master

Enter fullscreen mode Exit fullscreen mode

La commande hugo permettant de builder le site est exĂ©cutĂ©e et produit le rĂ©sultat dans l'artifact "public", le site buildĂ© est mis Ă  disposition et votre site est opĂ©rationnel 😎.

Si votre site n'est pas disponible, vous pouvez vérifier la configuration dans le menu "Settings" > "Pages".

L'url de votre page doit ĂȘtre affichĂ©e telle que :

Conf Pages

Kubernetes

Il est possible d'intégrer (facilement) des cluster kubernetes à GitLab. AprÚs avoir créé son compte sur Google Kubernetes Engine ou Amazon, GitLab va permettre via le menu "Operations" > "Kubernetes" de créer ou déclarer un cluster Kubernetes sur l'une des deux plateformes. Mon exemple concerne l'infrastructure Google.

Kubernetes

AprÚs avoir un cluster, plusieurs outils sont intégrables via l'onglet "Applications", comme Helm, Ingress, Prometheus, etc.

Kubernetes
Kubernetes

On peut mĂȘme y voir l'Ă©tat de santĂ© de notre cluster.

Kubernetes

Pour déployer une application via GitLabCI, c'est trÚs simple, cela se passe toujours dans le .gitlab-ci.yml et via l'image google/cloud-sdk, l'outil kubectl est disponible et permet donc de déclarer des déploiements, services en ligne de commande ou bien via un fichier yaml. C'est également possible avec Helm si vous avez bien activé l'application auparavant.

🐋 deploy_gcp :
  stage: deploy
  image: google/cloud-sdk
  script:
    - kubectl apply -f k8s/hello-world.yaml
Enter fullscreen mode Exit fullscreen mode

The (happy) end

L'approche GitLabCI est trÚs simple à prendre en main, par contre, il faut l'avouer qu'au départ, c'était assez sportif de construire nos pipelines.
DĂšs qu'un nouveau job Ă©tait en construction, il plante souvent ... J'ajoute une ligne dans mon job, je git add, git commit, git push, regarde mon pipeline tourner, puis planter. Je modifiais le pipeline, git add, commit, push, regardait mon pipeline tourner, puis planter, etc.
MĂȘme avec l'utilisation du Web IDE, ça facilitait les opĂ©rations git, mais les statistiques de nos pipelines n'Ă©taient pas dingues. Sur le premier projet de nos tests avec GitLabCI, 40% de tests passĂ©s avec succĂšs !

Les GitLab Runner permettent Ă  GitLab de constuire vos pipelines, et bien l'outil GitLab-Runner peut ĂȘtre installĂ© sur vos machines : https://docs.gitlab.com/runner/install/

Cela permet de gagner un temps fou, et d'amĂ©liorer vos statistiques de pipeline si votre chef prĂ©fĂ©rĂ© vous espionne 😅

Si vous avez un pipeline constituĂ© de plusieurs jobs, il est mĂȘme possible d'exĂ©cuter un seul job. Par exemple si vous avez un job 'job1' dĂ©clarĂ© dans votre .gitlab-ci.yml, vous pourrez l'exĂ©cuter avec les process de votre machine via un

gitlab-runner exec docker job1

.

Je ne l'ai pas encore dit, mais vos runner peuvent utiliser plusieurs types d'executor : docker (le seul que j'ai utilisĂ©), shell, sh, virtual box et mĂȘme kubernetes (que je dĂ©couvre en Ă©crivant cet article). Je vous laisse lire la documentation si vous voulez approfondir ce point : https://docs.gitlab.com/runner/executors/.

Avec toutes ces notions, nous avons pu automatiser nos pipelines de CI/CD pour automatiser les builds d'applications, les installer sur des machines distantes, informer via Slack des livraisons effectuĂ©es avec le commit, bref nous faire gagner en temps et en confort 😎 MĂȘme l'intĂ©gration sur un cluster Kubernetes est simple et rapide Ă  mettre en place.

La documentation de GitLab est trĂšs bien faite et est en constante Ă©volution : https://docs.gitlab.com/ee/ci/yaml/.

Merci de votre lecture et bons pipelines !

Top comments (0)

Classic DEV post:

CLI tools you won't be able to live without 🔧

CLI tools