EPSI — Développer et sécuriser une solution Cloud

Dernière révision de la page : 31/01/2023

Création d’un nouveau repository

Un repository Github est un espace de stockage en ligne pour un projet basé sur Git. Il permet de stocker le code source, les fichiers de documentation et les fichiers de configuration d’un projet. Il permet également de suivre les modifications apportées au code, de collaborer avec d’autres développeurs et de gérer les versions du projet. Il est possible d’accéder, de télécharger, de forker et de contribuer à un repository Github. Les utilisateurs peuvent également utiliser les fonctionnalités de Github pour créer des issues, gérer des tâches, et effectuer des revues de code. Nous allons donc nous rendre sur la page d’accueil de Github pour créer un nouveau repository en cliquant sur le bouton vert intitulé « New » situé sur la gauche dans la section de nos repository.

Le screenshot montre la page de création d’un nouveau référentiel (repository). On remplit le champ « Repository name » qui va reflétait notre code, le champs description et licence sont optionnelles. Nous allons choisir un référentiel privé, ainsi que l’ajout d’un README file puis on clique sur « Create repository »

SSH (Secure Shell) est un protocole de réseau qui permet de se connecter à un ordinateur distant de manière sécurisée. Il permet de se connecter à un ordinateur distant via une connexion chiffrée, ce qui protège les informations échangées contre la surveillance et la modification par des tiers. SSH est souvent utilisé pour accéder à un serveur à distance pour exécuter des commandes ou transférer des fichiers, ou pour configurer une connexion sécurisée pour d’autres protocoles de réseau, comme FTP ou Telnet. SSH utilise généralement des clés pour l’authentification plutôt que des mots de passe, ce qui renforce encore la sécurité. On génère une nouvelle paire de clef SSH avec les paramètres par défaut, cette paire de clef va nous permettre de nous identifier auprès de notre compte GitHub.

ssh-keygen
Bash user command
Output command
Generating public/private rsa key pair.
Enter file in which to save the key (/home/epsi/.ssh/id_rsa): 
Created directory '/home/epsi/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/epsi/.ssh/id_rsa
Your public key has been saved in /home/epsi/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:xN/A0FLqW2lgxCw9eezmB0V5gX27Z1hEljtSX+XoarA epsi@zeorus-epsi
The key's randomart image is:
+---[RSA 3072]----+
|       +o=...+.o*|
|      .oB++ + o*+|
|       .*=o. .oo*|
|       + o++ o +o|
|        So*.. ooo|
|         +.o....o|
|        . E.o  ..|
|           .     |
|                 |
+----[SHA256]-----+

On affiche notre clef publique précédemment généré afin de pouvoir la renseigner dans les paramètres de notre compte GitHub.

cat .ssh/id_rsa.pub
Bash user command
Output command
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDSOgPI7UL53BgFqlED51METd24O5xiqmJvxGkT67HrWAOrzcyhAdy+wVKpNl5D+CBUQM7lGDdisGf1OEeZGOWxsl9TOHs5mOGCAXQj+ALYgLi0MjEuwLBgxLws42uhQ9HTqzordXIe4G0UCmDPwf+QPpqc/yXMFc0b5XZklgJpApGInYUhtLy/k6gApHVzBU8ChyHPpuIupe4XXKvOSpWEHhmHl1MqiLqT0658fMvYsrp9alWMz+ALrsRpZKn3u0R7YIejxRcK8kqvFheAsilFk7RgFDc/xRCPj8vX00B3ut0HZFq9qg/exDIfx/Jv61IAHh8FidcWumjnpAIIfjwf610m8kKMY/X813BJhp7oG2AuXt3gOWF7K2T0mjUaqSGEVii4kDL1lPJCFe8abnFAX5q0gqYCGtWhj4Csnfb9jYjRYfwXCLZkEgKbK1DJ5GahV6Z6LbdogsLzspKVLTjZ8wZ/YwAdqK0m7OeuG8tJeZExJUkt12d3QaePbRAcqCU= epsi@zeorus-epsi

On se rend de nouveau sur notre compte GitHub, on clique sur le bouton en haut à droite qui nous permet d’afficher les paramètres de notre compte, puis « Settings »

La page des paramètres s’affiche, dans le menu sur la gauche, vous cliquez sur SSH and GPG keys. Sur cette interface, nous pouvons nos clefs existantes si l’on en possède, et on clique sur « New SSH Key »

Nous lui indiquons un nom explicite, pour notre part c’est notre machine machine pour l’environnement de développement.

Nous allons pouvoir maintenant à partir de notre machine de développement pourvoir commencer à développer. Pour cela nous allons nous rendre sur l’interface de notre repo et de récupérer le lien afin d’installer une version en local du repo sur notre machine.

Les commandes GIT

Si le package git n’est pas installé sur votre machine, vous pouvez le faire simplement avec cette commande :

apt-get install git -y
Bash root command

La commande « git clone » est utilisée pour créer une copie d’un dépôt Git existant (Ansible-EPSI) sur votre machine de développement. Elle prend en entrée l’URL du dépôt à cloner et crée un nouveau répertoire qui contient tous les fichiers et l’historique de commits de ce dépôt. Elle permettra également de synchroniser avec d’autres commande plus tard sur le repository distant, Github.

git clone git@github.com:FlynnHub/Ansible-EPSI.git
Bash user command

On se rend dans le dossier précédemment cloné

cd Ansible-EPSI
Bash user command

Pour la configuration de git, nous allons lui déclarer notre identité pour nos futurs commits

git config --global user.email "theophilegarin@hotmail.com"
git config --global user.name "Théophile Garin"
Bash user command

On peut demander à Git les modifications qui sont apportés à notre dossier. Pour l’instant il n’y a eu aucune modification.

git status
ShellScript
Output
Sur la branche main
Votre branche est à jour avec 'origin/main'.

rien à valider, la copie de travail est propre

Nous allons créer un nouveau dossier et un nouveau fichier dedans, vous pouvez le faire avec l’éditeur de code Visual Studio Code,soit vous le faites à l’aide des commandes ci-dessous

mkdir inventory
Bash user command

vim inventory/hosts
Bash user command

Ansible-EPSI/inventory/hosts
[all]

A nouveau si nous refaisons notre git status, nous voyons que nous avions de nouveau dossier et fichier non suivis, git nous recommande d’ailleurs d’utiliser une commande afin de pouvoir suivre ce fichier.

git status
Bash user command
Output
Sur la branche main
Votre branche est à jour avec 'origin/main'.

Fichiers non suivis:
  (utilisez "git add <fichier>..." pour inclure dans ce qui sera validé)
	inventory/

aucune modification ajoutée à la validation mais des fichiers non suivis sont présents (utilisez "git add" pour les suivre)

La commande « git add . » est utilisée pour ajouter tous les fichiers modifiés ou nouveaux dans l’index de Git. L’index est un étape intermédiaire avant de faire un commit, il permet de sélectionner les fichiers qui seront intégrés dans le prochain commit. Cette commande ajoute tous les fichiers dans le répertoire courant et ses sous-répertoires à l’index. Cela vous permet de préparer les fichiers pour le prochain commit

git add .
Bash user command

git status
Bash user command
Output
Sur la branche main
Votre branche est à jour avec 'origin/main'.

Modifications qui seront validées :
  (utilisez "git restore --staged <fichier>..." pour désindexer)
	nouveau fichier : inventory/hosts

Nous allons maintenant pouvoir effectuer notre premier commit. Il existe des bonnes pratiques en terme de message de commit pour pouvoir les publier, il n’est pas nécessaire mais assure la bonne compréhension.

git commit -m "feat(inventory):Add hosts file"
Bash user command
Output
[main ba87ed9] feat(inventory):Add hosts file
 1 file changed, 1 insertion(+)
 create mode 100644 inventory/hosts

Nous pouvons maintenant pousser nos modifications sur le repository distant sur GitHub

git push
Bash user command
Output
Énumération des objets: 5, fait.
Décompte des objets: 100% (5/5), fait.
Compression par delta en utilisant jusqu'à 2 fils d'exécution
Compression des objets: 100% (2/2), fait.
Écriture des objets: 100% (4/4), 360 octets | 360.00 Kio/s, fait.
Total 4 (delta 0), réutilisés 0 (delta 0), réutilisés du pack 0
To github.com:FlynnHub/Ansible-EPSI.git
   823281c..ba87ed9  main -> main

Si nous retournons maintenant sur notre interface GitHub, nous pouvons apercevoir nos modifications, que le dossier inventory est bien apparu, il y’a deux minutes

Nous pouvons afficher toutes nos branchs disponible via cette commande. L’étoile désignant la branch actuelle sur laquelle on se trouve. La branch main étant la principale, c’est celle qui doit être « Production Ready », tout le temps utilisable.

ShellScript
git branch -a 
ShellScript
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main

Nous pouvons créer des autres branchs afin de pouvoir développer des nouvelles fonctionnalités ou encore améliorer notre code. Une fois que sur notre branch le code est prêt et fonctionnel sans rétrogradation, nous pourrons le merger plus tard. Nous souhaitons créer une nouvelle branch afin de compléter notre inventaire.

git checkout -b "Complete_Inventory"
Bash user command

git branch -a
Bash user command
Output
* Complete_Inventory
  main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main

On créé nos dossiers

mkdir inventory/group_vars && mkdir inventory/host_vars
touch inventory/group_vars/APACHE.yml && touch inventory/host_vars/apache1.yml
Bash user command

On regarde nos modifications

git status
Bash user command
Output
Sur la branche Complete_Inventory
Fichiers non suivis:
  (utilisez "git add <fichier>..." pour inclure dans ce qui sera validé)
	inventory/group_vars/
	inventory/host_vars/

aucune modification ajoutée à la validation mais des fichiers non suivis sont présents (utilisez "git add" pour les suivre)

On les ajoutes à notre Index

git add .
Bash user command

On commit nos modifications

git commit -m "feat(inventory): Add Apache group and host_vars"
Bash user command

On push nos modifications

git push
Bash user command
Output
fatal: La branche courante Complete_Inventory n'a pas de branche amont.
Pour pousser la branche courante et définir la distante comme amont, utilisez

    git push --set-upstream origin Complete_Inventory

Vu qu’il s’agit d’une nouvelle branche qui est connu en local, mais pas sur notre repository distant, nous devons effectuer cette commande à chaque fois qu’une nouvelle branch n’est pas connu par Github

git push --set-upstream origin Complete_Inventory
Bash user command
Output
Énumération des objets: 8, fait.
Décompte des objets: 100% (8/8), fait.
Compression par delta en utilisant jusqu'à 2 fils d'exécution
Compression des objets: 100% (3/3), fait.
Écriture des objets: 100% (6/6), 528 octets | 528.00 Kio/s, fait.
Total 6 (delta 0), réutilisés 0 (delta 0), réutilisés du pack 0
remote: 
remote: Create a pull request for 'Complete_Inventory' on GitHub by visiting:
remote:      https://github.com/FlynnHub/Ansible-EPSI/pull/new/Complete_Inventory
remote: 
To github.com:FlynnHub/Ansible-EPSI.git
 * [new branch]      Complete_Inventory -> Complete_Inventory
La branche 'Complete_Inventory' est paramétrée pour suivre la branche distante 'Complete_Inventory' depuis 'origin'.

Maintenant que nous retournions sur notre branch main que ce soit sur notre repo local (La machine de développement) ou sur notre repository distant (Github). Nous voyons seulement les modifications précédemment effectué seulement sur la branch Complete_Inventory

Gérer son inventaire Ansible

L’inventaire Ansible à la base est composé d’un seul fichier « Hosts ». Il référence la liste des hôtes et des groupes de serveurs ou équipements réseaux qui peut-être géré par Ansible. En terme de bonnes pratiques, pour une plateforme qui va entre 1 à 200-300 servers, on le compose d’un dossier inventory qui contiendra notre fichier hosts, puis deux dossiers, un qui sera utilisé pour les variables par servers, et un qui sera utilisé pour les variables par groupe de servers. Exemple :

Génération d’un inventaire deux environnements qui sont ISO, un environnement pour la préproduction ainsi qu’un environnement pour la production. Les deux environnements contiennent chacun :

  • 1 Haproxy
  • 2 Apaches
  • 1 MySQL
~/ansible/Ansible-EPSI/inventory/hosts
#################### PREPRODUCTION ####################

[PPROD:children]
PPROD_HAPROXY
PPROD_APACHE
PPROD_MYSQL

#################### PRODUCTION #######################

[PROD:children]
PROD_HAPROXY
PROD_APACHE
PROD_MYSQL

#################### HOSTS ############################

[PPROD_HAPROXY]
192.168.0.10

[PPROD_APACHE]
192.168.0.12
192.168.0.13

[PPROD_MYSQL]
192.168.0.17

[PROD_HAPROXY]
192.168.0.20

[PROD_APACHE]
192.168.0.22
192.168.0.23

[PROD_MYSQL]
192.168.0.27

Une fois que le fichier hosts est créé, il faut passer maintenant à la création des host_vars et des group_vars. Nous allons au moins créer un dossier dans les group_vars par groupe dans fichier hosts, voici un exemple :

Les commandes ad-hoc

Les commandes ad-hoc sont la première utilisation d’Ansible. Ansible fonctionne avec des modules avec lequel nous allons faire appel. Pour tester le bon fonctionnement de la connexion on va utiliser le module ping. Dans cette commande on appelle :

  • ansible : Est le nom de notre logiciel auquel nous faisons appel
  • apache1 : Ce deuxième paramètre spécifie les hôtes, ou le groupe d’hôte distant, apache1
  • -i inventory/ : Permet de spécifier ou se trouve notre inventaire, inventory
  • -u root : Permet de spécifier avec quel utilisateur se connecter sur l’hôte distant, root
  • -m ping : Permet de spécifier le nom du module à exécuter, ping
ansible apache1 -i inventory/ -u root -m ping
Bash user command
Output
apache1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

Ici on effectue la même commande mais avec le paramètre de spécification des hôtes avec « PROD_APACHE ». Il va donc essayer de ping les deux machines, sur cet exemple le second hôte du groupe est down, il n’arrive donc pas à la ping et nous affiche un « UNREACHABLE ».

ansible PPROD_APACHE -i inventory/ -u root -m ping
Bash user command
Output
apache1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
apache2 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: ssh: connect to host apache2 port 22: Connection timed out",
    "unreachable": true
}

Les commandes ad-hocs sont souvent utilisées pour effectuer une seule tâche sur plusieurs serveurs comme leur mise à jour, par exemple :

ansible PPROD_APACHE -i inventory/ -u root -m shell -a "apt-get update && apt-get upgrade -y"
ShellScript
Output
apache2 | CHANGED | rc=0 >>
Atteint :1 http://security.debian.org/debian-security bullseye-security InRelease
Atteint :2 http://http.us.debian.org/debian bullseye InRelease
Atteint :3 http://http.us.debian.org/debian bullseye-updates InRelease
Lecture des listes de paquets…
Lecture des listes de paquets…
Construction de l'arbre des dépendances…
Lecture des informations d'état…
Calcul de la mise à jour…
Les paquets suivants ont été conservés :
  linux-image-amd64
0 mis à jour, 0 nouvellement installés, 0 à enlever et 1 non mis à jour.
apache1 | CHANGED | rc=0 >>
Atteint :1 http://security.debian.org/debian-security bullseye-security InRelease
Atteint :2 http://http.us.debian.org/debian bullseye InRelease
Atteint :3 http://http.us.debian.org/debian bullseye-updates InRelease
Lecture des listes de paquets…
Lecture des listes de paquets…
Construction de l'arbre des dépendances…
Lecture des informations d'état…
Calcul de la mise à jour…
Les paquets suivants ont été conservés :
  linux-image-amd64
0 mis à jour, 0 nouvellement installés, 0 à enlever et 1 non mis à jour.

Ansible possède également une fonctionnalité de gathers_facts qui sont des variables magiques. C’est une étape qui peut-être facultative qui permet de collecter des informations sur l’hôte distant avant d’effectuer des tâches. Elles incluent des informations détaillés comme le système d’exploitation, sa version, la mémoire disponible etc.

ansible apache1 -i inventory/ -u root -m setup
Bash user command
Output
apache1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.0.12"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:feff:213"
        ],
        "ansible_apparmor": {
            "status": "enabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "11/12/2020",
        "ansible_bios_vendor": "Phoenix Technologies LTD",
        "ansible_bios_version": "6.00",
        "ansible_board_asset_tag": "NA",
        "ansible_board_name": "440BX Desktop Reference Platform",
        "ansible_board_serial": "None",
        "ansible_board_vendor": "Intel Corporation",
        "ansible_board_version": "None",
        "ansible_chassis_asset_tag": "No Asset Tag",
        "ansible_chassis_serial": "None",
        "ansible_chassis_vendor": "No Enclosure",
        "ansible_chassis_version": "N/A",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-5.10.0-20-amd64",
            "quiet": true,
            "ro": true,
            "root": "UUID=3faf6c6b-7a9b-44c7-925b-728a8cd81ad4"
        },