Gestion de la configuration 101: Écrire des livres de lecture Ansible

introduction

En résumé, la gestion de la configuration du serveur (également appelée IT Automation) est une solution permettant de transformer l’administration de votre infrastructure en base de code, décrivant tous les processus nécessaires au déploiement d’un serveur dans un ensemble de scripts de provisioning pouvant être versionnés et réutilisés facilement. Cela peut considérablement améliorer l’intégrité de toute infrastructure de serveur au fil du temps.

Dans un https://www.digitalocean.com/community/tutorials/an-introduction-to-configuration-management (guide précédent), nous avons présenté les principaux avantages de la mise en œuvre d’une stratégie de gestion de la configuration pour votre infrastructure de serveur. les outils fonctionnent et ce qu’ils ont généralement en commun.

Cette partie de la série vous guidera tout au long du processus d’automatisation du provisioning de serveur à l’aide d’Ansible, un outil de gestion de la configuration fournissant un cadre d’automatisation complet et des capacités d’orchestration, tout en maintenant un objectif de simplicité et de minimalisme ultimes. Nous nous concentrerons sur la terminologie linguistique, la syntaxe et les fonctionnalités nécessaires pour créer un exemple simplifié permettant d’automatiser complètement 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 pour atteindre notre objectif:

  1. Mettre à jour le cache + apt +

  2. Installer Apache

  3. Créer un répertoire racine de document personnalisé

  4. Placez un fichier + index.html dans la racine du document personnalisé

  5. Appliquer un modèle pour configurer notre hôte virtuel personnalisé

  6. Redémarrer Apache

Nous allons commencer par examiner la terminologie utilisée par Ansible, puis par un aperçu des principales fonctionnalités linguistiques pouvant être utilisées pour écrire des playbooks. À la fin de ce guide, vous trouverez le contenu d’un exemple de provisionnement complet permettant d’automatiser les étapes décrites pour la configuration d’Apache sur Ubuntu 18.04.

Commencer

Avant de pouvoir passer à une vue plus concrète de 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:

  • * Control Node *: la machine sur laquelle est installé Ansible, chargée de l’exécution du provisioning sur les serveurs que vous gérez.

  • * Inventory *: un fichier + INI + qui contient des informations sur les serveurs que vous gérez.

  • * Playbook *: un fichier + YAML + contenant une série de procédures à automatiser.

  • * Tâche *: un bloc qui définit une procédure unique à exécuter, par exemple: installer un package.

  • * Module *: un module résume généralement une tâche système, comme traiter des packages ou créer et modifier des fichiers. Ansible dispose d’une multitude de modules intégrés, mais vous pouvez également en créer des personnalisés.

  • * Role *: ensemble de playbooks, modèles et autres fichiers associés, organisés de manière prédéfinie pour faciliter la réutilisation et le partage.

  • * Jouer *: un provisioning exécuté du début à la fin s’appelle un play.

  • * Faits *: variables globales contenant des informations sur le système, telles que les interfaces réseau ou le système d’exploitation.

  • * Gestionnaires *: 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

Une tâche définit une étape automatisée unique devant être exécutée par Ansible. Cela implique généralement l’utilisation d’un module ou l’exécution d’une commande brute. Voici à quoi ressemble une tâche:

- 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 du provisioning lors de l’exécution de la tâche. La partie + apt + est un module intégré Ansible qui résume la gestion des paquets sur les distributions basées sur Debian. Cet exemple de tâche indique à Ansible que l’état du paquet + vim + devrait être changé en + latest +, ce qui obligera le gestionnaire de paquet à installer ce paquet s’il ne l’est pas encore.

Format du livre de jeu

Les Playbooks sont des fichiers + YAML + contenant une série de directives pour automatiser l’approvisionnement d’un serveur. L’exemple suivant est un livre de lecture simple qui effectue deux tâches: met à jour le cache + apt + et installe + vim + par la suite:

---
- hosts: all
 become: true
 tasks:
    - name: Update apt-cache
      apt: update_cache=yes

    - name: Install Vim
      apt: name=vim state=latest

+ YAML + s’appuie sur l’indentation pour sérialiser les structures de données. Pour cette raison, lors de la rédaction de playbooks et en particulier lors de la copie d’exemples, vous devez faire très attention à conserver l’indentation correcte.

Avant la fin de ce guide, nous verrons un exemple plus réaliste de manuel de jeu, expliqué en détail. La section suivante vous donnera un aperçu des éléments et des fonctionnalités les plus importants qui peuvent être utilisés pour écrire des cahiers de jeu Ansible.

Écrire des cahiers

Maintenant que vous maîtrisez la terminologie de base et le format général des cahiers et des tâches de Ansible, nous allons en apprendre davantage sur certaines fonctionnalités qui peuvent nous aider à créer des automatisations plus polyvalentes.

Travailler avec des variables

Il existe différentes manières de définir des variables dans Ansible. Le moyen le plus simple consiste à utiliser la section + vars + d’un playbook. L’exemple ci-dessous définit une variable + package + qui sera utilisée ultérieurement 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 est accessible à tout moment du provisionnement, même à partir de fichiers et de modèles inclus.

Utiliser 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 tâche unique et utiliser une boucle pour répéter la tâche avec tous les packages que vous souhaitez installer.

Pour créer une boucle dans une tâche, incluez l’option + with_items + avec un tableau de valeurs. Le contenu est accessible via la variable de boucle + item +, comme indiqué dans 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 de conditions

Les conditions peuvent être utilisées pour déterminer de manière dynamique si une tâche doit être exécutée, en fonction d’une variable ou du résultat d’une commande, par exemple.

L’exemple suivant n’arrêtera que les systèmes basés sur Debian:

- name: Shutdown Debian Based Systems
 command: /sbin/shutdown -t now
 when: ansible_os_family == "Debian"

Le conditionnel + quand + reçoit en argument une expression à évaluer. La tâche n’est exécutée que dans le cas où l’expression est évaluée à + ​​true +. Dans notre exemple, nous avons testé un * fact * pour vérifier si le système d’exploitation appartient à la famille Debian.

Un cas d’utilisation courant pour les conditions dans l’automatisation informatique est lorsque l’exécution d’une tâche dépend de la sortie d’une commande. Avec Ansible, nous implémentons cela en enregistrant une variable pour conserver les résultats de l’exécution d’une commande, puis en testant cette variable dans une tâche ultérieure. Nous pouvons tester l’état de sortie de la commande (en cas d’échec ou de succès). Nous pouvons également rechercher des contenus spécifiques dans la sortie, bien que cela puisse nécessiter l’utilisation d’expressions regex et de commandes d’analyse de chaînes.

L’exemple suivant montre deux tâches conditionnelles basées sur le résultat d’une commande + php -v +. Nous allons tester le statut de sortie de la commande, car nous savons que son exécution échouera si PHP n’est pas installé sur ce serveur. La partie + ignore_errors + de la tâche est importante pour s’assurer que le provisioning continue même lorsque l’exécution de la commande échoue.

- name: Check if PHP is installed
 register: php_installed
 command: php -v
 ignore_errors: true

- name: This task is only executed if PHP is installed
 debug: var=php_install
 when: php_installed|success

- name: This task is only executed if PHP is NOT installed
 debug: msg='PHP is NOT installed'
 when: php_installed|failed

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 (en utilisant l’argument + msg +), soit imprimer le contenu d’une variable (en utilisant l’argument + var +).

Travailler avec des modèles

Les modèles sont généralement utilisés pour configurer les fichiers de configuration, ce qui permet d’utiliser des 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 de configuration d’un hôte virtuel Apache, utilisant une variable pour configurer la racine du document pour 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 template à 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, appliquez le modèle pour remplacer l’hôte virtuel Apache par défaut:

- name: Change default Apache virtual host
 template:
   src: vhost.tpl
   dest: /etc/apache2/sites-available/000-default.conf

Définir et déclencher des gestionnaires

Les gestionnaires sont utilisés pour déclencher un changement d’état dans un service, tel qu’un restart ou un stop. Même s’ils peuvent sembler assez similaires aux tâches ordinaires, les gestionnaires ne sont exécutés que lorsqu’ils ont déjà été déclenchés à partir d’une directive + notify + dans une tâche. Ils sont généralement définis comme un tableau dans une section + handlers + du playbook, mais ils peuvent également vivre dans des fichiers séparés.

Prenons en considération notre exemple d’utilisation du modèle précédent, dans lequel nous avons configuré un hôte virtuel Apache. Si vous voulez vous assurer que 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 sont définis les gestionnaires dans un playbook:

handlers:
   - name: restart apache
     service: name=apache2 state=restarted

   - name: other handler
     service: name=other state=restarted

La directive + nom + ici est importante car ce sera l’identifiant unique de ce gestionnaire. Pour déclencher ce gestionnaire à partir d’une tâche, vous devez utiliser l’option + notify +:

- name: Change default Apache virtual host
 template:
   src: vhost.tpl
   dest: /etc/apache2/sites-available/000-default.conf
 notify: restart apache

Nous avons vu certaines des fonctionnalités les plus importantes que vous pouvez utiliser pour commencer à écrire des livres de lecture Ansible. Dans la section suivante, nous allons plonger dans un exemple plus réel de playbook qui automatisera l’installation et la configuration d’Apache sur Ubuntu.

Exemple Playbook

Voyons maintenant un livre de lecture qui automatisera l’installation d’un serveur Web Apache sur un système Ubuntu 18.04, comme indiqué dans l’introduction de ce guide.

L’exemple complet, y compris le fichier de modèle pour la configuration d’Apache et un fichier HTML destiné au serveur Web, est disponible à l’adresse on Github. Le dossier contient également un fichier Vagrant qui vous permet de tester le livre de lecture dans une configuration simplifiée, à l’aide d’une machine virtuelle gérée par https://vagrantup.com [Vagrant].

Contenu du livre de jeu

Le contenu complet du manuel est disponible ici pour votre commodité:

playbook.yml

---
- 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 manuel plus en détail:

  • hosts: all * + Le playbook commence par indiquer qu’il doit être appliqué aux hôtes + all + de votre inventaire (+ hosts: all +). Il est possible de limiter l’exécution du playbook à un hôte spécifique ou à un groupe d’hôtes. Cette option peut être remplacée au moment de l’exécution.

  • deviennent: vrais * + La partie `deviens: vrais + 'indique à Ansible d’utiliser l’ascension des privilèges (sudo) pour exécuter toutes les tâches de ce manuel. Cette option peut être écrasée tâche par tâche.

  • vars * + Définit une variable, + doc_root +, qui sera utilisée plus tard dans une tâche. Cette section peut contenir plusieurs variables.

  • tasks * + La section où les tâches réelles sont définies. La première tâche met à jour le cache + apt +, et la seconde tâche installe le paquetage + 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 des fichiers et des répertoires.

La quatrième tâche utilise le module * copy * pour copier un fichier local sur le serveur distant. Nous copions un simple fichier HTML qui servira de site Web hébergé par Apache.

  • handlers * + Enfin, nous avons la section + handlers +, où les services sont déclarés. Nous définissons le gestionnaire + restart apache qui est notifié à partir de la quatrième tâche, où le modèle Apache est appliqué.

Lancer un livre de jeu

Une fois que vous avez téléchargé le contenu de ce livret 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 livre de lecture sur * tous * les hôtes à partir 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:

ansible-playbook playbook.yml

Vous pouvez également utiliser + -l + pour limiter l’exécution à un seul hôte ou à un groupe d’hôtes de votre inventaire:

ansible-playbook -l  playbook.yml

Si vous devez spécifier un autre utilisateur SSH pour vous connecter au serveur distant, vous pouvez inclure l’argument + -u + à cette commande:

ansible-playbook -l  playbook.yml -u

Pour plus d’informations sur l’exécution des commandes et des livres de lecture Ansible, veuillez vous reporter à notre guide à l’adresse https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-ubuntu-18-. 04 [Comment installer et configurer Ansible sur Ubuntu 18.04].

Conclusion

Ansible est un outil d’automatisation informatique minimaliste qui a une courbe d’apprentissage faible, utilisant + YAML + pour ses scripts de provisioning. Il possède un grand nombre de modules intégrés qui peuvent être utilisés pour des tâches abstraites telles que l’installation de packages et l’utilisation de modèles. Son infrastructure simplifiée et son langage simple peuvent convenir à ceux qui débutent avec la gestion de la configuration. Cependant, certaines fonctionnalités avancées que vous pouvez trouver avec des outils plus complexes comme Puppet et Chef peuvent manquer.

Dans la next de cette série, nous verrons un aperçu pratique de Puppet, une configuration populaire et bien établie outil de gestion qui utilise un DSL personnalisé expressif et puissant basé sur Ruby pour écrire des scripts de provisioning.