11 min read

Mise en place d'une stack de CI/CD avec des outils IaC

Dans ce blog nous allons voir les objectifs d'une pipeline de CI/CD ainsi que certains des outils permettant de mettre en place des processus automatisés.

#jenkins

#git

#terraform

#ansible

#docker

Article publié le 31 janv. 2023

·

11 min de lecture

1. Objectifs

La mise en place de pipelines de CI/CD, permet de simplifier la vie du développeur. Cela lui permet également de s'assurer que son code est de qualité avant même d'atteindre la production. Les objectifs principaux lorsque l'on veut mettre en place une pipeline de déploiement continue, sont généralement pour:

  • Agir sur une infrastructure facilement: une fois la pipeline mise en place, les devs, les ops pourront se concentrer sur d'autres tâches d'améliorations et d'automatisations. Car une fois en place, les tests et déploiements seront sûr d'être exécutés.

  • Automatiser les tests et les déploiements: le développeur pourra se concentrer sur son code. Une fois ses modifications terminées, il aura juste pousser son code sur Git et lancer le job, ce qui aura pour effet de déclencher des processus: la mise en place (ou mise à jour) du serveur, le build de l'application, l'exécution des différents tests et le déploiement.

  • Garantir un environnement de test similaire à celui de la production: Comme on utilise la même pipeline pour l'environnement de dev et de prod on garantit les mêmes étapes que pour la production et facilitant la maintenance.Et en utilisant Docker, on pourra garantir que les tests sont exécutés dans un environnement similaire à celui de la production, réduisant ainsi les risques de bugs liés à des différences d'environnement.

  • Automatiser la configuration de notre serveur: en utilisant Ansible pour décrire les étapes nécessaires pour configurer et déployer nos applications sur nos serveurs, nous pouvons automatiser la configuration de notre environnement de test et de production.

  • Améliorer la qualité et la fiabilité des mises à jour: En utilisant ces outils ensemble, nous pouvons mettre en place une chaîne d'intégration continue efficace, améliorant ainsi la qualité et la fiabilité des mises à jour.

Ci-dessous un schéma permettant de visualiser notre pipeline comprenant les relations entre les différents acteurs ainsi que l'exécution des différents actions dans le temps:

1_sequence_diagram.png

Comment se déroulera la phase de déploiement ?

1. Le développeur, une fois son code push dans son repo GitHub,se connecte à l'interface web de Jenkins et lance la pipeline de déploiement.

💡 Cette partie peut être automatisé en intéragissant avec des webhooks, contactez un de nos experts pour discutez de vos besoins

2. Jenkins récupère les dernière sources du projet configuré sur GitHub. Ici pour simplifié, les fichiers de Terraform et de Ansible seront dans le même repo GitHub.

3. Grâce au plugin Terraform, Jenkins exécutera nos fichiers .tfpour créer (ou mettre à jour) notre machine dans le Public Cloud de OVH. Puis, on exécutera le playbook Ansible qui installera les paquets nécessaires sur notre machine ainsi avec les dépendances nécessaires pour le bon fonctionnement de notre application.

4. Ensuite, une fois la machine prête à accueillir notre application, on va build l'image Docker de notre application et lancer nos tests unitaires et de sécurité.

5. Si les tests sont ok, alors l'application est déployé, avec un autre playbook Ansible sur notre machine.

2. Les outils

Pour que la chaîne de CI/CD soit efficace et performante, nous utiliserons des outils tels que Jenkins, Docker, Terraform et Ansible qui nous permettrons d'automatiser la création d'instance sur le Public Cloud de OVH, d'automatiser les tests et les déploiements dans le but de réduire les risques de bugs ainsi que les temps de déploiements et de maintenances.

2.1. GitHub

📦 - En utilisant GitHub pour stocker le code source de notre application, on pourra par la suite automatiser les tâches de build et de déploiement de notre application. Dans notre répertoire GitHub on stockera nos fichiers Terraform, nos fichiers Ansible ainsi que le code source de notre application.

🎁 Les fichiers seront disponibles sur le GitHub KanOps.

Notre répertoire Git sera organisé comme suit:

  • Un répertoire /terraform qui contiendra les différents fichiers de configuration de notre infrastructure. Ici, cette structure de nos répertoires et fichiers, nous permet peut importe le nombre d'environnements qu'on possède d'utiliser les mêmes modules:
    |_terraform/
        |_...
    
  • Un répertoire /ansible qui contiendra nos playbooks de configuration et de déploiement:
    |_ansible/
        |_...
    
  • Le répertoire qui contient notre application
    |_/app
        |_Dockerfile
        |_entrypoint.sh
    
  • Et pour finir le dossier contenant notre ```Jenkinsfile````
    |_ci
        |_Jenkinsfile
    

2.2. Docker

🐳 - Docker est un outil de conteneurisation qui peut permettre de créer des environnements isolés pour les tests et les déploiements. Cela garantit que les tests sont exécutés dans un environnement similaire à celui de la production, réduisant ainsi les risques de bugs liés à des différences d'environnement. Nos images seront stockés uniquement sur la machine en local.

💡 Pour avoir un historique complet des différentes versions vous pouvez créer un commpte sur Dockerhub et y poussez vos images.

Sur le GitHub de Docker nous pouvons trouver un utilitaire qui nous servira à tester la sécurité de notre image Docker et permettre d'apercevoir les éventuels mauvaises configurations. Pour benchmark notre image, nous devons dans un premier temps cloner le répertoire docker-bench-security:

git clone https://github.com/docker/docker-bench-security.git && cd docker-bench-security

Puis, nous pouvons lancer le scan de notre image:

sudo ./docker-bench-security.sh -i notre-image

À la fin de l'exécution, un score sera attribué ainsi que les diverses modifications à effectuer.

2.3. Jenkins

⚙️ - Jenkins est un système de CI/CD open source qui permet de déclencher des builds et des tests automatisés en fonction de la fréquence ou de l'événement souhaité. Il peut également être utilisé pour déclencher des déploiements automatisés sur les serveurs de production. Dans un premier temps on installera Jenkins avec Docker, puis dans un second temps on écrira notre pipeline dans un fichier Jenkinsfile qui contiendra nos stages et steps avec du code Groovy.
Ici, dans notre tutoriel ,Jenkins est le cœur du système, il permettra de :

  • Utiliser le plugin Terraform pour communiquer avec l'API Openstack d'OVH et pouvoir configurer notre infrastructure dans le Public Cloud. Ici la documentation.
  • UtiliserAnsible pour configurer notre instance et déployer notre application.
  • Lancer les tests sur notre application et pouvoir les visualiser.
  • Déployer notre application en production si les tests sont validés.

Nous allons déployer Jenkins sur notre machine en local. Nous créerons donc un répertoire ainsi qu'un volume Docker pour y stocker les données de Jenkins.

⚠️ Ceci est nécessaire pour ne pas perdre les configurations lors du redémarrage du conteneur.

On crée notre répertoire :

mkdir $HOME/jenkins

⭐️ Vérifier que l'utilisateur qui lance le conteneur a les droits de lecture/d'écriture dans ce répertoire.

On créer le volume, en spécifiant un répertoire où les configurations seront accessibles:

docker volume create --opt type=none \
--opt device=$HOME/jenkins \
--opt o=bind \
jenkins-volume

Nous pouvons lancer notre conteneur avec l'image jenkins/jenkins:lts en montant le volume précédemment crée:

docker run --name jenkins -d \
-v jenkins-volume:/var/jenkins_home \
-p 8080:8080 -p 50000:50000 \
jenkins/jenkins:lts

⭐️ Une fois lancé, il faudra récupérer le mot de passe admin généré par Jenkins dans les logs ou directement dans le conteneur ici /var/jenkins_home/secrets/initialAdminPassword.

Nous pouvons donc accéder à l'interface de Jenkins à cette adresse : http://localhost:8080.

Ensuite, une fois le mot de passe admin renseigné, nous pouvons "Installer les plugins suggérés" :

jenkis_cicd_jenkins_init.gif

Puis une fois l'installation de base terminée, on peut donc installer nos plugins Ansible et Terrafom. Nous installerons par la suite Terrafom directement dans le conteneur :

jenkins_install_plugins.gif

Pour pouvoir utiliser la commande terraform dans Jenkins, on devra installer manuellement terraform dans notre conteneur jenkins:

  • Ouvrons un shell en root dans le conteneur:
    docker exec -u root -it jenkins /bin/bash
    
  • Mettons à jour les paquets et installer des paquets nécessaires:
    apt update && apt install -y wget lsb-release docker.io
    
  • Ajoutons la clé .gpg de Hashicorp:
    wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
    
  • On crée le dépôt de Hashicorp dans les sources:
    echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/hashicorp.list
    
  • Puis, installons le paquet terraformà la version 1.1.9:
    apt update && apt install terraform=1.1.9
    
  • Check de la version de terraform:
    terraform --version
    

Pour finir, nous devons ajouter la clé privée SSH utilisé pour accéder aux machines. Cela sera nécessaire pour lancer nos playbooks ansible par la suite. Pour cela, nous devons nous rendre dans le panneau d'administration de Jenkins et créer un credential de type SSH : jenkins_add_credentials.png

Notre serveur Jenkins est maintenant prêt pour la création de notre pipeline dans un fichier Jenkinsfile ! 🚀

2.4. Terraform

💻 - Terraform est un outil de gestion de la configuration d'infrastructure. Il permet de décrire les ressources d'infrastructure (serveurs, réseaux, stockage, etc.) sous forme de code et de les déployer automatiquement sur différents fournisseurs d'infrastructure (AWS, GCP, Azure, etc.).

⭐️ Les descriptions de ressources sont écrites en HashiCorp Configuration Language (HCL), qui est similaire à YAML.

Avec Terraform, les Admin Sys et les Devops peuvent décrire les ressources nécessaires pour leur infrastructure dans des fichiers au format .tf sous forme de code. Ce qui facilite la gestion et la réutilisation des ressources. Cela permet de déployer rapidement et de manière fiable leurs infrastructures.

⭐️ Ici Terraform sera utilisé uniquement pour créer l'infrastructure, la configuration du seveur sera gérer par Ansible.

L'arborescence de notre dossier /terraform sera comme suit :

|_terraform/
    |_modules/
        |_ app/
            |_main.tf
            |_variables.tf
            |_output.tf
            |_versions.tf
    |_dev/
        |cloud-structure/
            |_main.tf
            |_versions.tf
        |_firewall/
            |_main.tf
            |_versions.tf
        |_instances/
            |_main.tf
            |_versions.tf
    |_prod/
        |_cloud-structure/
            |_main.tf
            |_versions.tf
        |_firewall/
            |_main.tf
            |_versions.tf
        |_instances/
            |_main.tf
            |_versions.tf

👨🏽‍💻 Cette structure à était réfléchie et mis en place par notre expert Brian Benoit !

Contactez-nous pour établir des infrastructures évolutives et performantes !

Pour finaliser, nous devons configurer les credentials Openstack dans Jenkins, en tant variables d'environnements, pour permettre à Terraform d'agir sur le Public Cloud d'OVH. Pour cela, nous devons nous connecter à l'interface horizon d'OVH pour récupérer les identifiants nécessaires. Ces variables d'environnements pourront par la suite être utilisées dans notre Jenkinsfile. En procédant ainsi, aucun secrets ne sont exposés, vos identifiants resteront en local dans votre conteneur jenkins.

2.5. Ansible

🛠️ - Ansible (écrit en python par RedHat) est un outil de configuration et de déploiement automatisé. Il utilise des scripts, appelés playbooks, pour décrire les tâches à effectuer sur les serveurs. Les playbooks sont écrits en YAML, ce qui les rend faciles à lire et à comprendre.

L'intérêt d'utiliser Ansible dans une chaîne d'intégration continue (CI) est qu'il permet de configurer et de déployer rapidement des applications sur des serveurs, en automatisant les tâches répétitives. Cela peut réduire les erreurs humaines et accélérer les déploiements, améliorant ainsi la qualité et la rapidité de la livraison des projets..

Ci-dessous, l'arborescence de notre répertoire /ansible:

ansible/
    |_/roles
        |_role1/
            |_defaults/
                |_main.yml
            |_files/
            |_tasks/
                |_main.yml
        |_role2/
            |_...
playbook1.yml
playbook2.yml

Ici, avec cette structure, nous pouvons utiliser un même role dans plusieurs playbook différents. Ici, l'objectif est de rendre un role le plus générique possible, exemples : docker, postgresql, ... .

Conclusion

En conclusion, les outils d'Infrastructure as Code (IaC) jouent un rôle crucial dans l'automatisation de la configuration et du déploiement de l'infrastructure dans une chaîne d'intégration continue. En utilisant des outils tels que Terraform, Ansible ou CloudFormation, vous pouvez gérer efficacement vos ressources informatiques, réduire les erreurs humaines et faciliter les mises à jour de votre infrastructure.

Ce tutoriel vous a permis de découvrir les avantages de l'utilisation des outils IaC dans votre pipeline CI. Vous avez appris à utiliser ces outils pour décrire, provisionner et configurer votre infrastructure de manière automatisée. Vous avez également découvert les concepts clés tels que la gestion des versions, les dépendances et les workflows.

Nous espérons que ce tutoriel vous a aidé à comprendre l'importance de l'utilisation des outils IaC dans votre pipeline CI et vous a incité à les utiliser dans vos projets. Nous vous invitons à suivre notre prochain tutoriel pour découvrir comment mettre en place une pipeline complète en utilisant ces outils, de la planification à la livraison continue.

Auteur Billy PAYET

Billy PAYET

Billy est un expert en DevOps qui a une solide expérience en automatisation et en intégration continue. Il utilise des outils tels que Ansible, Jenkins et Docker pour améliorer les processus de déploiement et de livraison des applications. Il est passionné par l'amélioration continue et aider les équipes à atteindre leurs objectifs de qualité et de performance.