2. BONJOUR À TOUS !
Info trafic : le présentateur ne fait pas grève aujourd’hui.
3. Noël Bardelot
Architecte DevOps / Java
12 ans d’informatique,
d’amélioration continue,
d’automatisation des processus
45 minutes pour vous parler d’Ansible
puis répondre à vos questions
5. dépôts de paramètres (CMDB)
${clé} : valeur
Processus
de livraison
dépôts de composants
automatisation
orchestration
API de déploiement continu
infrastructure & architecture scalables
6. Concepts clés du paradigme Ansible
Group : le groupe est l’unité de rangement logique des paramètres
– Sans classification a priori
– Un exemple de classification qu’on peut choisir :
• Infrastructure : rhel7, datacenter-irlande, 8cpu
• Middleware : tomcat85, jdk8
• Applications : appli_compta, batchs_compta
Host : les hôtes sont des machines virtuelles ou physiques adressables
– Ansible calcule les variables (vars) à appliquer à l’hôte pour en faire des
paramètres de l’exécution du code
Inventory : l’inventaire organise les hôtes et les groupes
– Arborescence : les nœuds sont des groupes, les feuilles sont des hôtes
– Un groupe peut donc contenir d’autres groupes (notion de children) ou des
hôtes (hosts)
– Ansible ne force pas à assimiler inventaire et environnement, mais c’est une
organisation possible
7. [jdk8:children]
tomcat85
batchs_compta
[tomcat85:children]
webapp
[webapp]
hostname1
hostname2
[batch_compta]
hostname1
hosts
Chaque inventaire statique
est conçu autour
d’un fichier hosts au format
INI qui fait le lien entre les
hôtes et les groupes, et les
groupes entre eux :
SSHD_LOG_LEVEL: "INFO"
host_vars/hostname1.yml
HTTP_PORT: 8080
HTTPS_PORT: 8443
JVM_HEAP_SIZE: "1024M"
LANG: "en_US"
group_vars/tomcat85.yml
SSHD_LOG_LEVEL: "ERROR"
LANG: "fr_FR"
group_vars/all.yml
Le groupe all
est le standard pour
gérer des paramètres
globaux pour
l’inventaire
Les groupes forment
le gros du rangement
logique des
paramètres.
Il est rare de
spécialiser des
paramètres par hôte
mais c’est possible.
9. {
"all": {
"hosts": ["hostname1", "hostname2"],
"vars": {
"SSHD_LOG_LEVEL": "ERROR"
"LANG": "fr_FR"
}
},
"_meta": {
"hostvars": {
"hostname1": {
"SSHD_LOG_LEVEL": "INFO"
}
"hostname2": {}
}
},
"jdk8": {
"children": ["tomcat85", "batchs_compta"],
"vars": {}
},
"tomcat85": {
"children": ["webapp"],
"vars": {
"HTTP_PORT": 8080,
"HTTPS_PORT": 8443,
"JVM_HEAP_SIZE": "1024M",
"LANG": "en_US"
}
},
"webapp": {
"hosts": ["hostname1", "hostname2"],
"vars": {}
},
"batch_compta": {
"hosts": ["hostname1"],
"vars": {}
}
}
Quelles contraintes ce format
impose-t-il pour un modèle de CMDB
?
1. La notion d’hôte est au cœur de la
structure, c’est sur elle que
s’appuie Ansible pour finaliser le
mécanisme de précédence des
paramètres.
2. L’organisation logique tourne
entièrement autour de la notion
de groupe et de groupe de
groupes, mais sans imposer ce
qu’ils représentent.
3. Ansible encourage à fournir
toutes les données en une seule
passe (cf. section _meta) plutôt
qu’à requêter la CMDB une fois
pour les groupes, puis
unitairement pour chaque hôte.
C’est un critère pour obtenir de
bonnes performances.
10. Choix de l’organisation logique
• Reprenons l’exemple initial :
• Infrastructure : rhel7, datacenter-irlande, machine_8cpu
• Middleware : tomcat85, jdk8
• Applications : appli_compta, batchs_compta
• Avantages/Contraintes de cette organisation :
– On peut séparer des responsabilités par typologie de
groupes
– La notion de version d’application n’a pas besoin
d’être présente dans l’inventaire ; charge à la CMDB
de calculer l’inventaire dynamique
11. Concepts clés du paradigme Ansible
Task : la tâche est l’unité de code dans Ansible
Role : un rôle permet de ranger plusieurs tâches sous forme d’une procédure
– Exemple : un rôle « installer_tomcat85 » qui permet d’installer un Tomcat 8.5
Playbook : un manuel est le point d’entrée pour exécuter du code
– C’est lui qui fait l’association entre un ou plusieurs hôtes ou groupes et des
tâches ou des rôles à exécuter
– Par exemple le playbook « installer_tomcat85.yml » peut jouer le rôle
« installer_tomcat85 » sur le groupe « tomcat85 » qui liste les hôtes qui ont
besoin de ce middleware
Files/Templates: fichiers et modèles de fichiers prêts à l’emploi dans les rôles
– Les fichiers peuvent être copiés en l’état
– Les modèles sont variabilisés à l’aide du moteur Jinja2 (fichiers .j2)
12. « La folie, c’est de faire toujours la même chose
et de s’attendre à un résultat différent. »
Albert Einstein
idempotence
13. Où ranger les fichiers et modèles ?
• Les bonnes pratiques Ansible
– Chaque rôle possède un répertoire
– On met les fichiers dans le sous-répertoire files
– On met les modèles dans le sous-répertoire
templates
• Le cycle de vie de ces données est le plus
souvent corrélé à celui du code Ansible
• Il est donc naturel de ranger les fichiers et les
modèles de configuration avec le code Ansible
14. Les données confidentielles
• Liste non-exhaustive des données candidates :
– Les mots de passe
– Les certificats (PKI/X.509, …)
– Les clés de chiffrement (SSH, …)
– Les tokens d’API
• Ces données doivent être stockées uniquement
chiffrées
• L’accès à la CMDB ne doit pas être équivalent à
l’accès à ces informations, et il faut assurer le
principe de moindre privilège
15. Ansible Vault
• Ansible propose deux solutions de sécurité
• encrypt et la notion de vault :
– N’importe quel fichier d’inventaire statique peut être chiffré par
un mot de passe
– Le fichier devient un coffre-fort de données confidentielles,
qu’on peut stocker de manière sûre dans la CMDB ou ailleurs
– Il vient compléter l’inventaire dynamique à l’exécution
• encrypt_string, le chiffrement des paramètres :
– On peut chiffrer un paramètre et le stocker chiffré dans la CMDB
• Dans les deux cas on déchiffre les secrets à l’exécution
Nota : ces fonctionnalités dépendent de la version d’Ansible. Ansible 2.4 (25/10/2017)
introduit des améliorations sur la gestion des mot de passe pour le chiffrement.
16. Solutions du marché
Nom (Editeur)
Licence
Avantages Inconvénients
Ansible Tower
(RedHat)
versions communautaires
et payantes
• IHM
• Editeur d’inventaires
• Gestion des habilitations
(LDAP)
• API REST
• Orchestrateur (remplace
Jenkins pour cet usage)
• Audit
• Ansible nativement
• Rigide
• Payant pour l’usage
souhaité (LDAP, audit, …)
• Plus qu’une simple
CMDB de paramètres
Rudder
(rendu OpenSource par
Normation)
GPLv3
• IHM
• Inventaires par
catégories
• Gestion des habilitations
(LDAP)
• API REST
• Intégration avec Ansible
• Plus qu’une simple
CMDB de paramètres
17. Bases de données ad-hoc
Type
Exemple
Avantages Inconvénients
LDAP
Active Directory
• Structure arborescente
• Orienté « organisation »
• Quid de la gestion d’un
historique des valeurs
de paramètres ?
SQL
PostgreSQL
• Schéma ad-hoc
• Contraintes d’intégrité
• Gestion de l’historique
simple à implémenter
• Mapping objets-
relationnel
Clé-Valeur
Redis
• Performances
• Simplicité
• Les clés qu’on souhaite
sont « complexes »
(beaucoup de critères)
Graphe
Neo4j ou OrientDB
• Adapté à une structure
arborescente
• Gestion de l’historique
simple à implémenter
• Bonne traversée du
graphe ?
19. Où, quand, comment ?
• Au sein de s2e
– métier bancaire de l’épargne salariale (pensez « PEE »)
– au sein de l’équipe d’architecture d’Alexis Haumont
• La migration de version du progiciel au cœur du SI
– il faut mettre en place Siebel version 8, le CRM d’Oracle
– il faut adapter de nombreux services satellites en Java
• Novembre 2016 – Février 2018
– à mon arrivée les développements ont déjà commencé
chez CGI
– fin 2016 l’entreprise vient de redonner sa confiance à
Thalès pour gérer son infrastructure
20. 1 an pour…
• Changer l’infrastructure
– Solaris laisse la place à RedHat Enterprise Linux
• Changer l’architecture
– il faut découper le serveur « monolithe »
• Automatiser les processus
– d’installation des environnements
– de patch management
– de déploiement applicatif
25. Environnements
hors développement et intégration
• 2 environnements sur le Cloud
– Recette interne et UAT
– pas de redondance
– chaque environnement nécessite 8 serveurs
• 2 environnements infogérés
– Préproduction et Production
– chaque architecture est redondé sur 2 datacenters
– chaque environnement nécessite 16 serveurs
• 48 serveurs à orchestrer
27. Bonnes pratiques Ansible
• Voir la documentation Ansible nommée « Best
practices » qui est un bon point de départ
• L’objectif est d’éviter la duplication de code
• Il faut utiliser un mécanisme pour modulariser :
– l’héritage entre rôles : c’est la préconisation Ansible,
mais il y a beaucoup de bugs liés à ces mécanismes
– Galaxy : à mettre en place très tôt dans un projet,
plutôt mis en avant comme online par Ansible…
– ou manuellement : c’est la voie que nous avons
privilégiée avec hash_behaviour = merge
28. Comment utilise-t-on Ansible ?
• Nous utilisons la version 2.3 (on y reviendra)
• En ligne de commande, avec des scripts shell
utilitaires ad-hoc :
– un script pour télécharger depuis le Nexus une
version stable des playbooks et des inventaires
– un script pour assister à l’exécution des playbooks
• L’ensemble des inventaires et des playbooks
est versionné dans SVN dans un projet piloté
avec Maven
29. Les problèmes de précédences
• Ansible souffre de problèmes de précédence pour le
rangement des group_vars entre inventaires et
playbooks… (cf. le ticket 17703 à ce sujet)
• Par conséquent, on ne peut pas avoir en même temps :
– des group_vars dans les playbooks qui contiennent les
données indépendantes de l’environnement
– et des group_vars dans les inventaires, pour les données
spécifiques
• Nous avons opté pour une solution de contournement
en créant des fichier env_vars.yml dans nos inventaires
que nous incluons « à la main »
30. Les inventaires
• Nous créons un inventaire par environnement
• Nous séparons également les données
confidentielles dans des fichiers à part, qui ne
sont pas versionnés dans SVN ou publié dans
Nexus
• Nous n’utilisons pas Vault mais l’ajout de ces
données confidentielles se fait au dernier
moment par les opérateurs habilités sur le
serveur d’orchestration
31. inventories/hom1/env_vars.yml
playbooks/group_vars/tomcat.yml
tomcat_instances:
instance_WSIntranet:
HEAP_SIZE: "1024m“
…
tomcat_instances:
instance_WSIntranet:
JAVA_HOME: "{{ jdk.HOME }}"
HTTP_PORT: 8080
JAVA_OPTS: >
-Xms${HEAP_SIZE}
-Xmx${HEAP_SIZE}
Fusion de dictionnaires
roles/tomcat/templates/setenv.sh.j2
#!/bin/bash
# {{ ansible_managed }}
HEAP_SIZE="{{ item.HEAP_SIZE }}“
JAVA_OPTS="{{ item.JAVA_OPTS }}"
export HEAP_SIZE
export JAVA_OPTS
…
Si les dictionnaires portent le même nom
sans autres dictionnaires imbriqués
alors l’option hash_behaviour = merge dans
ansible.cfg fait qu’Ansible réalise la fusion.
Sinon, il faut réaliser la fusion manuellement :
set_fact: d="{{ d1 | combine(d2, recursive=True) }}"
33. Quand tout se passe bien
• Hors base de données, dans le Cloud nous
installons un environnement en 24h
• Nous faisons les mises à jour du système et
des middlewares en 2h
• La livraison d’une nouvelle version applicative
prend 30 minutes en plus d’une préparation la
veille
34. Nombre de fichiers
• Inventaires : 177 fichiers
• Playbooks : 873 fichiers
– dont 532 dans roles
– 60 dans group_vars
– et 265 playbooks
• Auxquels il faut ajouter la documentation
35. Nombre de lignes de code
• Plus de 70K lignes au total
– 10 832 dans les inventaires
– 60 494 dans les playbooks
• 33K lignes dans des fichiers YAML
– parmi 689 fichiers
– soit une moyenne de 48 lignes par fichier
• 11K lignes de modèles Jinja2
– parmi 188 fichiers
– soit une moyenne de 57 lignes par fichier
36. Taille des fichiers YAML
0
20
40
60
80
100
120
140
160
0-9 10-19 20-29 30-39 40-49 50-99 100-999 1000+
nb. fichiers
tailles de fichiers en nombre de lignes
37. Dépôt de sources
• 2985 commits à ce jour sur le dépôt complet
– Premier commit le 1er février 2017
• 109 versions
• 3 commiters principaux sur la branche
$ svn log -v --xml | grep '<author.*/author>' | sort $* | uniq -c | sort -rn
1264 <author>Noël Bardelot</author>
426 <author>Alexis Thaveau</author>
409 <author>Abderrahim Tajmouti</author>
8 <author>Alexis Haumont</author>
1 <author>Eric Thureau</author>
38. Pour en finir avec les nombres…
• il y a 4782 lignes de commentaires
– dont 36 occurrences de #FIXME
– et 8 occurrences de #TODO
• compressé le projet fait 2.12Mo de livrables
• l’IDE favori de l’équipe est IntelliJ IDEA
• 17 fichiers de documentation en markdown
40. Pourquoi pas Ansible Tower ?
• Il est très rigide
– il faut se plier à la façon Tower là où pourtant
Ansible est souple (inventaires, répertoires…)
– il faut l’utiliser dès le début du projet, sinon le
refactoring est trop coûteux
• Il n’est pas ergonomique
– en particulier les interfaces d’administration
• Il n’y a qu’une documentation limitée
– notamment pour les subtilités à l’installation
41. Pourquoi pas Ansible Vault ?
• Il faut un mot de passe partagé par les
opérateurs (mauvaise pratique)
• Nous avons été confrontés au manque de
temps pour tenir les délais du projet
• Ca reste la piste la plus prometteuse pour
stocker les secrets sur la machine
d’orchestration
42. Pourquoi pas Ansible Galaxy ?
La encore l’opportunité est arrivée trop tard, il y
avait trop de travail de refactoring pour tenir les
délais du projet.
43. Prototype d’usine conteneurisée
à l’aide de docker
Frontal HAProxy
Orchestrateur
Jenkins CI
Dépôts de sources
SCM-Manager (SVN)
Dépôt d’artefacts
Nexus
LDAP
OpenLDAP
45. Python
• La gestion des paquets vous fera perdre des
cheveux
– attention à ce que vous installez avec votre
gestionnaire de paquet système
– … vs. ce que vous installez avec PIP
• D’ailleurs, attention à la version de Python
• Le moteur de templating Jinja2 est puissant,
mais il a une forte courbe d’apprentissage
46. YAML
• Comme en Python, une mauvaise indentation
peut vous faire perdre de précieuses minutes
• Il y a de beaux pièges syntaxiques, notamment
avec les guillemets et les sauts de lignes
• Malgré un support du format dans IntelliJ il ne
faut pas s’attendre à des miracles en terme
d’interface de développement
47. Le « modèle » Ansible
• Ansible est orienté « machines », là où les
orchestrateurs récents sont orientés « instances
applicatives », et c’est le sens de l’histoire…
• La sémantique d’un groupe est confuse dans le
fichier hosts de l’inventaire
– réseau (groupe « datacenter-1 »)
– système (groupe « RHEL7 »)
– applicatif (groupe « webserver »)
• Les bonnes pratiques mettent en avant la
réutilisation du code par héritage de rôles (peu
fiable) plutôt qu’avec Galaxy en offline
48. Un projet avec des instabilités
• Chaque montée de version peut être un enfer
– pas de compatibilité ou de semantic versionning
– méfiez-vous-même des versions mineures
• La version 2.4 d’Ansible nous impose de
réécrire du code qui fonctionnait
– Cf. issue 30901 du projet Ansible sur GitHub
• Il y a plus de bugs créés que corrigés et même
s’il y a une communauté très active, vous
aurez souvent des rustines dans votre code
50. Oui !
• Ansible est clairement un excellent outil qui
permet d’automatiser des tâches récurrentes
– l’usage naturel de SSH en fait l’outil parfait pour des
environnements Linux
– le support de WinRM permet de l’utiliser sous
Windows et donc dans des environnements mixtes
• Contrairement à Puppet ou Chef, on maîtrise
« quand » le changement est opéré
• Le paradigme de l’idempotence est efficace, et
encourage une conception plus robuste
51. Mais…
• Si c’était à refaire je ne mettrais pas tout sous
forme de playbooks Ansible
• Avec du recule, il faut combiner les techniques
pour obtenir le meilleur de chaque outil :
– une partie du code peut aller dans des paquets RPM
(installation des middleware par ex.), eux-mêmes
pilotés par Ansible
– coder ses modules Python pour Ansible est une piste
qui peut remplacer des playbooks trop complexes
• Il faut que l’organisation s’y prête, notamment en
termes d’accès à l’infrastructure
52. Conclusion
Si vous avez un projet legacy, ou si vous n’êtes pas
prêt pour franchir le cap des conteneurs…
Si votre organisation a déjà une équipe DevOps, ou
d’intégrateurs avec des accès à l’infra…
Alors Ansible est fait pour vous.
Mais sinon, Kubernetes vous tend les bras, avec
une approche orientée architecture plus pertinente.