---
# System prepended metadata

title: Formation Ansible

---

# Formation Ansible

## Le formateur
 - Guillaume Rémy / Ingénieur / Docteur

## Tour de table
2 intégrateurs, 3 architectes, 1 Dev, 4 Exploit, 1 data

## Introduction

### What is DevOps ?
DevOps = Un peu de tehnique et beaucoup d'organisation.
Faire tomber le mur de la confusion entre les Devs et les Ops.

#### Organisation orienté "Marché"
Dans une orga silotée classique, personne n'a la vision globale de ce qui se passe entre le build et le run.

Dans une Org orientée Marché, tout le monde est utilisateur d'une même plateforme. Les Ops font fonctionner la plateforme et les Devs l'utilisent

@NPernoud : A la métro on est en transition. Tout un pan du SI est dans l'ancien monde.
PAs toujours possible avec les éditeurs qui ne proposent pas forcément des apps conteneurisées.    
#### Les métriques
LEs métriques sont importantes pour savoir où l'on en est dans la transformation.

Le TTM : moment entre le temps où la fonction est développée et lorsqu'elle est mise en prod. On cherche à réduire le TTM au max.

Le MTTR : Temps de rétablissement du service après crash.

**Les 3 principes du DevOps** :

- Opitmisation du flux entre la partie dev et la partie prod
- Les boucles de retours (vision en temps réel des problèmes éventuels des développements)
- Culture de l'expérimentation et de l'apprentissage continu (try & learn)

ex : le CosMonkey
Créer le chaos de manière aléatoire dans l'infrastructure pour pour voir comment elle se comporte. => évaluer la résilience de l'infrastructure et des applications.

#### Mise en place
- Accéler leur déploeiments grâce à des pipelines de CI
- Qualité du code (SonarQube par ex)
- Mettre en place de la métrologie (monitoring du bon fonctionnement de l'app et automatiser les corrections) => La fameuse boucle de retour.
- Créer des environnements à la demande.

#### L'exemple Etsy

- Les collabos restaient tard le soir
- déploiements compliqués ~4h (2 fois par semaine)
- mise à l'échelle compliquée avec le développement de l'entreprise

En se basant sur l'exemple de *Flickr*, ils sont passés au DevOps ce qui leur a permis de déployer 50 fois par jours avec un MTTR passé de quelques heures à 4 minutes.

### Les 5 piliers du DevOps (CALMS)

1. **C**ulture
    1. Est-ce que toute l'équipe produit est intégrée dans la résolution d'un problème ?
    2. Vision commune partagée
    3. Résoudre les problèmes collectivement plutôt que de déterminer qui est le responsable (Post-Mortem). Ne pas pointer du doigt la personne pour conserver la culture de l'expérimentation.
2. **A**utomatisation
    1. Déployer fréquemment
    2. Blue/Green deployment : déploiement sur un des 2 env de prod (le green) et si OK, on généralise.
    3. Les tests qui doivent être automatisés, couvrir la plus grande partie du code, être variés.

> Automatised GUI : Selenuim pour créer des scripts front qui réalisent des recettes => Est-ce que nos CPI connaissent cet outil pour leur recette ? 

> (Il y a un XP côté SI Sol pour Iodas)

> Les tests Sélenium restent très lourds à paramétrer et a maintenir. :+1: 

3. **L**ean
    - Méthodo issue de Toyota : éliminer les gaspillages tout au long de la chaine de production. On peut applique cette méthodo à une chaine de production de code.
    - Parler au dirigeant (voir sa vision des process dans son entreprise)
    - observez les process et collecter le données rééelles
    - créer la *values tree map* pour optimiser les processes
    Requêtes > Approbation > devs >
4. **M**esure
    - Mise en place de KPI (Key Performance Indicators): qu'elle soit technique (TTM, ...) que fonctionelle (combien d'utilisateur se sont inscrit, ont cliqué sur le bouton "X")
5. **S**hare
    - La personne qui construit l'app s'occupe de la faire tourner et de la maintenir en conditions opérationnelles.
    

> "You Build It You Run It"


### Quelques pièges à éviter

- Ne pas appliquer du DevOps sur une app monolythique.
    Donc ne pas le faire sur la applications Editeurs non architecturées pour le devOps.
- Connaitre et appliquer la méthodologie agile avant de se tourner vers le devOps.
> 
- Prévoir du temps pour l'automatisation et l'amélioration continue !
    Sans amélioration continue c'est pas agile et obsolescence à prévoir, voir dégradation en désactivant certaines fonctionnalités (tests...)
- laisser de côté l'aspect culturel du DevOps
    La culture de l'apprentissage continu et de l'expérimentation doit rester au coeur du DevOps
- Oublier la culture des 2 pizzas ??
    Une équipe projet ne doit pas dépasser 8 à 10 personnes (il faut une part de pizza pour chacun) > Donc des petites équipes.

## Orchestration de CI/CD et Ansible
### What is CI ??
Intégration continue : c'est le build de l'application avec la création d'un artifact mis a disposition pour l'étape d'après, le CD.

Fusion des changements avec la branche principale le plus souvent possible. A chaque fusion les tests sont lancés et un rapport est généré.

### What is CD ?
Déploiement d'un artefact (créé par la CI) sur son(ses) environnements.

- Livraison continue: déploiement sur l'env de staging mais pas en prod (des utilisateurs vont faire la recette manuellement) avant déploiement en prod (automatisé). Utile dans un premier temps pour bien mettre en place les pipelines, tests...
- Le déploiement continu automatique toutes les étapes jusqu'au déploiement en production.

Le DevOps est une boucle infinie entre CI(dev) et CD(ops)

![](https://i.imgur.com/JtIbg7y.png)

### Gestion des sources
**Git** évidemment.

![](https://i.imgur.com/ySQmmtr.png)

#### Organisation des devs autour de git : 
Git flow
- A chaque nouvelle feature, on crée une branch
- On merge d'abord sur develop sauf pour les hotfix
- Les hotfix peuvent être créer depuis master puis mergées sur develop/master
- seule develop ou release peuvent être mergées sur master quand le travail est terminé.

![](https://i.imgur.com/LbZJ0cv.png)

> NdBenoit : Gitflow un peu lourd, voir p-e Gitlab Flow : :+1: 
> https://docs.gitlab.com/ee/topics/gitlab_flow.html

#### GitOps:
Git est le seul référentiel où tout est centralisé (code, doc, scripts de déploiement)

Les fondamentaux :
- Convergence: les scripts garantissent la cohérence entre desc et état
- L'idempotence : garanti que la répétition d'une opération se passe toujours de la même façon.
- L'automatisation 

## Virtualisation et gestion des configs

### La virtualisation
Objectif: dynamiser l'allocation des ressources informatiques (ex rush de Noël pour les site de e-commerces)

4 techniques de virtulisations: 
- Par isolateur (conteneur)
- Noyau en espace utilisateur: chaque utilisateur a son propre noyau système => lourd en RAM et espace dique + problème de sécu
- Hyperviseur de type 2 (VirtualBox): permet n'importe que OS dans n'importe quel OS, vrai cloisonnement sécu, perf très limitée
- Hyperviseur de type 1 (KVM, VSpere) système de virtulisation dédié à la place de l'OS hôte (hyperviseur) pour de la virtualisation lourde à grande échelle.

La virt. matérielle permet de l'optimisation par les VM avec l'utilisation des instrutions spécifiques matérielles

### Infra as a Code

#### Configuration management
L'état des serveur est géré par des configurations: on définit l'état attendu et le système se charge d'atteindre cet objectif plutôt que définir les instructions a exécuter manuellement pour arriver à l'état.

Tout est automatiser grâce à la CI/CD.

**Style déclaratif vs style procédural** => avantage du déclaratif

**Puppet vs Ansible vs Chef** : Ansible très simple à mettre en place, Puppet si on a de nombreuses machines existantes est ^plus facile à mettre en place. Principe maitre/agent de Puppet qui peut être un avantage ou inconvénient selon le contexte.

#### Terraform
Fournit l'infra qui permet ensuite d'y déployer les configs vu précédement.

=> De plus en plus les deux essaient de rendre les services de l'autre, terraform déploie de la conf et Ansible peut déployer de l'infra. Dans des cas simple on peut utiliser un seul des deux outils (déploiement de noeuds dans un cluster Kubernetes qui a très peu d'instructions donc peut être déployé avec Terraform)

#### Ansible
(Slide 69)
Chaque tâche utilise un et un seul *module*
Les *transports* permettent de définir comment se connecter à une machine
Les *plugins* permettent d'étendre les fonctionnalités (rapports de déploiement par mail)
Les playbook sont des jeux d'instructions qui peuvent comporter plusieurs *plays* (scénario de déploiement)
Un *rôle* est une unité partageable avec la communauté (par exemple déploiement d'un apache avec sa conf)
*L'inventaire* est l'ensemble des machines que l'on souhaite configurer dans un env Ansible

## Déployer médiawiki avec Ansible (projet fil rouge)
```bash
# Init env
apt-get install python3-venv
python3 -m venv ansible
source ansible/bin/activate
pip install --upgrade pip && pip3 install ansible

# Créer l'utilisateur ansible-user sur les machines et déployer clé RSA
#PASS=$(ansible localhost -i hosts -m debug -a "msg={{ 'passforce' | password_hash('sha512','secretsalt') }}")
PASS='$6$secretsalt$X5YDmUgDphPxnMkByvHbNaiP4T5Uk0WjEZ9TukWKQnXmXN81jG3DcGZnNJiSz9ltgPhplH92HOR/RqgmyS.zN1'
ansible -i hosts -m user -a "name=ansible-user password=${PASS}" --user root all
ansible -i hosts -m user -a 'name=ansible-user groups=sudo append=yes' --user root all
# Pour ces 2 étapes : mettre le mot de passe "passforce" défini à la ligne 3
ansible -i hosts -m user -a 'name=ansible-user groups=sudo append=yes' --user ansible-user --become --ask-become-pass --ask-pass all
ansible -i hosts -m authorized_key -a 'user=ansible-user state=present key="{{ lookup("file", "/home/user/.ssh/id_rsa.pub") }}" ' --user ansible-user --ask-pass all
# Pur cette étape : mettre le mot de passe "passforce" défini à la ligne 3 (le mot de passe become est le même)
ansible -i hosts -m lineinfile -a 'path=/etc/sudoers line="%sudo ALL=(ALL) NOPASSWD: ALL" regexp=".*%sudo.*"' --user ansible-user --become --ask-become-pass all
# OU (plus propre car créé un fichier dans sudoers.d)
ansible -i hosts -m copy -a 'dest=/etc/sudoers.d/ansible-user content="%sudo ALL=(ALL) NOPASSWD: ALL"' --user ansible-user --become --ask-become-pass all

```

## Quelques Modules Ansible
- raw : permet d'executer une ligne de commande sur les hosts du fichier hosts.

- debug : module qui affiche quelque chose en sortie

- user : Module de gestion des utilisateurs (CRUD)
- lineFile : Gérer une ligne dans un fichier de conf.

## Les Rôles Ansible
Un role détermine les tâches à exécuter mais il ne décrit pas où les exécuter. 
> C'est aussi une bonne pratique d'isoler les tâches des cibles.
> 
Structure d'un role Ansible : 

role
|_ meta        Description du rôle
|_ tasks       Tâches à réaliser
|_ templates   Templates j2
|_ files       Fichiers à déployer tels quels
|_ defaults    Variables
|_ handlers    Triggers pour idempotence
|_ tests        
|_ vars        

## Le playbook Ansible 
Un playbook est un fichier de configuration YAML
contenant une suite de jeux d’instructions. Chacun peut
être constitué d’options, et fait appel à un ou plusieurs
rôles. Il permet de décrire une stratégie de déploiement,
ou de configuration, en structurant les actions nécessaires.

## Sécurité Ansible
l'outil `ansible-vault` permet de chiffrer les données sensibles comme les mots de passe.
> Attention : pour ne pas afficher de mot de passe dans les logs d'Ansible une fois qu'ils sont déchffrés par vault, il faut préciser l'option `no_log: true` dans les playbooks.

L'option `--ask-vault-pass` permet de demnader le mdp au moment de l'execution. On ne peut pas demander plusieurs mdp avec cette option, il faut pour cela identifier les mdp lors du chiffrage avec l'option `--vault-id=Dev`
> la bonne pratique est de définir le vaul-id avec l'environnement : `--vault-id=dev@prompt`

>Cette option n'est pas compatible avec `--ask-vault-pass`

`ansible-vault` permet aussi de chiffrer des fichiers entiers
`ansible vault edit` pour modifier un fichier chiffré
`ansible vault view` pour consulter un fichier chiffré (afficher dans la console uniquement, pas déchiffré sur le disque)

## Ansible facts
Donne toutes les infos de la machine host au format JSON. Permet nottament de récupérer la famille d'OS et le gestionnaire de paquets [doc](https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html)

Interrogation du dictionnaire ansible_facts : 
```json=
...
},
    "ansible_distribution": "CentOS",
    "ansible_distribution_file_parsed": true,
    "ansible_distribution_file_path": "/etc/redhat-release",
    "ansible_distribution_file_variety": "RedHat",
    "ansible_distribution_major_version": "7",
    "ansible_distribution_release": "Core",
    "ansible_distribution_version": "7.5.1804",
    "ansible_dns": { ...
```
La propriété `ansible_distribution` du JSON s'adresse comme suit  dans le dictionnaire  Ansible : `ansible_facts['distribution']`


### TP CentOS
L'objectif est de rendre compatible notre playbook avec d'autres versions d'OS. L'installation de php7 est différente. Il y a plusieurs solutions pour faire cela.
1. Faire du templating j2 directement dans les noms de packages du fichier `php7-install.yml`, en utilisant le dictionnaire ansible_facts.

2. Créer des fichiers de variables liés à la version d'OS et les appeler dans le fichier `php7-install.yml`.

Renommer `php7-install.yml` en `php7-install.Debian.yml` et  modifier le fichier `roles/apache/main.yaml` avec le contenu suivant :
```yaml
---
# tasks file for apache
- name: "apache installation"
  package:
    name: "apache2"
    state: "present"
- name: "apache service activation"
  service:
    name: "apache2"
    state: "started"
    enabled: yes
- name: "install php7 packages for debian"
  include: "php7-install.{{ ansible_facts['distribution'] }}.yml"
  when: php_install|default(False)|bool
```

Créer le fichier `php7-install.CentOS.yml` avec le contenu suivant
```yaml
---
- name: "epel activation"
  yum:
    name: "epel-release"
    state: present
 
- name: Import remi GPG key.
  rpm_key:
    key: http://rpms.remirepo.net/RPM-GPG-KEY-remi
    state: present
 
- name: Import remi GPG key 2018.
  rpm_key:
    key: http://rpms.remirepo.net/RPM-GPG-KEY-remi2018
    state: present
 
- name: "remi repo activation"
  yum:
    name: "https://rpms.remirepo.net/enterprise/remi-release-{{ansible_facts['distribution_major_version']}}.rpm"
    state: present
 
- name: "install php70 packages"
  include_vars: centos{{ansible_facts['distribution_major_version']}}.yml
  yum:
    name: "{{php_packages}}"
    state: latest
    enablerepo: "remi-php70"
  notify: [ "apache restart" ]
```

Créer le répertoire `roles/apache/vars` et les fichiers:

"centos7.yml" : 
```yaml
php_packages:
  - php
  - php-mysql
  - php-xml
  - php-mbstring
  - php-mcrypt"
  - php-gd
  - php-intl
```

"centos8.yml"
```yaml
php_packages:
  - php
  - php-mysqlnd
  - php-xml
  - php-mbstring
  - php70-php-mcrypt"
  - php-gd
  - php-intl
  - php-json
```

* Modifié l'utilisateur et le groupe selon la distribution

L’utilisateur web (web_user) pour CentOS est apache. Le groupe web (web_group) pour CentOS est apache
```yaml=
web_user: "{{ 'www-data' if ansible_facts['distribution']=='Debian' else 'apache' }}"


```

Attention : il faut que l'environnement soit chargé, par exemple dans le fichier media-wiki-install.yml 

```yaml=
- name: "MediaWiki apache configuration"
  hosts: apache
  #gather_facts: no
  tags: "apache"
  roles:
   - role: "mediawiki/confapache"
```

## Modules Ansible



## Ansible Galaxy

Il est possible d'aller chercher des roles déjà développés par la communauté Ansible ave la commande `ansible-galaxy search`.
La meilleure pratique est de mettre tous les roles nécessaires a notre playbook dans un fichier de *pré-requis* à la racine de notre projet Ansible.

`ansible-galaxy install -r requirements.yml`

## Notion avancée Ansible

## Ressources
[pdf de la formation](https://drive.google.com/file/d/1Jtga7qwKswvcGpP0RlhECu92clMulMex/view)
