Introduction
En bref, la gestion de la configuration des serveurs (également appelée couramment automatisation IT) est une solution permettant de transformer l’administration de votre infrastructure en un ensemble de scripts de provisionnement pouvant être versionnés et réutilisés facilement. Cela peut grandement améliorer l’intégrité de n’importe quelle infrastructure serveur au fil du temps.
Dans un guide précédent, nous avons discuté des principaux avantages de la mise en œuvre d’une stratégie de gestion de la configuration pour votre infrastructure serveur, du fonctionnement des outils de gestion de la configuration et des éléments typiques de ces outils.
Cette partie de la série vous guidera à travers le processus d’automatisation du provisionnement des serveurs en utilisant Ansible, un outil de gestion de la configuration qui fournit un cadre d’automatisation complet et des capacités d’orchestration, tout en maintenant un objectif de simplicité ultime et de minimalisme. Nous nous concentrerons sur la terminologie, la syntaxe et les fonctionnalités nécessaires pour créer un exemple simplifié permettant de automatiser entièrement le déploiement d’un serveur web Ubuntu 18.04 à l’aide d’Apache.
La liste suivante contient toutes les étapes que nous devons automatiser afin d’atteindre notre objectif:
- Mettre à jour le cache
apt
- Installer Apache
- Créer un répertoire racine de document personnalisé
- Placez un fichier
index.html
dans le répertoire de document personnalisé - Appliquez un modèle pour configurer notre hôte virtuel personnalisé
- Redémarrez Apache
Nous commencerons par jeter un coup d’œil à la terminologie utilisée par Ansible, suivi d’une vue d’ensemble des principales fonctionnalités du langage pouvant être utilisées pour écrire des playbooks. À la fin du guide, vous trouverez le contenu d’un exemple complet de provisionnement pour automatiser les étapes décrites pour configurer Apache sur Ubuntu 18.04.
Note: ce guide vise à vous initier au langage Ansible et à la rédaction de playbooks pour automatiser la provision de votre serveur. Pour une vue plus introductive d’Ansible, incluant les étapes nécessaires à l’installation et à la prise en main de cet outil, ainsi que la manière d’exécuter des commandes et des playbooks Ansible, consultez notre guide Comment Installer et Configurer Ansible sur Ubuntu 18.04.
Commencer
Avant de passer à une vue plus pratique d’Ansible, il est important que nous nous familiarisions avec la terminologie et les concepts importants introduits par cet outil.
Terminologie
La liste suivante contient un aperçu rapide des termes les plus pertinents utilisés par Ansible :
- Nœud de Contrôle : la machine où Ansible est installé, responsable de l’exécution de la provision sur les serveurs que vous gérez.
- Inventaire : un fichier
INI
contenant des informations sur les serveurs que vous gérez. - Playbook : un fichier
YAML
contenant une série de procédures devant être automatisées. - Tâche : un bloc qui définit une seule procédure à exécuter, par exemple : installer un package.
- Module : un module abstrait généralement une tâche système, comme la gestion des packages ou la création et modification de fichiers. Ansible dispose d’une multitude de modules intégrés, mais vous pouvez également en créer des personnalisés.
- Rôle : un ensemble de playbooks, de modèles et d’autres fichiers connexes, organisés de manière prédéfinie pour faciliter la réutilisation et le partage.
- Play : une provision exécutée du début à la fin est appelée un play.
- Facts : des variables globales contenant des informations sur le système, telles que les interfaces réseau ou le système d’exploitation.
- Handlers : utilisés pour déclencher des changements d’état du service, comme le redémarrage ou le rechargement d’un service.
Format de Tâche
A task defines a single automated step that should be executed by Ansible. It typically involves the usage of a module or the execution of a raw command. This is how a task looks:
- name: This is a task
apt: name=vim state=latest
La partie name
est en fait facultative, mais recommandée, car elle apparaît dans la sortie de la provision lorsque la tâche est exécutée. La partie apt
est un module intégré à Ansible qui abstrait la gestion des paquets sur les distributions basées sur Debian. Cette tâche d’exemple indique à Ansible que le paquet vim
devrait avoir son état changé en latest
, ce qui entraînera l’installation de ce paquet si ce n’est pas déjà fait.
Format du Playbook
Les playbooks sont des fichiers YAML
contenant une série de directives pour automatiser la provision d’un serveur. L’exemple suivant est un playbook simple qui effectue deux tâches : met à jour le cache apt
et installe ensuite vim
:
---
- hosts: all
become: true
tasks:
- name: Update apt-cache
apt: update_cache=yes
- name: Install Vim
apt: name=vim state=latest
YAML
repose sur l’indentation pour sérialiser les structures de données. Pour cette raison, lors de l’écriture de playbooks et surtout lors de la copie d’exemples, vous devez être particulièrement attentif à maintenir l’indentation correcte.
Avant la fin de ce guide, nous verrons un exemple plus concret d’un playbook, expliqué en détail. La prochaine section vous donnera un aperçu des éléments et fonctionnalités les plus importants qui peuvent être utilisés pour écrire des playbooks Ansible.
Écriture de Playbooks
Maintenant que vous êtes familiarisé avec la terminologie de base et le format général des playbooks et des tâches dans Ansible, nous allons apprendre quelques fonctionnalités des playbooks qui peuvent nous aider à créer des automatisations plus polyvalentes.
Travailler avec des variables
Il existe différentes façons de définir des variables dans Ansible. La manière la plus simple est d’utiliser la section vars
d’un playbook. L’exemple ci-dessous définit une variable package
qui est ensuite utilisée dans une tâche :
---
- hosts: all
become: true
vars:
package: vim
tasks:
- name: Install Package
apt: name={{ package }} state=latest
La variable package
a une portée globale, ce qui signifie qu’elle peut être accédée à partir de n’importe quel point de la provision, même à partir des fichiers inclus et des modèles.
Utilisation des boucles
Les boucles sont généralement utilisées pour répéter une tâche en utilisant différentes valeurs d’entrée. Par exemple, au lieu de créer 10 tâches pour installer 10 packages différents, vous pouvez créer une seule tâche et utiliser une boucle pour répéter la tâche avec tous les packages différents que vous voulez installer.
Pour créer une boucle au sein d’une tâche, incluez l’option with_items
avec un tableau de valeurs. Le contenu peut être accédé via la variable de boucle item
, comme le montre l’exemple ci-dessous :
- name: Install Packages
apt: name={{ item }} state=latest
with_items:
- vim
- git
- curl
Vous pouvez également utiliser une variable de tableau pour définir vos éléments :
---
- hosts: all
become: true
vars:
packages: [ 'vim', 'git', 'curl' ]
tasks:
- name: Install Package
apt: name={{ item }} state=latest
with_items: "{{ packages }}"
Utilisation des conditionnelles
Les conditionnelles peuvent être utilisées pour décider dynamiquement si une tâche doit être exécutée ou non, en fonction d’une variable ou d’une sortie d’une commande, par exemple.
L’exemple suivant ne va arrêter que les systèmes basés sur Debian :
La conditionnelle when
reçoit en argument une expression à évaluer. La tâche n’est exécutée que si l’expression est évaluée à true
. Dans notre exemple, nous avons testé un fait pour vérifier si le système d’exploitation est de la famille Debian.
A common use case for conditionals in IT automation is when the execution of a task depends on the output of a command. With Ansible, the way we implement this is by registering a variable to hold the results of a command execution, and then testing this variable in a subsequent task. We can test for the command’s exit status (if failed or successful). We can also check for specific contents inside the output, although this might require the usage of regex expressions and string parsing commands.
L’exemple suivant montre deux tâches conditionnelles basées sur la sortie d’une commande php -v
. Nous allons tester le statut de sortie de la commande, car nous savons qu’elle échouera à s’exécuter si PHP n’est pas installé sur ce serveur. La partie ignore_errors
de la tâche est importante pour s’assurer que la provision continue même lorsque la commande échoue à s’exécuter.
Le module debug
utilisé ici est un module utile pour afficher le contenu des variables ou des messages de débogage. Il peut soit imprimer une chaîne (lors de l’utilisation de l’argument msg
) soit imprimer le contenu d’une variable (lors de l’utilisation de l’argument var
).
Travailler avec les modèles
Les modèles sont généralement utilisés pour configurer des fichiers de configuration, permettant l’utilisation de variables et d’autres fonctionnalités destinées à rendre ces fichiers plus polyvalents et réutilisables. Ansible utilise le moteur de modèle Jinja2.
L’exemple suivant est un modèle pour configurer un hôte virtuel Apache, en utilisant une variable pour définir le répertoire de documents de cet hôte :
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot {{ doc_root }}
<Directory {{ doc_root }}>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Le module intégré template
est utilisé pour appliquer le modèle à partir d’une tâche. Si vous avez nommé le fichier de modèle ci-dessus vhost.tpl
et que vous l’avez placé dans le même répertoire que votre playbook, voici comment vous appliqueriez le modèle pour remplacer l’hôte virtuel Apache par défaut :
Définition et déclenchement des gestionnaires
Les gestionnaires sont utilisés pour déclencher un changement d’état dans un service, tel qu’un redémarrage ou un arrêt. Bien qu’ils puissent sembler assez similaires aux tâches régulières, les gestionnaires ne sont exécutés que lorsqu’ils ont été préalablement déclenchés par une directive notify
dans une tâche. Ils sont généralement définis sous forme de tableau dans une section handlers
du playbook, mais ils peuvent également se trouver dans des fichiers séparés.
Prenons en considération notre exemple précédent d’utilisation de modèle, où nous avons configuré un hôte virtuel Apache. Si vous voulez vous assurer qu’Apache est redémarré après un changement d’hôte virtuel, vous devez d’abord créer un gestionnaire pour le service Apache. Voici comment les gestionnaires sont définis dans un playbook :
La directive name
ici est importante car elle sera l’identifiant unique de ce gestionnaire. Pour déclencher ce gestionnaire à partir d’une tâche, vous devez utiliser l’option notify
:
Nous avons vu quelques-unes des fonctionnalités les plus importantes que vous pouvez utiliser pour commencer à écrire des playbooks Ansible. Dans la prochaine section, nous plongerons dans un exemple plus concret d’un playbook qui automatisera l’installation et la configuration d’Apache sur Ubuntu.
Exemple de playbook
Jetons maintenant un coup d’œil à un playbook qui automatisera l’installation d’un serveur web Apache sur un système Ubuntu 18.04, comme discuté dans l’introduction de ce guide.
L’exemple complet, incluant le fichier modèle pour la configuration d’Apache et un fichier HTML à servir par le serveur web, peut être trouvé sur Github. Le dossier contient également un fichier Vagrantfile qui vous permet de tester le playbook dans une configuration simplifiée, en utilisant une machine virtuelle gérée par Vagrant.
Contenu du playbook
Le contenu complet du playbook est disponible ici pour votre commodité :
- ---
- - hosts: all
- become: true
- vars:
- doc_root: /var/www/example
- tasks:
- - name: Update apt
- apt: update_cache=yes
-
- - name: Install Apache
- apt: name=apache2 state=latest
-
- - name: Create custom document root
- file: path={{ doc_root }} state=directory owner=www-data group=www-data
-
- - name: Set up HTML file
- copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
-
- - name: Set up Apache virtual host file
- template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- notify: restart apache
- handlers:
- - name: restart apache
- service: name=apache2 state=restarted
-
Examinons chaque partie de ce playbook en détail :
hôtes: tous
Le playbook commence en indiquant qu’il doit être appliqué à tous les hôtes de votre inventaire (hôtes: tous
). Il est possible de restreindre l’exécution du playbook à un hôte spécifique ou à un groupe d’hôtes. Cette option peut être écrasée au moment de l’exécution.
devenir: vrai
La partie devenir: vrai
indique à Ansible d’utiliser l’élévation de privilèges (sudo) pour exécuter toutes les tâches de ce playbook. Cette option peut être écrasée tâche par tâche.
vars
Définit une variable, doc_root
, qui est ensuite utilisée dans une tâche. Cette section pourrait contenir plusieurs variables.
tâches
La section où les tâches réelles sont définies. La première tâche met à jour le cache apt
, et la deuxième tâche installe le paquet apache2
.
La troisième tâche utilise le module intégré fichier pour créer un répertoire qui servira de racine de document. Ce module peut être utilisé pour gérer les fichiers et répertoires.
La quatrième tâche utilise le module copie pour copier un fichier local sur le serveur distant. Nous copions un fichier HTML simple pour être servi en tant que site web hébergé par Apache.
gestionnaires
Enfin, nous avons la section gestionnaires
, où les services sont déclarés. Nous définissons le gestionnaire redémarrer apache
qui est notifié à partir de la quatrième tâche, où le modèle Apache est appliqué.
Exécution d’un playbook
Une fois que vous avez téléchargé le contenu de ce playbook sur votre nœud de contrôle Ansible, vous pouvez utiliser ansible-playbook
pour l’exécuter sur un ou plusieurs nœuds de votre inventaire. La commande suivante exécutera le playbook sur tous les hôtes de votre fichier d’inventaire par défaut, en utilisant l’authentification par paire de clés SSH pour se connecter en tant qu’utilisateur système actuel:
Vous pouvez également utiliser -l
pour limiter l’exécution à un seul hôte ou à un groupe d’hôtes de votre inventaire:
Si vous devez spécifier un utilisateur SSH différent pour vous connecter au serveur distant, vous pouvez inclure l’argument -u utilisateur
à cette commande:
Pour plus d’informations sur la façon d’exécuter des commandes et des playbooks Ansible, veuillez vous référer à notre guide sur Comment Installer et Configurer Ansible sur Ubuntu 18.04.
Conclusion
Ansible est un outil d’automatisation IT minimaliste qui présente une courbe d’apprentissage faible, utilisant YAML
pour ses scripts de provisionnement. Il dispose d’un grand nombre de modules intégrés qui peuvent être utilisés pour abstraire des tâches telles que l’installation de paquets et le travail avec des modèles. Ses exigences en infrastructure simplifiées et son langage simple peuvent convenir à ceux qui commencent avec la gestion de configuration. Cependant, il peut manquer certaines fonctionnalités avancées que l’on peut trouver avec des outils plus complexes comme Puppet et Chef.
Dans la prochaine partie de cette série, nous verrons un aperçu pratique de Puppet, un outil populaire et bien établi de gestion de configuration qui utilise un DSL personnalisé expressif et puissant basé sur Ruby pour écrire des scripts de provisionnement.