March 26, 2019

Ansible : Automatiser la gestion de serveurs


Introduction



Ansible est un logiciel de déploiement/configuration à distance, créé par M. De Hann ( Redhat : Cobbler et Func) et est écrit en python. Il utilise seulement SSH et ne nécessite pas de serveur : une simple station de travail peut suffire. Il est bon de noter qu'il fonctionne en mode push (de Ansible vers le serveur cible). La machine hébergeant Ansible ne nécessite que python 2.4+, et Ansible est extensible en n'importe quel langage.

Cette solution est plutôt dédiée à un usage professionnel.


Installer Ansible



J'ai mis en œuvre Ansible sur  : CentOS7. 
Je décris ici l'installation.


CentOS



Il est nécessaire d'installer les dépôts EPEL.

Ensuite, installer Ansible via

Code BASH :
yum install ansible

Préparer le terrain




Configurer le "serveur" Ansible



Sur la machine qui possède Ansible, configurer le fichier /etc/hosts avec le nom des hôtes :

Code BASH :

infra ~ # cat /etc/hosts
127.0.0.1       localhost.localdomain localhost
10.21.27.11     cluster1.adrien.lan cluster1
10.21.27.12     cluster2.adrien.lan cluster2
10.21.27.125    rhelsrv1
10.21.27.127    rhelsrv2
10.21.27.130    debsrv1
10.21.27.121    debsrv2
 

Partie SSH

On génère ensuite une paire de clés SSH :

Code BASH :

infra ~ # ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
d8:de:8e:f9:a4:44:07:a7:ec:dc:ed:81:10:ef:1e:b8 root@rhelsrv1
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|        o .      |
|       + *       |
|      . S o      |
|       = B o     |
|        * B o    |
|       . O o .   |
|        E.+ .    |
+-----------------+


Puis on copie notre clé sur chaque serveur :

Code BASH :
infra ~ # ssh-copy-id rhelsrv1
infra ~ # ssh-copy-id rhelsrv2
infra ~ # ssh-copy-id cluster1
infra ~ # ssh-copy-id cluster2
infra ~ # ssh-copy-id debsrv1
infra ~ # ssh-copy-id debsrv2
 


On peut vérifier le bon fonctionnement en se connectant à chacune des machines...


Configuration des hôtes Ansible



Pour plus de facilité, je me rend dans le dossier ansible :

Code BASH :

infra ~ # cd /etc/ansible

Tout se passe dans le fichier /etc/ansible/hosts. On édite le fichier. Voici un exemple :

Code BASH :

[rhel]
rhelsrv1
rhelsrv2
[cluster]
cluster1
cluster2
[sambaservers]
debsrv1
debsrv2
 

Entre crochet, on trouve les groupes d'hôtes, avec les hôtes concernés en dessous.
Ici, j'ai donc 3 groupes, un rhel avec les hôtes rhelsrv1 et rhelsrv2 et le groupe cluster avec cluster1 et cluster2 etc...

Il est tout à fait possible d'avoir Ansible installé sur une machine Calculate Linux, et d'installer des paquets sur une distribution Linux autre (CentOS, Debian ...)


Utiliser Ansible



Ansible s'articule autour de modules.
Plus d'infos sur les modules : http://docs.ansible.com/list_of_all_modules.html

Tester la communication



Pour tester la communication, on peut utiliser le module ping d'Ansible :

Code BASH :
ansible -m ping all


all ici signifie tous les hôtes :

Code BASH :
 
cluster1 | success >> {
    "changed": false, 
    "ping": "pong"
}
cluster2 | success >> {
    "changed": false, 
    "ping": "pong"
}
rhelsrv2 | success >> {
    "changed": false, 
    "ping": "pong"
}
rhelsrv1 | success >> {
    "changed": false, 
    "ping": "pong"
}
debsrv2 | success >> {
    "changed": false,
    "ping": "pong"
}
debsrv1 | success >> {
    "changed": false,
    "ping": "pong"
}
 



En mode "on-liner"



Pour tester le bon fonctionnement, on va installer htop sur rhelsrv2 en utilisant le module yum

Code BASH :
ansible -m yum -a 'name=htop state=present' rhelsrv2


La console affiche l'état des opérations :

Code BASH :
rhelsrv2 | success >> {
    "changed": true,
    "msg": "warning: /var/cache/yum/x86_64/7/epel/packages/htop-1.0.3-3.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY\nImporting GPG key 0x352C64E5:\n Userid     : \"Fedora EPEL (7) <epel@fedoraproject.org>\"\n Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5\n Package    : epel-release-7-2.noarch (@extras)\n From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7\n",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\n * base: mirror.ate.info\n * epel: epel.mirrors.ovh.net\n * extras: mirror.ate.info\n * updates: mirror.skylink-datacenter.de\nResolving Dependencies\n--> Running transaction check\n---> Package htop.x86_64 0:1.0.3-3.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package         Arch              Version                Repository       Size\n================================================================================\nInstalling:\n htop            x86_64            1.0.3-3.el7            epel             87 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 87 k\nInstalled size: 181 k\nDownloading packages:\nPublic key for htop-1.0.3-3.el7.x86_64.rpm is not installed\nRetrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : htop-1.0.3-3.el7.x86_64                                      1/1 \n  Verifying  : htop-1.0.3-3.el7.x86_64                                      1/1 \n\nInstalled:\n  htop.x86_64 0:1.0.3-3.el7                                                     \n\nComplete!\n"
    ]
}


On peut aussi tester sur Calculate Linux en installant aussi htop sur les 2 machines du groupe cluster en utilisant le module portage:

Code BASH :
ansible -m portage -a 'name=htop state=present' cluster


La console affiche moins de choses, puisque les paquets sont déjà installés :

Code BASH :
cluster1 | success >> {
    "changed": false,
    "msg": "Packages already present."
}
cluster2 | success >> {
    "changed": false,
    "msg": "Packages already present."
}


Et un test sur debian, avec le module apt :

Code BASH :
ansible -m apt -a 'name=htop' debsrv1


Code BASH :
debsrv1 | success >> {
    "changed": true,
    "stderr": "",
    "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nSuggested packages:\n  strace ltrace\nThe following NEW packages will be installed:\n  htop\n0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.\nNeed to get 74.9 kB of archives.\nAfter this operation, 216 kB of additional disk space will be used.\nGet:1 http://ftp.fr.debian.org/debian/ wheezy/main htop amd64 1.0.1-1 [74.9 kB]\nFetched 74.9 kB in 0s (286 kB/s)\nSelecting previously unselected package htop.\r\n(Reading database ... \r(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r(Reading database ... 70%\r(Reading database ... 75%\r(Reading database ... 80%\r(Reading database ... 85%\r(Reading database ... 90%\r(Reading database ... 95%\r(Reading database ... 100%\r(Reading database ... 40200 files and directories currently installed.)\r\nUnpacking htop (from .../htop_1.0.1-1_amd64.deb) ...\r\nProcessing triggers for menu ...\r\nProcessing triggers for man-db ...\r\nSetting up htop (1.0.1-1) ...\r\nProcessing triggers for menu ...\r\n"
}
 


Par exemple, pour mettre à jour les serveurs rhel :

Code BASH :
ansible -m yum -a 'name=* state=latest' rhel



Utiliser les playbooks



Un playbook est une sorte de mégascript qui va automatiser des tâches de manière séquentielle. 

Globalement, un playbook est composé de tâches comme ceci : 

Code BASH :
- name: Texte qui décris votre tâche
  module: option=value



Un exemple simple



Voici une illustration avec un playbook "test" pour installer htop sous Calculate Linux :

Code BASH :
# htop.yml
---
- hosts: cluster
  tasks:
    - name: 1. install htop
      portage: name=htop state=present


Ici, je vise les hôtes du groupe cluster, et le playbook ne comporte qu'une seule tâche.

On lance le playbook via la commande 

Code BASH :
ansible-playbook htop.yml


Code BASH :
 
PLAY [cluster] **************************************************************** 
GATHERING FACTS *************************************************************** 
ok: [cluster2]
ok: [cluster1]
TASK: [1. install htop] ******************************************************* 
changed: [cluster1]
changed: [cluster2]
PLAY RECAP ******************************************************************** 
cluster1                   : ok=2    changed=1    unreachable=0    failed=0   
cluster2                   : ok=2    changed=1    unreachable=0    failed=0   
 


Une autre expérience intéressante consiste à relancer l’exécution du playbook

Code BASH :
 
PLAY [cluster] **************************************************************** 
GATHERING FACTS *************************************************************** 
ok: [cluster2]
ok: [cluster1]
TASK: [1. install htop] ******************************************************* 
ok: [cluster1]
ok: [cluster2]
PLAY RECAP ******************************************************************** 
cluster1                   : ok=2    changed=0    unreachable=0    failed=0   
cluster2                   : ok=2    changed=0    unreachable=0    failed=0  


Tout devrait aller beaucoup plus vite, et à la place de "changed" après chaque instruction, on lit "ok".
Ce qui veut dire qu’un playbook est plus intelligent qu’un bête script, et ne se contente pas d’exécuter des instructions.
Ansible va garantir quel tel service soit bien actif et qu’il utilise bien le dernier fichier de conf. Ce qui en fait l’outil parfait pour tester vos systèmes automatiquement.

Installer LAMP, sous CentOS



Ci-dessous, un playbook que j'ai réalisé, pour installer LAMP sur CentOS.
A noter l'apparition d'une nouvelle section nommée handlers. Cette section permet notamment de déclarer les éventuelles notifications.
Ici, cela correspond à l'étape 7, étape notify, restart httpd
Et pour pimenter les choses, l'étape 3 installe plusieurs paquets d'un coup.

Code BASH :
# lamp-centos.yml
---
- hosts: rhel
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted
  tasks:
    - name: 1. Installation Apache
      yum: name=httpd state=present
    - name: 2. Installation PHP
      yum: name=php state=present
    - name: 3. Installation extensions PHP
      yum: name={{item}} state=present
      with_items:
       - php-pdo
       - php-mysql
       - php-soap
       - php-gd
       - php-pear-MDB2-Driver-mysqli
    - name: 4. Installation de MariaDB
      yum: name=mariadb-server
    - name: 5. Démarrage Apache
      service: name=httpd state=running enabled=yes
    - name: 6. Démarrage MariaDB
      service: name=mariadb state=running enabled=yes
    - name: 7. Installation index
      copy: src=lamp-centos.yml.index.php dest=/var/www/html/index.php
      notify:
        - restart httpd
    - name: 8. Ajout de la règle de pare-feu
      action: command /usr/bin/firewall-cmd --permanent --add-port=80/tcp
    - name: 9. Redémarrer le pare-feu
      service: name=firewalld state=restarted


  1. Installation d'un paquet.
  2. Installation d'un paquet.
  3. Illustration de l'installation de plusieurs paquets dans une même tâche.
  4. Installation d'un paquet.
  5. Vérification d'un service sur la position "démarré"
  6. Vérification d'un service sur la position "démarré"
  7. Copier Coller d'un fichier du "serveur Ansible" vers le serveur cible. Avec une fois l'opération effectuée un redémarrage du service.
  8. Exécution d'une commande sur la machine cible
  9. Redémarrage d'un service.


Ce playbook est donc bien complet.

Voici une illustration d'exécution du playbook :

Code BASH :
infra ansible# ansible-playbook lamp-centos.yml
PLAY [rhel] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [rhelsrv1]
ok: [rhelsrv2]
TASK: [1. Installation Apache] ************************************************
changed: [rhelsrv1]
changed: [rhelsrv2]
TASK: [2. Installation PHP] ***************************************************
changed: [rhelsrv1]
changed: [rhelsrv2]
TASK: [3. Installation extensions PHP] ****************************************
changed: [rhelsrv2] => (item=php-pdo,php-mysql,php-soap,php-gd,php-pear-MDB2-Driver-mysqli)
changed: [rhelsrv1] => (item=php-pdo,php-mysql,php-soap,php-gd,php-pear-MDB2-Driver-mysqli)
TASK: [4. Installation de MariaDB] ********************************************
changed: [rhelsrv1]
changed: [rhelsrv2]
TASK: [5. Démarrage Apache] ***************************************************
changed: [rhelsrv2]
changed: [rhelsrv1]
TASK: [6. Démarrage MariaDB] **************************************************
changed: [rhelsrv1]
changed: [rhelsrv2]
TASK: [7. Installation index] *************************************************
changed: [rhelsrv1]
changed: [rhelsrv2]
TASK: [8. Ajout de la règle de pare-feu] **************************************
changed: [rhelsrv2]
changed: [rhelsrv1]
TASK: [9. Redémarrer le pare-feu] *********************************************
changed: [rhelsrv2]
changed: [rhelsrv1]
NOTIFIED: [restart httpd] *****************************************************
changed: [rhelsrv2]
changed: [rhelsrv1]
PLAY RECAP ********************************************************************
rhelsrv1                   : ok=11    changed=10    unreachable=0    failed=0
rhelsrv2                   : ok=11    changed=10    unreachable=0    failed=0
 





Installer et Configurer SAMBA, sous Debian



Cette fois-ci un playbook d'installation de SAMBA sur deux Debian.
A noter qu'il est déjà installé et configuré sur un des deux serveurs; comme le montrera l'exécution du playbook.

Le playbook : samba-debian.yml

Code BASH :
# samba-debian.yml
---
- hosts: sambaservers
  handlers:
    - name: restart samba
      service: name=samba state=restarted
  tasks:
    - name: 1. Installer samba
      apt: name=samba state=present
    - name: 2. Démarrer service samba
      service: name=samba state=running enabled=yes
    - name: 3. Création du dossier public
      command: mkdir -p /srv/samba/commun
    - name: 4. Correction des droits
      file: path=/srv/samba/commun owner=root group=users mode=0777
    - name: 5. Modification du fichier smb.conf
      lineinfile: dest=/etc/samba/smb.conf backup=yes line="include /etc/samba/smb.conf.ansible"
    - name: 6 Copier le fichier personnalisé de samba
      copy: src=samba-debian.yml.smb.conf.ansible dest=/etc/samba/smb.conf.ansible
      notify:
        - restart samba
 


Le fichier samba-debian.yml.smb.conf.ansible

Code BASH :
[commun]
        comment = Partage de fichiers commun
        browseable = yes
        public = yes
        path = /srv/samba/commun
        writable = yes


On exécute ensuite le playbook :

Code BASH :
infra ansible # ansible-playbook samba-debian.yml


La console affiche :

Code BASH :
 
PLAY [sambaservers] ***********************************************************
GATHERING FACTS ***************************************************************
ok: [debsrv1]
ok: [debsrv2]
TASK: [1. Installer samba] ****************************************************
ok: [debsrv1]
changed: [debsrv2]
TASK: [2. Démarrer service samba] *********************************************
ok: [debsrv1]
ok: [debsrv2]
TASK: [3. Création du dossier public] *****************************************
changed: [debsrv1]
changed: [debsrv2]
TASK: [4. Correction des droits] **********************************************
ok: [debsrv1]
ok: [debsrv2]
TASK: [5. Modification du fichier smb.conf] ***********************************
ok: [debsrv1]
changed: [debsrv2]
TASK: [6 Copier le fichier personnalisé de samba] *****************************
ok: [debsrv1]
changed: [debsrv2]
NOTIFIED: [restart samba] *****************************************************
changed: [debsrv2]
PLAY RECAP ********************************************************************
debsrv1                    : ok=7    changed=1    unreachable=0    failed=0
debsrv2                    : ok=8    changed=5    unreachable=0    failed=0
 


  1. Installation d'un paquet.
  2. Démarrage d'un service.
  3. Exécution d'une commande.
  4. Modification de droits.
  5. Ajout d'une ligne dans un fichier.
  6. Copie de fichier + notification

On voit bien dans le dernier point que le NOTIFIED ne s'applique qu'aux hôtes dont un changement a eu lieu...


No comments:

Post a Comment

How to Install Docker CE on CentOS 8 and RHEL 8

  Docker  is a daemon-based container engine which allows us to deploy applications inside containers.  Docker is available in two versions,...