Pour débuter
Outils de base
VIM
06 min
SSH
14 min
rsync
20 min
Shell fish
13 min
Serveur HTTP
Apache
40 min
Nginx
30 min
PHP
NodeJS
Base de données
MySQL
15 min
Redis
08 min
Emails
HTTPS
FTP
ProFTPD
14 min
Sécurité
Pour le confort
Déploiement

Mettre en place un serveur manuellement peut rapidement s'avérer pénible, surtout si vous avez plusieurs machines à configurer de la même manière. Pas mal de personnes se sont penchées sur cette problématique et proposent des solutions pour automatiser le déploiement. Je vous propose de découvrir l'une d'entre elles aujourd'hui : Ansible.

Ansible permet de décrire la configuration a appliquer à nos différents serveurs au travers de recettes écrites en YAML. Ces recettes contiennent une série de taches qui seront lancées les unes après les autres. Les taches utilisent des modules internes à Ansible qui permettent de décrire les opérations à effectuer et les conditions de lancement.

Notre première tache

Pour cet exemple on va chercher à installer git sur nos serveurs. On commence d'abord par écrire un fichier hosts qui va contenir la liste de nos serveurs.

[web]
192.168.33.10

Ici on précise que l'on a un groupe "web" qui contient un seul serveur. On peut définir plusieurs groupe afin de séparer les serveurs suivant la configuration à y effectuer (si on a des serveurs pour la base de données et des serveurs pour le serveur web par exemple).
Ensuite nous allons créer un fichier YAML qui va permettre de décrire notre recette :

---
- name: Installation des serveurs web
  hosts: web
  remote_user: root
  tasks: 
    - name: Installation de Git
       apt: name=git state=latest
...

Le module APT permet d'utiliser la commande apt afin d'installer différents packages sur votre serveur. L'avantage est qu'Ansible n'effectuera pas cette tâche à chaque fois. La seconde fois que vous lancerez le déploiement, il détectera que Git est déjà installé et ne fera rien.

Enfin pour lancer le déploiement :

ansible-playbook -i hosts playbook.yml

Les rôles

Afin de mieux organiser nos taches, on peut les séparer dans des rôles afin de pouvoir les réutiliser plus simplement.

roles
 |-- <nom du role>
           |--- tasks
                  |--- main.yml
                  |--- installation.yml 
                  |--- configuration.yml 
           |--- handlers
                  |--- main.yml
           |--- defaults
                  |--- main.yml
  • Le dossier tasks va contenir les taches, le fichier main.yml sera chargé par défaut et peut inclure d'autres fichiers de taches via un include.
  • Le dossier handlers va contenir des taches à effectuer lors de la réussite d'autres taches (comme le redémarrage d'nginx par exemple).
  • Le dossier defaults va contenir les variable par défaut pour ce role. Ces variables peuvent être modifiées dans le playbook qui chargera ce role.

Les handlers

Les handlers permettent de gérer des taches qui doivent être effectuées en cas de changement d'une tache précédente. Par exemple lors de l'installation d'nginx on souhaite supprimer la configuration par défaut. Suite à cette suppression on doit notifier nginx pour qu'il recharge notre configuration. On va ainsi commencer par créer un handler pour gérer le rechargement d'nginx :

# handlers/main.yml
---
- name: nginx reload
  service: name=nginx state=reloaded

Ensuite dans notre série de tache nginx :

---
- name: Install
  apt: name=nginx state=latest

- name: Start
  service: name=nginx state=started enabled=true

- name: Supprimer default.conf
  file: path=/etc/nginx/sites-enabled/default state=absent
  notify: nginx reload

Les variables

Une configuration doit s'adapter suivant les besoins ! Pour cela on peut définir des variables que l'on pourra utiliser dans nos recette. Par exemple on va paramétrer la timezone à utiliser pour php. Dans notre fichier defaults/main.yml ou dans la partie vars de notres playbook :

php_timezone: Europe/Paris

On peut alors injecter cette variable dans notre tache

- lineinfile: dest=/etc/php/7.0/fpm/php.ini regexp='date.timezone[\s]?=' line='date.timezone = {{ php_timezone }}'

On peut aussi utiliser des listes

php_packages:
  - php7.0
  - php7.0-common
  - php7.0-cli
  - php7.0-intl
  - php7.0-curl
  - php7.0-cgi
  - php7.0-fpm
  - php7.0-mcrypt
  - php7.0-mysql
  - php7.0-gd
# Que l'on utilisera Ensuite
- name: Installation du package {{ item }}
  apt: name={{ item }} state=latest
  with_items: php_packages

Les templates

Ces variables peuvent aussi être utilisé dans des templates. Par exemple on souhaite créer une configuration nginx modulable :

server{
  server_name www.{{ item.domain }};
  return 301 $scheme://{{ item.domain }}$request_uri;
}

server{
  server_name {{ item.domain }};
  root /var/www/{{ item.domain }};

  {% if item.php %}
  index index.php index.html;

  location ~ \.php$ {
      try_files $uri =404;
      fastcgi_pass unix:/run/php/php7.0-fpm.sock;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include fastcgi_params;
  }

  location / {
      try_files $uri $uri/ /index.php?$query_string;
  }
  {% else %}
  index index.html;
  {% endif %}
}

Par défaut, Ansible utilise le moteur de template Jinja que l'on peut appeller depuis le module template.

- name: Création de la configuration nginx
  template: src=templates/nginx.j2 dest=/etc/nginx/sites-available/{{ item.domain }} force=yes
  notify: nginx reload

Ansible Galaxy

Créer ses propres rôles peut sembler complexe lorsque l'on commence. Ansible dispose d'un hub appellé Galaxy qui permet d'échanger ces recettes avec la communauté. C'est un bon point de départ si vous voulez voir ce que font les autres et découvrir comment les autres utilisateurs utilisent Ansible.