Dernière révision de la page : 02/03/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 commandGenerating 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 commandssh-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 commandLa 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 commandOn se rend dans le dossier précédemment cloné
cd Ansible-EPSI
Bash user commandPour 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 commandOn peut demander à Git les modifications qui sont apportés à notre dossier. Pour l’instant il n’y a eu aucune modification.
git status
ShellScriptSur 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 commandvim inventory/hosts
Bash user command[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 commandSur 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 commandgit status
Bash user commandSur 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[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É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.
git branch -a
* 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 commandgit branch -a
Bash user command* 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 commandOn regarde nos modifications
git status
Bash user commandSur 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 commandOn commit nos modifications
git commit -m "feat(inventory): Add Apache group and host_vars"
Bash user commandOn push nos modifications
git push
Bash user commandfatal: 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É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
#################### 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 :

Préparation de l’environnement pour les connexions SSH
Dans un premier temps, nous allons nous assurer que le package contenant SSH est bien installé. Il est possible que si vous avez un serveur avec une interface graphique, le package ne soit pas installé par défaut.
apt-get install openssh-server -y
Bash root commandNous allons passer le PermitRootLogin à yes. Cette manipulation va nous permettre de nous connecter directement en root sur la machine distante, cette authentification de base sur OpenSSH est généralement désactivée sur les distributions par défaut pour des raisons de sécurité. Une bonne pratique étant de créer un utilisateur technique sur la machine qui va être utilisé afin de pouvoir passer les commandes Ansible. La manipulation suivante que nous allons faire n’est pas recommandé mais va nous permettre de gagner du temps.
vim /etc/ssh/sshd_config
Bash root command#PermitRootLogin prohibit-password
Avant modificationPermitRootLogin yes
Après modificationNous allons ensuite redémarrer notre service SSH afin de prendre en compte les nouvelles modifications
systemctl restart ssh
Bash root commandNous allons ensuite importer notre clef SSH de notre serveur. Elle va permettre la connexion sans mot de passe depuis notre bastion qui fait office d’environnement de développement avec cette commande :
ssh-copy-id root@192.168.0.20
Bash user commandThe authenticity of host '192.168.0.20 (192.168.0.20)' can't be established.
ED25519 key fingerprint is SHA256:ppCKTa6I0XB2+KquawymTaRkYBj8RcOV78AvDLwG9uQ.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.0.20's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.0.20'"
and check to make sure that only the key(s) you wanted were added.
Afin de tester le bon échange des clefs, nous pouvons exécuter la commande suivante, elle est censé nous permettre de se connecter sur le serveur distant, avec l’utilisateur root et sans mot de passe
ssh root@192.168.0.20
Bash user commandAfin d’être un peu plus représentatif de ce que l’on pourrait avoir en entreprise, nous allons modifier notre fichier /etc/hosts. C’est un fichier de configuration qui permet de faire correspondre des noms d’hôtes à adresses IP sur un système d’exploitation. Elle permettra de simuler une entrée DNS pour nos noms de domaine.
127.0.0.1 localhost
127.0.1.1 zeorus-epsi
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.0.20 apache01
192.168.0.16 apache02
ShellScriptLes 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 commandapache1 | 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 commandapache1 | 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"
ShellScriptapache2 | 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 commandapache1 | 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"
},
Les playbooks
---
- name: Basic roles
Les roles
Nous allons procéder à l’installation de rôle existant, et pour cela nous allons les spécifier dans notre fichier requirements.yml
---
- name: python
src: git+https://github.com/OCG-EPSI/python.git
version: latest
- name: haproxy
src: git+https://github.com/OCG-EPSI/haproxy.git
version: latest
- name: apache
src: git+https://github.com/OCG-EPSI/apache2.git
version: latest
- name: mysql
src: git+https://github.com/OCG-EPSI/mysql_server.git
version: latest
JavaScriptUne fois notre fichier remplis avec les rôles dont lequel on a le besoin, on les prends en local sur notre poste afin de pouvoir s’en servir
ansible-galaxy install -r requirements.yml --force
Bash user commandPour notre plateforme, nous avons le besoin d’un rôle SFTP, mais malheureusement nous n’en possédons pas parmi les rôles communs à l’entreprise. On initialise donc un nouveau rôle que l’on va développer qui va servir à la fois pour notre plateforme et ainsi aux autres grâce à son fait générique.
ansible-galaxy init sftp
Nous pouvons appeler le rôle SFTP précédemment créé depuis notre playbooks afin de pouvoir l’instancier sur nos machines. Dans notre cas, nous allons l’appeler à partir d’un playbook qui s’appelle main.yml et qui va contenir nos rôles que l’on souhaite appeler :
---
- name: Basic roles
hosts: all
gather_facts: true
roles:
- { name: python, tags: python }
- { name: sftp, tags: sftp }
- { name: haproxy, tags: haproxy }
- { name: apache, tags: apache }
- { name: mysql, tags: mysql }
On fait donc appelle à notre rôle, en lançant notre playbook main.yml
ansible-playbook main.yml -u root -i inventory -l PROD_APACHE --tags sftp
Bash user commandChiffrement des données sensibles
Afin de pouvoir chiffrer nos données sensibles qui sont livrés avec Ansible, nous pouvons utiliser l’outil Ansible-vault. Il existe plusieurs façon de l’utiliser, nous allons en voir une ci-dessous. Notre rôle Ansible SFTP utilise des données sensible, comme les mots de passe SFTP. On peut télécharger une extension visual studio code “ansible-vault” qui vous permettra avec la combinaison de touche ctrl+alt+0 de pouvoir chiffrer et déchiffrer à la volée.

Il faut pour cela indiquer dans notre fichier ansible.cfg où se trouve notre fichier contenant notre secret :
[defaults]
host_key_checking = False
inventory = inventory
vault_password_file = $HOME/secrets/rte
Maintenant que nous avons paramétré notre fichier ansible.cfg, nous avons ce fichier contenant un utilisateur SFTP avec son mot de passe associé qui apparaissent en clair

On exécute notre combinaison de touches ctrl + alt + 0 et voici notre nouveau rendu :
