Workbook GitLab CI - Les fondamentaux de l'intégration et du déploiement continus (CI/CD)

Un guide concis et pratique conçu pour ceux qui souhaitent apprendre les fondamentaux de GitLab CI, étape par étape. Il vous accompagne à travers les principes de base des pipelines, l'orchestration des tâches et les modèles réutilisables grâce aux templates et composants, afin que vous puissiez automatiser en toute confiance les builds, les tests et les déploiements dans n'importe quel projet.

Workbook GitLab CI - Les fondamentaux de l'intégration et du déploiement continus (CI/CD)
Photo par Vitali Gariev / Unsplash

Pipelines

Pipelines | Référence .gitlab-ci.yml

La fonctionnalité Gitlab CI crée un pipeline pour exécuter des tâches conformément au fichier de configuration principal de Gitlab CI : .gitlab-ci.yml.

Les tâches exécutées au sein d'un pipeline CI/CD GitLab sont appelées emplois et s'exécutent dans des étapes spécifiques. Les étapes servent à organiser l'exécution des tâches. Les tâches s'exécutent à l'intérieur de coureurs Cela devrait être disponible pour le projet Gitlab.

La liste des étapes disponibles pour un pipeline GitLab CI est déclarée à l'intérieur du .gitlab-ci.yml fichier comme suit:

stages:
  - sast
  - package
  - deploy

Chaque tâche sélectionne l'étape sur laquelle elle doit s'exécuter, et les tâches s'exécutent séquentiellement selon l'ordre des étapes (par exemple, les tâches de l'étape « sast » s'exécutent, puis celles de l'étape « package », puis celles de l'étape « deploy », etc.). Par défaut, les tâches d'une même étape sont exécutées en parallèle.

Voici une capture d'écran d'un pipeline Gitlab CI et de sa configuration associée :

gitlab-ci-pipeline.webp

La routine shell .gitlab-ci.yml configuration pour ce pipeline :

# Stages definition

stages:
  - sast
  - package
  - deploy

# Jobs definition

trivy:
  image: alpine
  stage: sast
  script:
    - echo "Running Static Application Security Testing on the app code"

docker-build-push:
  image: alpine
  stage: package
  script:
    - echo "Packaging app"

helmfile-apply:
  image: alpine
  stage: deploy
  script:
    - echo "Deploying the app into Kubernetes"

Nous en apprendrons davantage sur la configuration des pipelines Gitlab CI dans les sections suivantes, continuez votre lecture.

Runners

Runners | Gestion des coureurs | Exécuteurs de la Cour | Inscription d'un coureur

Carrières Dans un pipeline GitLab CI, les tâches sont exécutées par des runners. Les runners sont des ressources de calcul (machines physiques ou virtuelles, clusters Kubernetes, etc.) qui peuvent s'enregistrer auprès d'une instance GitLab à trois niveaux différents :

  • instance Le runner est enregistré pour l'ensemble de l'instance GitLab. Tous les projets de cette instance peuvent voir et utiliser le runner.

  • group Le runner est enregistré uniquement pour un groupe spécifique. Seuls les projets appartenant à ce groupe peuvent voir et utiliser le runner.

  • project Le runner est enregistré uniquement pour un projet spécifique. Seul ce projet peut voir et utiliser le runner.

Avant d'enregistrer et de gérer les runners Gitlab, nous devons comprendre le concept de coureurs exécuteurs testamentaires.

Lorsque nous enregistrons un runner sur une instance Gitlab (en utilisant le interface de ligne de commande gitlab-runner (ou le fichier de configuration), nous devons spécifier un exécuteur pour le runner. L'exécuteur détermine l'environnement d'exécution des tâches. Voici des exemples :

  • exécuteur d'instance Les tâches exécutées dans un runner enregistré auprès de l'exécuteur d'instance auront un accès complet à l'instance hôte, au système d'exploitation et aux périphériques connectés. Les commandes des tâches sont exécutées directement dans une session shell sur l'instance hôte.

  • exécuteur Docker Les tâches exécutées par un runner enregistré auprès de l'exécuteur Docker s'exécuteront dans un conteneur isolé. L'image du conteneur utilisée pour exécuter la tâche est définie dans la configuration de cette dernière. Cet exécuteur requiert… Démon Docker à installer afin de pouvoir créer des conteneurs pour chaque tâche.

  • exécuteur Kubernetes - Les tâches exécutées dans un runner enregistré auprès de l'exécuteur Kubernetes s'exécuteront en tant que pods au sein d'un cluster Kubernetes. Ici Vous trouverez des instructions pour enregistrer un runner auprès de l'exécuteur Kubernetes sur une instance GitLab à l'aide d'un Helm graphique.

Pour obtenir la liste complète des exécuteurs de runners GitLab, consultez : ceci..

Pour obtenir des instructions sur la manière d'inscrire et de gérer les coureurs, consultez :

Carrières

Carrières | Mots clés du poste

Un job Gitlab CI est la plus petite unité de calcul d'un pipeline.

myjob:
  image: ubuntu
  before_script:
    - echo "Preparing script execution"
  script:
    - echo "single line command"
    - |
      echo "$message multiline command 1"
      echo "$message multiline command 2"
  variables:
    message: "Hello"
  tags: "myrunnertag"
  • La routine shell image Ce mot-clé ne doit être utilisé que lorsque votre exécuteur utilise une technologie de conteneur comme exécuteur (Docker, Kubernetes, etc.).

  • Si votre runner n'utilise pas de technologie de conteneur comme exécuteur et que vous utilisez le image S'il s'agit d'un mot-clé, il sera tout simplement ignoré.

  • Un emploi doit contenir au moins les scénario or déclencher mot-clé.

  • La routine shell les variables Le mot-clé peut être utilisé pour déclarer des variables qui peuvent être réutilisées ailleurs dans la tâche (script, before_script, règles, etc.).

  • La routine shell avant_script, scénario et après_script Des mots clés peuvent être utilisés pour exécuter des commandes depuis l'interpréteur de commandes du conteneur d'image spécifié.

Artefact Dotenv

Rapport dotenv sur les artefacts

myjob1:
  image: ubuntu
  script:
    - echo "config1=value1" > $configfile
    - echo "config2=value2" >> $configfile
  variables:
    configfile: "config.env"
  artifacts:
    reports:
      dotenv: $configfile
    
# myjob2 can access variables declared
# inside the dotenv artifact from myjob1
myjob2:
  image: ubuntu
  script:
    - echo $config1
    - echo $config2
  • La routine shell artefacts:rapports:dotenv La configuration crée un artefact contenant le fichier dotenv spécifié.

  • La routine shell key=value Les variables de paires déclarées dans le fichier dotenv seront transférées aux tâches suivantes en tant que variables d'environnement.

Modèle

Aperçu et déclaration

emploi caché

  • Un modèle Gitlab CI définit des configurations qui peuvent être réutilisées par d'autres tâches.

  • Un modèle peut utiliser tous les mots-clés d'une offre d'emploi

  • Par conséquent, une offre d'emploi telle qu'elle apparaît dans la section « Offres d'emploi » peut également servir de modèle, mais la méthode courante pour déclarer un modèle consiste à créer une « offre d'emploi cachée » comme suit :

.mytemplate:
  image: ubuntu
  tags: "myrunnertag"
  variables:
    message: "Hello"

Utiliser le modèle dans un autre emploi

Étend le mot-clé | Réutilisation des configurations avec extensions | Détails de fusion étendus

Un emploi peut utiliser un modèle grâce à S'étend comme suit :

myjob:
  extends: .mytemplate
  script:
    - echo $message

Inclure des modèles provenant d'autres fichiers

Inclure le mot-clé | Inclure les locaux | Inclure le projet | Inclure les composants

Les modèles peuvent être déclarés dans leurs propres fichiers dédiés et inclus dans d'autres fichiers de configuration Giutlab CI comme suit :

  • Incluez un modèle situé dans le même dépôt et la même branche. Le chemin que vous spécifiez est relatif au répertoire où se trouve le fichier contenant les modèles :
include: 'mytemplates.gitlab-ci.yml'

# Can also be written:
include: 
  - local: '/mytemplates.gitlab-ci.yml'
  • Incluez un modèle situé dans un dépôt différent au sein de l'instance Gitlab actuelle :
include:
  - project: 'my-group/my-project'
    file: '/mytemplates.gitlab-ci.yml'

# Another form for multiple files and
# branch other than the default one
include:
  - project: 'my-group/my-project'
    file: 
      - '/mytemplate1.gitlab-ci.yml'
      - '/mytemplate2.gitlab-ci.yml'
    ref: "mybranch"

Modèles contenant plusieurs sections

Vous pouvez également créer des modèles contenant plusieurs sections :

# File: templates.gitlab-ci.yml

.terraform-scripts:
  init:
    - terraform init
  plan:
    - terraform plan
  apply:
    - terraform apply

Référencer les sections de modèles avec !reference

!référence

Les sections à l'intérieur d'un modèle peuvent être réutilisées dans d'autres projets grâce à !référence comme suit :

include: templates.gitlab-ci.yml

terraform-plan:
  image: hashicorp/terraform
  extends: .terraform-scripts
  script:
    - !reference [".terraform-scripts", "init"]
    - !reference [".terraform-scripts", "plan"]

terraform-apply:
  image: hashicorp/terraform
  extends: .terraform-scripts
  script:
    - !reference [".terraform-scripts", "init"]
    - !reference [".terraform-scripts", "apply"]

Paramètres et variables par défaut pour tous les emplois

Configurer les paramètres par défaut globaux

Mot-clé par défaut

default:
  image: ubuntu
  tags: "myrunnertag"
  interruptible: true
  • La routine shell défaut Ce mot-clé peut être utilisé pour configurer des paramètres par défaut globaux qui s'appliquent à tous les travaux pour lesquels ils ne sont pas déjà définis.

  • Si les paramètres par défaut sont déjà définis au niveau de la tâche, la définition de la tâche prévaut.

Configurer les variables globales par défaut

Variables

# Declare default global 
# variables for all jobs

variables:
  APP_NAME: "myapp"
  APP_VERSION: "1.0.0"
  • La routine shell les variables Le mot-clé peut être utilisé pour déclarer des variables par défaut :

    • pour des emplois spécifiques lorsqu'ils sont utilisés au niveau de l'emploi

    • globalement pour toutes les tâches lorsqu'il est utilisé au niveau supérieur dans le fichier de configuration Gitlab CI

Variables prédéfinies

Variables prédéfinies

  • CI Gitlab variables prédéfinies sont disponibles pour tous les emplois.

  • Pour obtenir la liste complète des variables prédéfinies de GitLab CI, consultez : Liste des variables prédéfinies de GitLab CI

  • Voici une liste de quelques variables prédéfinies couramment utilisées :

    • CI_COMMIT_BRANCH
    • CI_DEFAULT_BRANCH
    • CI_COMMIT_REF_NAME
    • CI_COMMIT_SHORT_SHA
    • CI_COMMIT_TAG
    • CI_PIPELINE_SOURCE
    • CI_PIPELINE_URL
    • CI_PROJECT_DIR
    • CI_MERGE_REQUEST_IID

Contrôler l'exécution des tâches à l'aide de règles

Règles

La routine shell Le mot-clé peut être utilisé pour définir les conditions de création ou non d'une tâche. La plupart du temps, vous en aurez besoin. Variables prédéfinies de GitLab CI dans vos règles. Voici des exemples :

  (...)
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_BRANCH
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never

Contrôlez l'exécution des pipelines avec le workflow

Workflow

La routine shell workflow Le mot-clé peut être utilisé pour définir les conditions de création ou non d'un pipeline. Voici des exemples :

# Create Merge Requests and branch
# pipelines while avoiding duplicates (two pipelines
# running at the same time after a commit in a Merge Request branch)

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: $CI_COMMIT_BRANCH

Exécution d'un ensemble de tâches dans des pipelines en aval

Imaginez que vous ayez plusieurs applications à déployer. Les tâches GitLab CI nécessaires au déploiement de toutes ces applications sont identiques et placées dans un environnement standardisé. deploy.yml.

Vous souhaitez un pipeline qui déploie deux de vos applications en utilisant cette norme deploy.yml Fichier CI. Une façon d'y parvenir tout en conservant un pipeline bien organisé consiste à utiliser des pipelines en aval, ce qui vous donnera un résultat similaire à celui-ci :

gitlab-ci-downstream-peipelines-overview-1.webp

gitlab-ci-downstream-peipelines-details-1.webp

Pour créer des pipelines en aval, vous utilisez GitLab CI. déclencher Voici des exemples de fichiers de configuration GitLab CI utilisés pour créer les pipelines illustrés dans les images ci-dessus :

  • standardisé deploy.yml contenu du fichier:
# deploy.yml

stages:
  - infra
  - app

create-infra:
  stage: infra
  script: echo "Creating $INFRA_TYPE infrastructure"

deploy-app:
  stage: app
  script: echo "Deploying app $APP_NAME into $INFRA_TYPE infrastructure" 
  • principal .gitlab-ci.yml contenu du fichier:
# .gitlab-ci.yml

stages:
  - app1
  - app2

app1:
  stage: app1
  trigger:
    include: 'ci/deploy.yml'
    strategy: depend
  variables:
    APP_NAME: myapp1
    INFRA_TYPE: VM

app2:
  stage: app2
  trigger:
    include: 'ci/deploy.yml'
    strategy: depend
  variables:
    APP_NAME: myapp2
    INFRA_TYPE: K8S

Composants Gitlab CI

Composants | Meilleures pratiques en matière de composants

Création et documentation d'un composant Gitlab CI

Voici une structure de projet de base que vous pouvez utiliser pour créer un composant Gitlab CI :

.
├── .gitlab-ci.yml
├── README.md
└── templates
    └── component1.yml
    └── component2.yml
    └── ...
  • templates - le répertoire contenant les fichiers des composants. Un fichier .yml par composant.
  • README.md - la documentation des composants. Quels composants sont disponibles, comment les utiliser dans d'autres projets, quelles entrées sont disponibles (nom, description, type, etc.).
  • .gitlab-ci.yml - un fichier de configuration classique de pipeline CI Gitlab contenant des tâches permettant de tester et de publier automatiquement les composants.

Pour connaître toutes les options disponibles concernant la structure d'un projet de composants GitLab CI, consultez : ceci..

Examinons maintenant la structure d'un composant :

# Component: hello
# templates/hello.yml

# => First part: inputs

spec:
  inputs:
    name:
      type: string
      description: 'The name of the person to greet.'
    stage:
      description: 'GitLab CI stage to run the hello job in'
      default: 'test'

--- # don't forget these 3 dashes

# => Second part: component jobs

# Here you can use classic Gitlab CI jobs / templates / variables

# A template containing script functions that
# will be used by the component.

.hello-scripts: &hello-scripts |
  set -euo pipefail

  function log_info() {
      echo -e "[\\e[1;94mINFO\\e[0m] $*"
  }

  function log_error() {
      echo -e "[\\e[1;91mERROR\\e[0m] $*"
  }

  function assert_defined() {
    if [[ -z "$1" ]]
    then
      log_error "$2"
      exit 1
    fi
  }

# A template used to define rules for the hello job
# Could be overridden from inside projects that use this
# component to set custom rules for running the compoenents jobs

.hello-rules:
  rules:
    - if: $CI_COMMIT_BRANCH
    - if: $CI_MERGE_REQUEST_IID

# A job that will be created by the component
# Multiple jobs can be added

hello:
  image: ubuntu
  stage: $[[ inputs.stage ]]
  extends: .hello-rules
  script:
    - !reference [.hello-scripts]
    - assert_defined $[[ inputs.name ]]
    - log_info "hello $[[ inputs.name ]]"

Une fois les composants prêts, nous pouvons générer automatiquement la documentation utilisateur en utilisant pré-commit et la hook pre-commit de Labdoc.

De cette façon, nous pouvons facilement régénérer la documentation après les modifications apportées au dépôt Git des composants, juste avant la validation.

Utilisation d'un composant Gitlab CI

Pour utiliser un composant Gitlab CI, il suffit de l'inclure dans un .gitlab-ci.yml fichier comme suit:

include:
  - component: "<gitlab_server_fqdn>/<path_to_component_project>/<component_name>@<component_version>"
    inputs: {}

Voici un exemple:

stages:
  - hello
  
include:
  - component: gitlab.com/hackerstack/skeletons/gitlab-ci-component/hello@1.0.0
    inputs:
      name: 'gmkziz'
      message: 'You are doing a great job here!'
      stage: 'hello'

Test et publication d'un composant Gitlab CI

Ajoutons maintenant un pipeline de test et de déploiement au sein du projet de composants en créant un .gitlab-ci.ymlVoici le contenu :

# This makes a pipeline run when there is a commit on any branch
# and avoid duplicated jobs in Merge Requests branches
workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: $CI_COMMIT_BRANCH

# Here we define the stage of the pipeline
# test will be used to run a job that test the component
# publish will be used to run a job that creates a version tag
# for the component and associates a release to it.
stages:
  - test
  - publish

include:
  # Here we call the component with the latest commit sha as the version
  # That way, we test it on each new commit inside the project
  - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/hello@$CI_COMMIT_SHA
    inputs:
      name: 'gmkziz'
      message: 'You are doing a great job here!'
      stage: 'test'

  # Here we use a semantic-release component to ease the release process
  - component: $CI_SERVER_FQDN/to-be-continuous/semantic-release/gitlab-ci-semrel@4.1
    inputs:
      # Make semantic-release job runs automatically, manual by default
      auto-release-enabled: true

Pour que le composant de libération sémantique fonctionne, vous devez ajouter un GITLAB_TOKEN variable à l'intérieur des variables CI/CD de votre projet, comme décrit iciPour en savoir plus sur la libération sémantique, consultez ceci..

Nous pouvons également faire apparaître les composants à l'intérieur de Catalogue Gitlab CI/CD en suivant les instructions ici.

Voici un composant J'ai publié dans le catalogue CI/CD de gitlab.com.

Autres fonctionnalités de GitLab CI

Matrice parallèle

Parallèle | Matrice parallèle

Vous pouvez utiliser GitLab CI matrice parallèle Fonctionnalité permettant d'exécuter une tâche plusieurs fois dans un seul pipeline avec des valeurs de variables différentes pour chaque instance de la tâche.

Voici un exemple:

stages:
  - greetings

hello:
  image: alpine
  stage: greetings
  script:
    - echo "Hello $NAME. $MESSAGE"
  parallel:
    matrix:
      - NAME: 'Ali'
        MESSAGE: 'How are you?'
      - NAME: 'gmkziz'
        MESSAGE: 'You are doing a great job!'
      - NAME: ['Bobo', 'Baba']

Résultat:

gitlab-ci-parallel-matrix.webp

pipelines programmés

pipelines programmés

Vous pouvez utiliser GitLab CI pipelines programmés Cette fonctionnalité permet d'exécuter des pipelines à intervalles réguliers selon des modèles cron. Utilisez les planifications de pipelines pour les tâches qui doivent s'exécuter selon une planification temporelle plutôt que déclenchées par des modifications de code.

entrées du pipeline

Vous pouvez également utiliser les entrées GitLab CI pour simplifier la création et la configuration de pipelines à des fins spécifiques. Lorsqu'un utilisateur crée un nouveau pipeline via « Pipelines → Nouveau pipeline », les entrées s'affichent et sont disponibles pour la configuration.

gitlab-ci-inputs-pipeline.webp

Voici la configuration Gitlab CI associée :

spec:
  inputs:
    name:
      description: 'Name of the person to greet'
      default: 'gmkziz'
      type: string
    message:
      description: 'Greeting message'
      default: 'You are doing a great job!'
      type: string

---

stages:
  - greetings

hello:
  image: alpine
  stage: greetings
  script:
    - "echo Hello $[[ inputs.name ]]. $[[ inputs.message ]]"

Fonctions Gitlab CI

Fonctions CI

La fonctionnalité « Fonctions GitLab CI » fournit des unités réutilisables de logique de tâches CI/CD qui remplacent le script dans une tâche GitLab CI/CD. Cette fonctionnalité est actuellement expérimentale et peut subir des modifications importantes.


Vous souhaitez signaler une erreur ou poser une question ? N'hésitez pas à m'envoyer un e-mail à gmkziz@hackerstack.orgJe serai heureux de répondre.

Si vous aimez mes articles, pensez à vous inscrire à ma newsletter afin de recevoir les derniers articles dès qu'ils sont disponibles.

Prenez soin de vous, continuez à apprendre et à bientôt pour le prochain post 🚀