Outils pour utilisateurs

Outils du site


stage:turgot:btssn:2020:couderchon.jonathan:ansible

COUDERCHON Jonathan | BTS SNIR 1er année


RAPPORT DE STAGE | ANSIBLE


Liens :

  • Présentation de Ansible sur Wikipedia.
  • Apprendre les bases de Ansible sur le site de Red Hat
  • Apprendre les bases de Ansible sur le site de Openclassrooms

Utilisation d'une clé SSH

Cela permet d'éviter d'utiliser un nom et un mot de passe avec peu de caractère. Avec ssh il est possible de choisir le nombre de caractère dans mon cas je suis a 2048 donc pratiquement impossible à trouver.

# ssh-keygen -t ecdsa

résultat clé ssh (non divulgué public)

Generating public/private ecdsa key pair.
Enter file in which to save the key (/root/.ssh/id_ecdsa): root
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in root.
Your public key has been saved in root.pub.
The key fingerprint is:
(clé ssh) root@cjdebian
The key's randomart image is:

Création de container

J'ai commencé par créer deux nouveaux containers avec comme iso “debian-10-standard_10.7-1_amd64.tar.gz”. Un de ces containers permet de gérer la partie web et l'autre permet de gérer la partie base de données.

Avant de continue je mets à jour les debian.

commande de mise à jour

# apt update
# apt upgrade

Connexion ssh entre les serveur et debian

Une fois que les serveurs debian sont à jour, je leur installe ssh pour que le premier debian créé que je vais nommer debian-cont se connecte aux deux serveurs.

commande d'installation ssh

# apt install openssh-server

Mais avant de pouvoir utiliser ssh il faut modifier le fichier ssh_config en rajoutant une ligne de code puis relancez le service ssh.

  • écrire dans le fichier ssh_config :
nano /etc/ssh/sshd_config
  • ajoutez la ligne suivante :
PermitRootLogin yes
  • Relancez le service ssh :
# systemctl restart ssh

Je vérifie que le langage de programmation Python est bien installé de base.

  • commande d'installation Python
# apt install python
# apt install python3
  • commande pour se connecter à ces deux serveurs
# ssh root@10.187.37.47
# ssh root@10.187.37.69

Installation Ansible

Installation Python - SSH

L'installation du paquet python-virtualenv permettra de créer des environnements de travail virtuels tels que virtualenv.

Ainsi que l'installation du paquet sshpass qui servira ultérieurement pour se connecter en SSH avec Ansible.

# apt install python-virtualenv sshpass

Création d'un simple utilisateur

Pour éviter de travailler en étant root sur le debian-cont qui n'ait pas recommandé, le compte root peut tout faire sans aucune limite.

# adduser user-ansible

Connexion a simple utilisateur

Une fois que le compte est créé, il suffit tout simplement d'utiliser la commande suivante pour se connecter au compte simple utilisateur

su - user-ansible

Création d'un environnement de travail virtuel

Comme indiqué plus haut, il faut utiliser un environnement de travail virtuel pour cloisonner l’installation et l'exécution d'Ansible. Ceci permettra de gérer les dépendances avec la version de Python et d’installer une version particulière de Ansible.

J'aurai besoin d'installer la version 2.7.10 de Ansible

$ virtualenv ansible2.7.10

J'utiliserai la commande virtualenv pour créer l'environnement ansible2.7.10 dans lequel les outils, les ressources et le gestionnaire de paquets sont installés

Afin de l'activer il faut activer le source ce qui permettra d'activer l’environnement virtuel

$ source ansible2.7.10/bin/activate

Instalation de Ansible dans l'environnement virtuel

Maintenant que je suis connecté avec le simple compte utilisateur, je peux installer Ansible2.7.10 grâce à la commande pip.

$ pip install ansible==2.7.10

La commande suite permet de connaître la version de Ansible installer

$ ansible --version

Vérification de l'installation

En utilisant la commande suivante, cela permet de savoir dans le répertoire bin de l'environnement virtuel les outils Ansible installés. Pour que l'installation soit une réussite il faut 10 outils dans le répertoire.

$ ls ansible2.7.10/bin/ansible* -l

Résultat :

-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-config
-rwxr-xr-x 1 user-ansible user-ansible 11709 Jun  9 14:58 ansible2.7.10/bin/ansible-connection
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-console
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-doc
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-galaxy
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-inventory
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-playbook
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-pull
-rwxr-xr-x 1 user-ansible user-ansible  5870 Jun  9 14:58 ansible2.7.10/bin/ansible-vault

Préparation de la communication

Définir un inventaire des nodes

utilisation des serveurs :

  • Serveur 1 : http1; installation : Apache, php et mediaWiki
  • Serveur 2 : bbd1; installation : Mariadb

Pour pouvoir utiliser le nom donné au serveur et non leur adresse IP je vais devoir modifier un fichier grâce à l'utilitaire nano.

# nano /etc/hosts

résultat avant modification :

127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
# --- BEGIN PVE ---
127.0.1.1 cjdebian.0870019y.lan cjdebian
# --- END PVE ---

résultat après modification :

127.0.0.1 localhost
127.0.1.1 node-manager
# le node http1
10.187.37.47 http1
# le node bbd1
10.187.37.69 bbd1

::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
# --- BEGIN PVE ---
127.0.1.1 cjdebian.0870019y.lan cjdebian
# --- END PVE ---

Création d'un fichier inventaire Ansible

Pour créer ce fichier d'inventaire Ansible, je dois tous d'abord me placer dans l'environnement virtuel,

$ source ansible2.7.10/bin/activate

Pour créer ce fichier d'inventaire Ansible, je dois tous d'abord me placer dans l'environnement virtuel,

$ nano inventaire.ini

Et pour finir la création du fichier je dois mettre les deux noms des nodes

http1
bbd1

Vérifier que les nodes communiquez

Lorsque l'on utilise Ansible pour automatiser des tâches, il faut lancer une connexion SSH sur les nodes pour enregistrer la fingerprint (l'empreinte du serveur qui doit être vérifiée pour être sûr de se connecter au bon node). Il est naiseraire de le faire au moins une fois afin que Ansible fonctionne avec les connections des nodes car le paquet sshpass ne sait pas gérer le fingerprint.

$ ssh root@http1

Une fois que la commande est utiliser je doit répondre “yes” puis écrire le mot de passe pour avoir accès au serveur debianweb et puis faire la même chose avec l'autre serveur pour accès au serveur debianbbd.

$ ssh root@bbd1

Utilisation de la commande Ansible en mode ad-hac

Je vais commencer par utiliser Ansible en mode ad-hoc donc avec des commandes manuelle plutôt que des scripts afin de mettre en place les prérequis. Cela permettra de les automatiser et de les appliquer à tous les nodes en même temps.

Les commande ad-hoc sont des actions rapides qui ne nécessitent pas forcément de les sauvegarder pour plus tard.

liens de référencement approfondi :

j'utilise maintenant un ping avec Ansible dans l'environnement de travail virtuel.

Commande ping http1 :

$ ansible -i inventaire.ini -m ping http1 --user root --ask-pass

résultat du ping :

SSH password:
http1 | SUCCESS => {
"changed": false,
"ping": "pong"
}

Commande ping bbd1 :

$ ansible -i inventaire.ini -m ping bbd1 --user root --ask-pass

résultat du ping :

SSH password:
http1 | SUCCESS => {
"changed": false,
"ping": "pong"
}

Il est possible d'utiliser plusieurs option sur la commande Ansible :

  • i : indique à Ansible l’emplacement du fichier inventaire
  • m : indique à Ansible d’utiliser le module ping
  • http : indique à Ansible de faire l’action sur le node http1
  • –user : indique à Ansible d’utiliser l’utilisateur root pour se connecter au node
  • –ask-pass : indique à Ansible de demander le mot de passe SSH

Le retour de la commande indique que l'action est un sucès et répond pong au ping. Le node http1 est bien joignable.

Ansible ne lancer pas la commande ping, il lance un module qui fait la même chose que la commande ping.

Module

Un Module est un programme qui exécute une tâche ou une commande Ansible. Chaque tâche utilise un seul module qui peut prendre des argument pour les exécuté de façon personalisée. Il est possible de créer ses propre modules, même si Ansible en fournit beaucoup.

En utilisant la commande ci-dessous j'ai accès a tous les modules de Ansible :

$ ansible-doc --list

Petit résultat (plusieurs centaine de ligne de modules)

a10_server                                           Manage A10 Networks AX...
a10_server_axapi3                                    Manage A10 Networks AX...
a10_service_group                                    Manage A10 Networks AX...
a10_virtual_server                                   Manage A10 Networks AX...
aci_aaa_user                                         Manage AAA users (aaa:...
aci_aaa_user_certificate                             Manage AAA user certif...
aci_access_port_to_interface_policy_leaf_profile     Manage Fabric interfac...
aci_aep                                              Manage attachable Acce...
aci_aep_to_domain                                    Bind AEPs to Physical ...
aci_ap                                               Manage top level Appli...
aci_bd                                               Manage Bridge Domains ...
aci_bd_subnet                                        Manage Subnets (fv:Sub...
aci_bd_to_l3out                                      Bind Bridge Domain to ...
aci_config_rollback                                  Provides rollback and ...
aci_config_snapshot                                  Manage Config Snapshot...
aci_contract                                         Manage contract resour...
aci_contract_subject                                 Manage initial Contrac...
aci_contract_subject_to_filter                       Bind Contract Subjects...
aci_domain                                           Manage physical, virtu...
aci_domain_to_encap_pool                             Bind Domain to Encap P...
aci_domain_to_vlan_pool                              Bind Domain to VLAN Po...
aci_encap_pool                                       Manage encap pools (fv...
aci_encap_pool_range                                 Manage encap ranges as...
:...skipping...
a10_server                                           Manage A10 Networks AX...
a10_server_axapi3                                    Manage A10 Networks AX...
a10_service_group                                    Manage A10 Networks AX...
a10_virtual_server                                   Manage A10 Networks AX...
aci_aaa_user                                         Manage AAA users (aaa:...
aci_aaa_user_certificate                             Manage AAA user certif...
aci_access_port_to_interface_policy_leaf_profile     Manage Fabric interfac...
aci_aep                                              Manage attachable Acce...
aci_aep_to_domain                                    Bind AEPs to Physical ...
aci_ap                                               Manage top level Appli...
aci_bd                                               Manage Bridge Domains ...
aci_bd_subnet                                        Manage Subnets (fv:Sub...
aci_bd_to_l3out                                      Bind Bridge Domain to ...
aci_config_rollback                                  Provides rollback and ...
aci_config_snapshot                                  Manage Config Snapshot...
aci_contract                                         Manage contract resour...
aci_contract_subject                                 Manage initial Contrac...
aci_contract_subject_to_filter                       Bind Contract Subjects...
aci_domain                                           Manage physical, virtu...
aci_domain_to_encap_pool                             Bind Domain to Encap P...
aci_domain_to_vlan_pool                              Bind Domain to VLAN Po...
aci_encap_pool                                       Manage encap pools (fv...
aci_encap_pool_range                                 Manage encap ranges as...
aci_epg                                              Manage End Point Group...
aci_epg_monitoring_policy                            Manage monitoring poli...
aci_epg_to_contract                                  Bind EPGs to Contracts...
aci_epg_to_domain                                    Bind EPGs to Domains (...
aci_fabric_node                                      Manage Fabric Node Mem...
aci_filter                                           Manages top level filt...
aci_filter_entry                                     Manage filter entries ...
aci_firmware_source                                  Manage firmware image ...
aci_interface_policy_fc                              Manage Fibre Channel i...
aci_interface_policy_l2                              Manage Layer 2 interfa...
aci_interface_policy_leaf_policy_group               Manage fabric interfac...
aci_interface_policy_leaf_profile                    Manage fabric interfac...
aci_interface_policy_lldp                            Manage LLDP interface ...
aci_interface_policy_mcp                             Manage MCP interface p...
aci_interface_policy_ospf                            Manage OSPF interface ...
aci_interface_policy_port_channel                    Manage port channel in...
aci_interface_policy_port_security                   Manage port security (...
aci_interface_selector_to_switch_policy_leaf_profile Bind interface selecto...
aci_intf_policy_fc                                   Manage Fibre Channel i...
aci_intf_policy_l2                                   Manage Layer 2 interfa...
aci_intf_policy_lldp                                 Manage LLDP interface ...
aci_intf_policy_mcp                                  Manage MCP interface p...
aci_intf_policy_port_channel                         Manage port channel in...
aci_intf_policy_port_security                        Manage port security (...
aci_l3out                                            Manage Layer 3 Outside...
aci_l3out_route_tag_policy                           Manage route tag polic...
:

Lorsque j'ai installer Ansible tous les modules officiels se sont télécharger. Ansible va chercher le code à exécuter dans le dossier du module quand un module est éxecuté, mais comme Ansible est installer dans un environnement tous les modules se trouve sur ./ansible2.7.10/lib/python2.7/site-packages/ansible.

Vérifier que Python est installé sur les nodes

Afin de bien tester la connectivité avec les serveurs je vais revérifier que Python est bien installer sur les nodes.

Installation de Python node : http1 :

$ ansible -i inventaire.ini -m raw -a "apt install -y python2" http1 --user root --ask-pass

Résultat :

http1 | CHANGED | rc=0 >>
Reading package lists... Done
Building dependency tree
Reading state information... Done
python2 is already the newest version (2.7.16-1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Shared connection to http1 closed.

Installation de Python node : http1 :

$ ansible -i inventaire.ini -m raw -a "apt install -y python2" bbd1 --user root --ask-pass

Résultat :

bbd1 | CHANGED | rc=0 >>
Reading package lists... Done
Building dependency tree
Reading state information... Done
python2 is already the newest version (2.7.16-1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Shared connection to http1 closed.

L'option -m permet de faire appele au module raw avec l'argument “apt install -y python” se qui permet d'installer la deuxième version de Python sur le node en question.

Création de l'utilisateur user-ansible sur les nodes

Je vais créer un simple utilisateur afin de ne pas directement travailler sur le compte root. Mais avant je vais générer un mot de passe chiffré a l'aide de Ansible.

$ ansible localhost -i inventaire.ini -m debug -a "msg={{ 'passforce' | password_hash('sha512', 'sceretsalt') }}"

Résultat du mot de passe chiffré :

localhost | SUCCESS => {
    "msg": "$6$sceretsalt$tBcfGEgifQpQZsg5CIGZ79XC55h5vHy7UWrys7cAF37KNCQQbm7iCvy58MlLQLaS2fLF6ZjqDVHhVrkMdRi0f0"
}

Cette commande j'utilise le module debug avec comme argument msg se qui a permis au mot de passe de se transformer en une chaîne chiffré. L'option “localhost” indique à Ansible de lancer la commande sur localhost.

Maintenant je vais créer l'utilisateur user-ansible avec aussi un mot de passe chiffré.

$ ansible -i inventaire.ini -m user -a 'name=user-ansible password=$6$sceretsalt$tBcfGEgifQpQZsg5CIGZ79XC55h5vHy7UWrys7cAF37KNCQQbm7iCvy58MlLQLaS2fLF6ZjqDVHhVrkMdRi0f0' --user root --ask-pass all

Résultat de la commande :

http1 | CHANGED => {
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 1000,
    "home": "/home/user-ansible",
    "name": "user-ansible",
    "password": "NOT_LOGGING_PASSWORD",
    "shell": "/bin/sh",
    "state": "present",
    "system": false,
    "uid": 1000
}
bbd1 | CHANGED => {
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 1000,
    "home": "/home/user-ansible",
    "name": "user-ansible",
    "password": "NOT_LOGGING_PASSWORD",
    "shell": "/bin/sh",
    "state": "present",
    "system": false,
    "uid": 1000
}

Donnez les droits sudo à user-ansible

Je me suis connecté au node http1 pour regardez le contenue du fichier /etc/sudoers, il s'agit de la configuration de sudo :

Fichier /etc/sudoers :

Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:$

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

Puisque le groupe sudo possède les droits d'administration, j'ajoute l'utilisateur user-ansible dans le groupe sudo sur tous les nodes

Commande d'ajoute a un groupe :

$ ansible -i inventaire.ini -m user -a 'name=user-ansible groups=sudo append=yes ' --user root --ask-pass all

Résultat de l'ajoute au groupe :

http1 | CHANGED => {
    "append": true,
    "changed": true,
    "comment": "",
    "group": 1000,
    "groups": "sudo",
    "home": "/home/user-ansible",
    "move_home": false,
    "name": "user-ansible",
    "shell": "/bin/sh",
    "state": "present",
    "uid": 1000
}
bbd1 | CHANGED => {
    "append": true,
    "changed": true,
    "comment": "",
    "group": 1000,
    "groups": "sudo",
    "home": "/home/user-ansible",
    "move_home": false,
    "name": "user-ansible",
    "shell": "/bin/sh",
    "state": "present",
    "uid": 1000
}

A partir de maintenant je n'utilise plus root, mais l'utilisateur user-ansible en mode sudo afin d'utiliser les commande Ansible.

Création de clés SSH

SSH : est une communication qui est établie sur la base de clés ce qui permet d'avoir un niveau d'authentification bien plus sûr qu'un simple mot de passe.

Afin de pouvoir se connecter en SSH, j'ai besoin d'une paire de clés SSH.

Création de clées SSH de type ecdsa

Je commance en me mettant en utilisateur user-ansible.

Commande pour entrer dans user-ansible :

# su - user-ansible

Puis j'utilise la commande suivante pour générer une clé (clé privé et clé publique)

$ ssh-keygen -t ecdsa

Exemple de Résultat afin de garder ma clé anonyme :

Generating public/private ecdsa key pair.
Enter file in which to save the key (/home/user-ansible/.ssh/id_ecdsa):
Created directory '/home/user-ansible/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user-ansible/.ssh/id_ecdsa.
Your public key has been saved in /home/user-ansible/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:geBOUCBR+4ljdMOn5QVmq9R7dpgmwYsAv995BtTWCYg user-ansible@node-manager
The key's randomart image is:
+---[ECDSA 256]---+
|+o+oo.+..    |
| + =E*.= o . |
|  = B X = o  |
| . X @ * +   |
|  = B * S .  |
|   . o . B . |
|  . o o      |
|   o         |
|             |
+----[SHA256]-----+

Ajout de la clé publique de l'utilisateur user-ansible sur les nodes

Je vais utiliser le module authorized_key se qui va me permettre d'enregistrer la clé publique de l'utilisateur user-ansible sur tous les nodes. Grâce a cette clé SSH je vais pouvoir me connecter aux autre nodes sans avoir a saisir le mot de passe SSH.

$ ansible -i inventaire.ini -m authorized_key -a 'user=user-ansible state=present key="{{ lookup("file", "/home/user-ansible/.ssh/id_ecdsa.pub") }}"' --user user-ansible --ask-pass --become --ask-become-pass all

Resultat :

http1 | SUCCESS => {
    "append": true,
    "changed": false,
    "comment": "",
    "group": 1000,
    "groups": "sudo",
    "home": "/home/user-ansible",
    "move_home": false,
    "name": "user-ansible",
    "shell": "/bin/sh",
    "state": "present",
    "uid": 1000
}
bbd1 | SUCCESS => {
    "append": true,
    "changed": false,
    "comment": "",
    "group": 1000,
    "groups": "sudo",
    "home": "/home/user-ansible",
    "move_home": false,
    "name": "user-ansible",
    "shell": "/bin/sh",
    "state": "present",
    "uid": 1000
}

Uniquement le mot de passe de sudo est utiliser alors que avant il était nécessaire d'utiliser également le mot de passe SSH. Une fois que toute cette partie est fini je vais pouvoir exécuter des commandes a distence sur les nodes grâce a Ansible avec le privilège sudo.

Opérations de déploiement

Création du premier rôle

Je vais créer une arborescence de fichiers de configuration qui me permettra de dérouler les étapes de déploiement de MediaWiki.

commande : création du répertoire rôles :

$ mkdir roles

commande : entrer dans le répertoire roles :

$ cd roles

Création de l'arborescence des rôles MediaWiki

Je vais créer un après l'autre la structure des 5 rôles pour le déploiement de MediaWiki.

Rôle Apache2

Lorsque je suis dans le répertoire roles j'utilise la commande suivante afin de supprimer les répertoires inutiles et de conservés les répertoires handlers, meta et tasks.

$ cd apache &&rm -r files meta templates vars defaults tests README.md

Résultat :

roles/apache2
|-- handlers
|   `-- main.yml
`-- tasks
    `-- main.yml

Rôle mariadb

commande pour créer les répertoire :

$ mkdir -p mariadb/tasks/

commande pour voir le répertoire :

$ tree mariadb

Résultat dans le répertoire rôles :

mariadb/
`-- tasks

commande pour créer le fichier main.yml:

$ touch mariadb/tasks/main.yml

Résultat :

mariadb
`-- tasks
    `-- main.yml

Je vais créer un répertoire spécifique mediawiki pour placer les rôles de configuration et commun. C'est opération de configuration et les variable concernent spécifiquement le déploiement de MediaWiki

commande de création du répertoire :

$ mkdir mediawiki

commande afin de voir tous le répertoire :

$ tree

Résultat (Répertoire “roles”) :

.
|-- apache2
|   |-- handlers
|   |   `-- main.yml
|   `-- tasks
|       `-- main.yml
|-- mariadb
|   `-- tasks
|       `-- main.yml
`-- mediawiki

Rôle confdb

Pour utiliser le roles confdb je dois tous d'abord créer une base de données et aussi d'attribuer des droits sur cette base de données

Puis je créer une dépendance avec le rôle commun afin de partager des variable globales

commande création des répertoire :

$ mkdir -p mediawiki/confdb/meta mediawiki/confdb/tasks

commande création des fichier qui contienne des actions :

$ touch mediawiki/confdb/tasks/main.yml 
$ touch mediawiki/confdb/meta/main.yml

Résultat :

mediawiki/
`-- confdb
    |-- meta
    |   `-- main.yml
    `-- tasks
        `-- main.yml

Rôle commun

Je vais créer le rôle commun qui permettra de contenir des variable partagées entre les rôles confapache2 et confdb. Se sera vraiment pratique car, au lieu de féfinir les mêmes variables à deux différents se qui est mieux en créeant un rôle commun et en utilisant une dépendance avec les autres rôles.

Il faut donc que je créer un répertoire defaults et créer un fichier main.yml a l’intérieur, ce fichier contiendra les variable globales.

commande : création du répertoire :

$ mkdir -p mediawiki/commun/defaults/

commande : création du fichier :

$ touch mediawiki/commun/defaults/main.yml

Résultat : répertoire roles:

.
|-- apache2
|   |-- handlers
|   |   `-- main.yml
|   `-- tasks
|       `-- main.yml
|-- mariadb
|   `-- tasks
|       `-- main.yml
`-- mediawiki
    `-- commun
        `-- defaults
            `-- main.yml

Rôle confdb

Comme je vais partager des variable globales avec le rôle confdb, je vais ajouter une dépendance avec le rôle commun. Mais également créer le répertoire d'installation de MediaWiki ainsi que télécharger les fichier MediaWiki du site officiel, puis lancer le script de l'installation et pour finir mettre les base de données à jour.

commande : création des répertoire :

$ mkdir -p mediawiki/confdb/meta mediawiki/confdb/tasks

commande : création du ficher :

$ touch mediawiki/confdb/tasks/main.yml 
$ touch mediawiki/confdb/meta/main.yml

Résultat : répertoire mediawiki :

mediawiki
|-- commun
|   `-- defaults
|       `-- main.yml
`-- confdb
    |-- meta
    |   `-- main.yml
    `-- tasks
        `-- main.yml

Rôle confapache2

Afin que la création du rôle confapache2, je vais partager des variables globales avec le rôle confdb. Pour cela je vais ajouter une dépendance avec le rôle commun, mais aussi créer un répertoire d'installation de MediaWiki

commande : installation répertoire d'installation MediaWiki (dans son répertoire)

$ mkdir -p confapache/meta confapache/tasks 

commande : création d'un ficher dans les deux répertoire

$ touch confapache/tasks/main.yml confapache/meta/main.yml

Résultat : répertoire mediawiki :

.
|-- commun
|   `-- defaults
|       `-- main.yml
|-- confapache
|   |-- meta
|   |   `-- main.yml
|   `-- tasks
|       `-- main.yml
`-- confdb
    |-- meta
    |   `-- main.yml
    `-- tasks
        `-- main.yml

Amélioration de l'inventaire en vue du déploiement

Je vais modifier le fichier inventaire.ini pour pouvoir séparer des deux nodes dans les deux groupes distincts. Cela permettra par la suite de s'adresser à un groupe au lieu de s'adresser directement aux nodes. Je pourais par la suite ajouter des nodes plus facilement en l'ajoutant le node dans le bon groupe puis dans le fichier inventaire.

commande : connexion sur le node manager (cjdebian) :

$ ssh user-ansible@node-manager

commande : Activation de l'environnement virtuel :

$ source ansible2.7.10/bin/activate

commande : Editer le fichier inventaire.ini :

$ vi inventaire.ini 

Résultat :

[apache]
http1
[db]
bbd1

Contrôle de l'exécution des opérations et enchaînement de plusieurs actions

Dans cette partie je vais construire les scriptes d'automatisation en complétant les fichier que j'avais créer “main.yml” se trouvant dans chaque rôle (si dessous). Ces scripts seront très utile car il permet d'exécuter des tâches et d'enchaîner plusieurs actions.

roles
|-- apache2
|   |-- handlers
|   |   `-- main.yml
|   `-- tasks
|       `-- main.yml
|-- mariadb
|   `-- tasks
|       `-- main.yml
`-- mediawiki
    |-- commun
    |   `-- defaults
    |       `-- main.yml
    |-- confapache
    |   |-- meta
    |   |   `-- main.yml
    |   `-- tasks
    |       `-- main.yml
    `-- confdb
        |-- meta
        |   `-- main.yml
        `-- tasks
            `-- main.yml

En regardent cette arborescence, je constate bien qu'il y a 5 rôles qui correspond à 9 fichier YAML décrivant les rôles :

  • apache2
  • mariadb
  • commun
  • confapache
  • confdb

script Apache2

J'utilise la commande suivante afin d'écrire dans le fichier main.yml de apache2.

$ nano roles/apache2/tasks/main.yml

Puis j'écrie les instruction suivante dans ce fichier :

---

#1. Cette t che permet d.installer Apache (httpd)   l.aide du module yum
- name: "apache2 installation"
  yum:
name: "httpd"
state: "present"

#2. Cette t che active le service Apache
- name: "apache2 service activation"
  service:
name: "httpd"
state: "started"
enabled: yes

#3. Cette t che fait appel   un autre fichier de configuration pour installer PHP. Elle est $
- name: "install php7 packages"
  include: "php7-install.yml"
  when: php_install|default(False)|bool

script PHP

Je vais également créer un fichier pour l'installation de PHP.

$ nano roles/apache/tasks/php7-install.yml

Et puis j'écrie les instruction suivante dans ce fichier :

---

#1. Cette tâche installe le dépôt  EPEL (Extra Packages for Enterprise Linux)
- name: "epel activation"
  yum:
name: "epel-release"
state: present

#2. Cette tâche installe le dépôt REMI pour bénéficier du paquet PHP7
- name: "remi repo activation"
  yum:
name: "https://rpms.remirepo.net/enterprise/remi-release-7.rpm"
state: present

#3. Cette tâche installe PHP7 et ses extensions
- name: "install php70 packages"
  yum:
name: "php,php-mysql,php-xml,php-mbstring,php-mcrypt,php-gd,php-intl"
state: latest
enablerepo: "remi-php70"
  changed_when: yes
  notify: [ "apache restart" ]

script MariaDB

J'utilise la commande suivante afin d'écrire dans le fichier main.yml de mariadb.

$ nano roles/mariadb/tasks/main.yml

Puis j'écrie les instruction suivante dans ce fichier :

---

# Installation des paquets mariadb serveur et son extension Python
- name: "mariadb-server installation"
  yum:
name:  "mariadb-server,MySQL-python"
state: "installed"

# Active le service MariaDB 
- name: "start mariadb service"
  service:
name:  "mariadb"
state: "started"
enabled: yes

Dans cette première tâche “mariadb-serveur installation” va installer mariadb sereur ainsi que son extension Python avec le module “yum”

script commun

J'utilise la commande suivante afin d'écrire dans le fichier main.yml de commun.

$ nano roles/mediawiki/commun/defaults/main.yml

Puis j'écrie les instruction suivante dans ce fichier :

---

# nom de la base de données
mediawiki_db_name: "mediawiki"

# nom de l’utilisateur de la base de données et son mot de passe
mediawiki_db_user: "mediawiki"
mediawiki_db_password: !vault |
       $ANSIBLE_VAULT;1.1;AES256      36663934633330396131376162363633666635376633313430616164303662633233303232353839      3932666230633632626434363734623537623463363631320a636662363032376563303163643366      37626237383534653035663335623233646364326365326565366361343835663030316533376664      6633376539663563310a386439653931623333316532326262343562326638313266343236346536
       3032

# nom et mot de passe de l’administrateur Mediawiki
mediawiki_admin_user: "admin"
mediawiki_admin_password: !vault |
       $ANSIBLE_VAULT;1.1;AES256      36663934633330396131376162363633666635376633313430616164303662633233303232353839      3932666230633632626434363734623537623463363631320a636662363032376563303163643366      37626237383534653035663335623233646364326365326565366361343835663030316533376664      6633376539663563310a386439653931623333316532326262343562326638313266343236346536
       3032

# nom du Mediawiki et son titre
mediawiki_name: "mediawiki"
mediawiki_title: "ELS"

# l’emplacement du répertoire d'installation de Mediawiki
mediawiki_directory: "/var/www/html/{{mediawiki_name}}"

# répertoire de maintenance de Mediawiki
mediawiki_maintenance_directory: "{{mediawiki_directory}}/maintenance"

# Definie le premier node du groupe mariadb
mediawiki_db_host: "{{groups.db.0}}"

# l’url des sources Mediawiki
mediawiki_archive_url: "https://releases.wikimedia.org/mediawiki/1.31/mediawiki-1.31.1.tar.gz"

Chiffrer les mots de passe

Afin de pouvoir utiliser mediawiki un mot de passe chiffrer serait plus sécuritaire.

commande : mot de passe chiffrer : “Ansible2021”

$ ansible-vault encrypt_string 'foobar' --name 'mediawiki_db_password'

Résultat :

mediawiki_db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          63306131326438653031306666323339353233383561623338323133663063326634333466316361
          6333313936613930626130353538383332663762336335610a373130383937613033633330646133
          37316236373665396338346366643562373730333635346564613834643066663762336663383063
          3137633562333061350a383139656463376637643432383833363236636566313262653163643564
          6664
Encryption successful

script confdb

Je vais commencer par déclarer une dépendance dans le répertoire meta pour pouvoir utiliser les variable enregistrées dans le rôle commun.

commande : écrire une dépendance :

$ nano roles/mediawiki/confdb/meta/main.yml

contenue à écrire :

dependencies:
  - role: "mediawiki/commun"

Puis je vais créer un nouveau répertoire afin d'écrire dans le fichier main.yml de confdb de code pour configurer mariadb pour mediawiki.

commande : écrire dans le fichier :

$ mkdir roles/mediawiki/mariadb/tasks/main.yml

commande : écrire dans le fichier main.yml

$ nano roles/mediawiki/mariadb/tasks/main.yml

contenue à écrire :

---

# Installation des paquets mariadb serveur et son extension Python
- name: "mariadb-server installation"
  yum:
name:  "mariadb-server,MySQL-python"
state: "installed"

# Active le service MariaDB 
- name: "start mariadb service"
  service:
name:  "mariadb"
state: "started"
enabled: yes

script confapache

Je vais commencer par déclarer une dépendance dans le répertoire meta pour pouvoir utiliser les variable enregistrées dans le rôle commun.

commande : écrire dans le fichier :

$ nano roles/mediawiki/confapache/meta/main.yml

contenue à écrire :

dependencies:
  - role: "mediawiki/commun"

commande : écrire dans le fichier

$ nano roles/mediawiki/confapache/tasks/main.yml

contenue à écrire :

---

#1. Création du repertoire pour l’installation des fichiers Mediawiki
- name: "mediawiki directory"
  file:
path: "{{mediawiki_directory}}"
owner: "apache"
group: "apache"
state: directory

#2. Décompresse le fichier source archive Mediawiki et le formate sans extension
- name: "uncompress mediawiki archive"
  unarchive:
src: "{{mediawiki_archive_url}}"
dest: "{{mediawiki_directory}}"
owner: "apache"
group: "apache"
remote_src: yes
# supprime mediawiki-1.xx.x/ du chemin
extra_opts: --transform=s/mediawiki-[0-9\.]*\///

#3. Exécute la tâche avec l'utilisateur apache, se place dans le répertoire de maintenance et exécute la commande de configuration si le fichier localsetting.php n’existe pas
- name: "mediawiki configuration"
  become: yes
  become_user: "apache"
  args:
   creates: "{{mediawiki_directory}}/LocalSettings.php"
   chdir: "{{mediawiki_maintenance_directory}}"
  command:
php install.php --scriptpath /{{mediawiki_name}}
    --dbname mediawiki --lang fr
    --dbuser {{mediawiki_db_user}}
    --dbpass {{mediawiki_db_password}}
    --pass {{mediawiki_admin_password}}
    --dbserver {{mediawiki_db_host}}  
    {{mediawiki_title}} {{mediawiki_admin_user}}
  run_once: yes
  delegate_to: "{{item}}"
  with_items: "{{groups.apache}}"

#4. Exécute la tâche avec l'utilisateur apache, se place dans le répertoire de maintenance et exécute la commande de mise à jour de la baseune seule fois    
- name: "mediawiki db update"
  become: yes
  become_user: "apache"
  command:
php update.php --quick
  args:
chdir: "{{mediawiki_maintenance_directory}}"
  # La mise à jour à besoin d'être lancée une seule fois
  run_once: yes
  register: resultat
  changed_when: "' ...done.' in resultat.stdout"

Assemblement des opération avec les playbooks afin d'automatiser le déploiement

——————————– déja installer

Création du playbook pour in installer apache

Afin de créer le playbook qui me permettra d'installer apache 2, je vais écrire dans le fichier suivant que je vais appeler “install-apache.yml” :

commande : écrire dans le fichier :

$ nano install-apache.yml

contenue du fichier :

---
- name: "Installation apache"
  hosts: http1
  roles:
    - role: "apache"
      php_install: yes

stage/turgot/btssn/2020/couderchon.jonathan/ansible.txt · Dernière modification: 2021/06/29 08:15 de couderchon.jonathan_educ-valadon-limoges.fr