Tuto Ansible

Introduction : le but du tuto

Le but de ce tutoriel est de s'acculturer à ansible en réalisant le provisionning d'un cluster de 4 serveurs représentant une architecture 3 tiers classique :

  • un serveur web
  • deux serveurs d'applications
  • un serveur de base de données

 

Ce tutoriel peut être effectué en autonomie sur une machine (VM par exemple) executant docker et ansible via l'utilisation de 4 containers docker représentant ces 4 serveurs (on utilise docker ici uniquement comme facilitateur pour évite de nécessiter 4 serveurs distant)

ETAPE 1 : setup de 4 conteneurs pour réaliser le tuto :

Démarrer 4 conteneurs Docker pour les 4 machines utilisées pour le tuto :

ssh-keygen
ssh-copy-id -i /home/vagrant/.ssh/id_rsa.pub -p 6122 root@webserver1
ssh-copy-id -i /home/vagrant/.ssh/id_rsa.pub -p 6222 root@tomcat1
ssh-copy-id -i /home/vagrant/.ssh/id_rsa.pub -p 6322 root@tomcat2
ssh-copy-id -i /home/vagrant/.ssh/id_rsa.pub -p 6422 root@database1

Générer une clé SSH et la copier sur tous les serveurs (le mdp est root):

docker run -d -p 6122:22 loicmathieu/sftp
docker run -d -p 6222:22 loicmathieu/sftp
docker run -d -p 6322:22 loicmathieu/sftp
docker run -d -p 6422:22 loicmathieu/sftp

Ajouter des alias vers les conteneurs docker : remplacer la première ligne du /etc/hosts par la suivante :

sudo vi /etc/hosts
127.0.0.1 localhost webserver1 tomcat1 tomcat2 database1

Créer la définition des hosts dans le fichier des hosts d'ansible, ici on définit trois groupes d'host (entre []) : webserver, appserver, database qui nous servirons ensuite au lieu de directement nommer les serveurs.

ETAPE 2 : Définition de l'inventaire des serveurs (des conteneurs ici) dans Ansible

sudo vi /etc/ansible/hosts
[webserver]
webserver1 ansible_ssh_user=root ansible_ssh_port=6122

[appserver]
tomcat1 ansible_ssh_user=root ansible_ssh_port=6222
tomcat2 ansible_ssh_user=root ansible_ssh_port=6322

[database]
database1 ansible_ssh_user=root ansible_ssh_port=6422

Vérifier que tout est OK en utilisant le module ping de la commande ansible pour tous les hosts :
 

ansible all -m ping

la commande ansible permet d'executer un module (ici ping) sur les hosts (ici tous) de l'inventaire

ETAPE 3 : Création du rôle nginx

Tout d'abord, initialiser dans le répertoire vagrant les répertoires suivants :

vagrant@vagrant-ubuntu-trusty-64:/vagrant$ mkdir ansible
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ mkdir ansible/roles
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ mkdir ansible/roles/nginx
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ mkdir ansible/roles/nginx/tasks

Nous allons ensuite  définir la tâche qui permettera d'installer un serveur Nginx en créant le fichier roles/nginx/tasks/main.yml :

---
  - name: Install EPEL repository where nginx packages lies.
    yum: name=epel-release state=latest

  - name: Install nginx webserver
    yum: name=nginx state=latest

Le fichier main.yml contient un ensemble de tâche nommée. Chaque tâche est implémentée via un module (ici yum)

ETAPE 4 : Création du playbook webserver

---
- hosts: webserver

  roles:
    - nginx

  environment:
    http_proxy: http://gateway.zscaler.net:9401
    https_proxy: http://gateway.zscaler.net:9401

ansible-playbook webserver_install.yml

Créer dans le répertoire ansible un playbook pour l'installation du webserver : webserver_install.yml

Lancer le playbook via la commande suivante :

Relancer la commande, on constate qu'Ansible ne réalise pas l'installation une deuxième fois!

Un playbook lie un groupe d'host à un ensemble de rôles. C'est la commande ansible-playbook qui permet de l'executer.

ETAPE 5 : création du rôle tomcat

mkdir roles/tomcat
mkdir roles/tomcat/tasks

Tout d'abord, il faut créer l'arborescence nécessaire au nouveau rôle : 

Ensuite il faut créer le fichier de role roles/tomcat/tasks/main.yml

---

  - name: Install Java
    yum: name=java-1.8.0-openjdk-devel state=latest

  - name: Download latest Tomcat version
    get_url: url=http://apache.mindstudios.com/tomcat/tomcat-8/v8.5.11/bin/apache-tomcat-8.5.11.tar.gz 
             dest=/tmp

  - name: Create the destination dir
    file: name=/opt/tomcat state=directory

  - name: Un-tar
    unarchive: src=/tmp/apache-tomcat-8.5.11.tar.gz dest=/opt/tomcat copy=no

  - name: Delete previously downloaded file
    file: name=/tmp/apache-tomcat-8.5.11.tar.gz state=absent

ETAPE 6 : création du playbook appserver

Créer dans le répertoire ansible un playbook pour l'installation de l'appserver: appserver_install.yml

---
- hosts: appserver

  roles:
    - tomcat

  environment:
    http_proxy: http://gateway.zscaler.net:9401
    https_proxy: http://gateway.zscaler.net:9401

Ici, la configuration du proxy est dupliqué avec le playbook précédent, on va donc externaliser ça dans un fichier de variable : group_vars/all

---
httpProxy: http://gateway.zscaler.net:9401
httpsProxy: http://gateway.zscaler.net:9401

On va ensuite remplacer la valeur du proxy par le nom de la variable entre moustache ({{}}) => c'est le templating Jinja2

ETAPE 6 : création du playbook appserver

Le fichier appserver_install.yml va alors ressembler à ça

---
- hosts: appserver

  roles:
    - tomcat

  environment:
    http_proxy: "{{ httpProxy }}"
    https_proxy: "{{ httpsProxy }}"

Vous pouvez en profiter pour modifier votre fichier webserver_install.yml pour qu'il utilise aussi ces variables

Lancer le playbook via la commande suivante :

ansible-playbook appserver_install.yml

group_vars/all est le fichier globale des variables. On peut aussi définir un fichier de variable par rôle (<rôle_dir>/vars/main.yml)

L'execution est en parallèle!

ETAPE 7 : création du rôle derby

Tout d'abord, il faut créer l'arborescence nécessaire au nouveau rôle : 

mkdir roles/derby
mkdir roles/derby/tasks

Ensuite il faut créer le fichier de rôle roles/derby/tasks/main.yml

---

  - name: Install Java
    yum: name=java-1.8.0-openjdk-devel state=latest

  - name: Download latest Derby version
    get_url: url=http://mirrors.standaloneinstaller.com/apache/db/derby/db-derby-10.13.1.1
             /db-derby-10.13.1.1-bin.tar.gz
             dest=/tmp

  - name: Create the destination dir
    file: name=/opt/derby state=directory

  - name: Un-tar
    unarchive: src=/tmp/db-derby-10.13.1.1-bin.tar.gz dest=/opt/derby copy=no

  - name: Delete previously downloaded file
    file: name=/tmp/db-derby-10.13.1.1-bin.tar.gz state=absent

Attention à remettre sur une seule ligne l'URL de récupération de Derby.

ETAPE 7 : création du rôle derby

Ici on constate que l'instalation de java est dupliqué entre les deux rôles tomcat et derby! On va l'externaliser dans un rôle java.

mkdir roles/java
mkdir roles/java/tasks

On va alors créer le fichier roles/java/tasks/main.yml avec le contenu suivant :

---

  - name: Install Java
    yum: name=java-1.8.0-openjdk-devel state=latest

Puis supprimer l'étape d'installation de Java du rôle database

ETAPE 8 : création du playbook database

Créer dans le répertoire ansible un playbook pour l'installation de l'appserver: database_install.yml

---
- hosts: database

  roles:
    - java
    - derby

  environment:
    http_proxy: "{{ httpProxy }}"
    https_proxy: "{{ httpsProxy }}"

Vous pouvez en profiter pour modifier votre fichier appserver_install.yml pour qu'il utilise le rôle java et supprimer l'installation de java du rôle tomcat

Lancer le playbook via la commande suivante :

ansible-playbook database_install.yml

Ce playbook va donc définir 2 rôles pour le groupe d'host database : java et derby

ETAPE 9 : template, include, ...

On va ensuite créer un script de démarrage de Derby via un fichier template (Jinja2) start.sh que l'on mettera dans le répertoire roles/derby/templates

echo "starting derby server on host {{ ansible_nodename }}"
nohup java -jar /opt/derby/db-derby-10.13.1.1-bin/lib/derbyrun.jar server start &

Ici, on utilise la syntaxe moustache pour inclure une variable système d'ansible (un fact) qui est le nom de la machine.

On va ensuite créer une sous-tâche de démarrage de derby dans le fichier roles/derby/tasks/start_db.yml

---
  - name: Copy the start script
    copy: src=roles/derby/templates/start.sh dest=/var/run/start.sh

  - name: Set exec mod on the script
    file: path=/var/run/start.sh mode=755

  - name: Launch the start script
    shell: /var/run/start.sh >> /var/log/start.log

Pour utiliser cette sous-tâche, on va l'inclure dans le fichier main.yml du rôle database (à la fin) :

ETAPE 9 : template, include, ...

- include: start_db.yml

Puis, relancer le playbook et ... voila !

Pour aller plus loin, la documentation d'Ansible contient la liste de tous les modules inclus par défaut : http://docs.ansible.com/ansible/modules_by_category.html

Les sources sont dispo ici, il y a un tag (STEP_X) par etape principale du tuto : https://github.com/loicmathieu/ansible-tuto

Tuto Ansible

By loicmathieu