Apprendre Ansible


Cette outil est comme un moteur d'orchestration où sur le serveur maître on définit des recettes qui seront appliqué à ses nodes.

Ressources

Installation sur le client

Via paquet Debian

sudo echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" > /etc/apt/sources.list.d/ansible.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
sudo apt-get update && apt-get install ansible python-keyczar

Ainsi on obtient:

ansible --version
2.2.1.0

Via Pip

sudo apt install python3-pip python3-dev libssl-dev
pip3 install setuptools ansible
echo 'export PATH=$PATH:~/.local/bin/' >> ~/.bashrc

Ainsi on obtient:

ansible --version
ansible 2.7.8

Installation sur les serveurs

Les paquet(s) sont un requis :

apt install python-apt

Déclarer ses serveurs

Créons une paire de clés qui va permettre de communiquer avec nos nœuds sans avoir besoin d'authentification :

ssh-keygen -N "" -f $HOME/.ssh/id_rsa
ssh-copy-id IP2mon-serveur

Ces nœuds doivent être déclaré sous forme d'alias. Cela permet d’exécuter une ou plusieurs commandes à un groupe de serveurs qui sont renseigné dans le fichier suivant:

nano /etc/ansible/hosts
[edu]
10.10.64.70
un_hostname ansible_port=5555 ansible_host=10.10.64.101

[tel]
192.168.42.87
192.168.42.111

On peut vérifier que tout fonctionne comme ceci :

ansible tel -m ping
192.168.42.111 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.42.87 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

On peut maintenant lancer des commandes via l'intermédiaire des modules. Admettons que l'on veut avoir des informations sur un fichier :

ansible edu -m stat -a "path=/etc/passwd"
xmg | SUCCESS => {
    "changed": false, 
    "stat": {
        "atime": 1499368621.679515,
        ...
        "xusr": false
    }
}
  • Tester son mot de passe sudo grâce à l'option -b (–become) et -K (–ask-become-pass)
ansible -bK --one-line -m ping "machines*"

Configuration

nano /home/user/.ansible.cfg
[defaults]
roles_path = ~/GIT/ansible-roles/
retry_files_enabled = False
inventory = $HOME/.ansible/hosts

[ssh_connection]
#ssh_args = -o ControlMaster=no -o ControlPersist=no
ssh_args = -o ControlMaster=auto -o ControlPersist=300s
pipelining = True

#[persistent_connection]
#connect_retry_timeout = 60

Créer un playbook

Admettons que l'on souhaite installer un serveur Apache sur plusieurs groupes de machines dont celles déclarés plus haut appartenant au groupe tel et edu. Pour répondre à ce besoin, on rédige un playbook:

nano /etc/ansible/roles/apache.yml
apache.yml
- hosts: [tel,edu]
 
  tasks:
  - name: install apache2
    apt: name=apache2
 
  - name: reload apache2
    service: name=apache2 state=restarted

Vérifions que la syntaxe soit bien employé :

ansible-playbook --syntax-check apache.yml

Il s'exécute ensuite ainsi :

ansible-playbook site.yml

On obtient ce type de résultat :

PLAY [tel,edu] *****************************************************************

TASK [setup] *******************************************************************
ok: [192.168.42.111]
ok: [192.168.42.87]
fatal: [10.10.64.101]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect [...]", "unreachable": true}
fatal: [10.10.64.70]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect [...]", "unreachable": true}

TASK [install apache] **********************************************************
ok: [192.168.42.111]
ok: [192.168.42.87]

TASK [reload apache2] **********************************
ok: [192.168.42.87]
ok: [192.168.42.111]
        to retry, use: --limit @/etc/ansible/web.retry

PLAY RECAP *********************************************************************
10.10.64.101               : ok=0    changed=0    unreachable=1    failed=0   
10.10.64.70                : ok=0    changed=0    unreachable=1    failed=0   
192.168.42.111             : ok=3    changed=0    unreachable=0    failed=0   
192.168.42.87              : ok=3    changed=0    unreachable=0    failed=0 

On peut remarquer qu'il y a deux machines non disponible sur le réseau (elle appartienne au groupe edu) et les deux autres machines disponibles ont bien reçu les instructions qui étaient déjà réalisées vu qu'elles sont dans l'état “ok”.

Lorsque l'on exécute cette commande, Ansibe lit dans un premier temps les configurations à appliquer, contacte ensuite les serveurs pour prendre en compte leurs disponibilités puis exécute les tâches à exécuter avec le compte root vu que l'on a échangé les clés avec cet utilisateur. La dernière étape est un récapitulatif des changements.

Vérifier ce qui va être lancé

Dans certains cas, on a besoin de lancer plusieurs playbooks sur plusieurs machines. Voici comment être sur de savoir ce que l'on fait exactement :

ansible-playbook -i inventory-preprod config.*-webapp.yml -K --diff

Syntaxes disponibles

J'expose ci-dessous les syntaxes que l'on peut souvent rencontrer lorsque l'on créer un playbook.

exemples.yml
- hosts: [tel,edu]
  vars:
    retour: ""
  tasks:
  - name: "packages are installed"
    apt: name='{{ item }}'
  with_items:
    - apache2-mpm-itk
    - apachetop
    - libapache2-mod-evasive
    - libwww-perl
 
   - name: "copier la config d'apache"
     copy: src=config.cfg dest=/etc/apache2/conf-available/ owner=root group=root mode="640"
 
# Ceci est un commentaire
   - name: "Arret des machines Debian et Ubuntu parmis les autres systèmes"
     command: /sbin/shutdown -t now
     when: (ansible_os_family == "Debian") or (ansible_os_family == "Ubuntu")
 
   - name: use epoll
     lineinfile:
       dest: /etc/nginx/nginx.conf
       regexp: '^(\s*use)\s+.+;'
       line: '    use epoll;'
       insertafter: 'events \{'
 
   - name : insérer une chaine dans un fichier 
     copy: content="your config line here" dest="/path/to/file"
 
 
 
  - name: fichier vpasswd is present?
    stat:
      path: /etc/proftpd/vpasswd
    register: file_is_present
 
  - name: debug
    debug:
      var: ansible_user
 
  - debug: var=ansible_facts

On peut lancer la commande de cette manière :

ansible-playbook exemples.yml --extra-vars retour="an2"

Commandes

  • Lancer une commande sur un ensemble de serveurs :
ansible groupe-serveur -bK --one-line --forks 42 -m command --args 'date'
  • Lancer un playbook sans se servir d'un inventaire :
ansible-playbook install-mysql.yml -K -i nom-machine, --diff 

Options

Options ansible les plus communes :

Commande Usage
–one-line tout mettre sur une seule ligne
-e 'ansible_python_interpreter=/usr/bin/python3' Variables additionnelles

Notes

  • S'assurer qu'une ligne est présente dans un fichier de configuration

- name: evocheck custom config

lineinfile:
  dest: /etc/evocheck.cf
  regexp: "^{{ item.key }}="
  line: "{{ item.key }}={{ item.value }}"
with_items:
  - { key: "IS_USRRO", value: "0" }
  • Vérifier si des paquets sont installé
- name: On récupère la liste des paquets installé
  ansible.builtin.package_facts:
    manager: auto
 
- name: Sinon, on vérifie si la dépendance suivante est présente
  ansible.builtin.apt:
    name:
      - sqlite3
    state: present
  when:
    - tache_cron.stat.exists is false
    -  "'fail2ban' in ansible_facts.packages"
  • Lister les machines qui ont un fichier
ansible "client*" -m command -a "test -s /etc/apt/trusted.gpg"