Ansible - l'orchestration facile

06 Sep 2013



L'une des choses qui m'intéresse énormément ces dernières années est le déploiement automatisé et industrialisé des plateformes en particulier via Puppet. Marre des scripts shell !

Présentation

Aujourd'hui j'ai découvert un outil nommé Ansible semblable à bien des aspects à Puppet mais avec quelques différences très intéressantes:

  • Aucun agent à installer sur les machines cibles. Ca permet de se lancer plus rapidement et plus facilement, on installe ansible et c'est parti !
  • Le déploiement et le passage de commande est réalisé via ssh ce qui permet de ne pas tout le temps être en root
  • Possibilité de lancer facilement des commandes shell sur tout ou partie de notre plateforme. Du genre un ping ou un apache status chose qui n'est pas facile via Puppet
  • Ecrit en python plutôt qu'en ruby (mais ça c'est personnel :)
  • Bien plus simple à prendre en main que Puppet

Après l'outil est encore un peu jeune et manque de certaines fonctionnalités dans la version open-source comme:

  • Avoir un dashboard pour consulter le résultat de déploiements réalisés de manière régulières (via cron par exemple). Actuellement on lance ansible il effectue ses actions et affiche le résultat sur la sortie standard. Pas de console centralisée
  • Logs d'exécution. Dans le cas où quelque chose se passe mal, le résultat affiché est très léger et oblige quasiment tout le temps à se logguer sur la machine pour voir de quoi il en retourne alors qu'avoir plus de logs et récupérés sur la machine exécutant ansible serait bien plus pratique quand même !
  • Déploiement sous Windows
Ces fonctionnalités semblent disponibles dans la version enterprise à 100$/machine/an.

Premiers pas

Assez parlé il est temps de jouer un peu avec Ansible !

Installation d'Ansible

L'installation est facile et prévue pour à peu près toutes les distributions Linux et même pour Mac sur la page getting started.

Pour ma part j'ai installé ça via un PPA:

On ajoute ça à nos sources:
deb http://ppa.launchpad.net/rquillo/ansible/ubuntu precise main 

deb-src http://ppa.launchpad.net/rquillo/ansible/ubuntu precise main

Et puis:
sudo apt-get install ansible

Et c'est bon !

Premiers tests

Pour faire nos tests nous allons initier une machine virtuelle via Vagrant:
vagrant init precise64

Et on lance notre vm:
vagrant up

Une fois la machine up nous allons faire un simple test de connexion à notre VM. Tout d'abord créons un dossier ansible à côté de notre Vagrantfile afin de travailler:
mkdir ansible && cd ansible

On créé ensuite le fichier hosts qui va contenir la liste des machines de notre plateforme qui ne contient qu'une machine:
127.0.0.1 ansible_ssh_port=2222 ansible_connection=paramiko

Le paramètre "ansible_ssh_port" permet de spécifier un port différent du port 22 par défaut pour se connecter via SSH. Le port 2222 est une redirection du port 22 de notre VM qui est ouvert automatiquement par Vagrant.

Le paramètre "ansible_connection" a été nécessaire pour moi afin de contourner un bug qui avait pour conséquence que Ansible restait bloqué après la connexion.

Pour info ce type de connexion est le type par défaut à partir d'Ansible 1.3.1 (j'ai fait mes tests avec la v1.2.2).


Et ensuite on lance le module "ping" (inclus dans Ansible) sur l'ensemble des machines de notre plateforme (donc juste en local):
ansible all -i hosts -m ping -u vagrant -k

Les options utilisées:
  • all: permet de préciser à quel groupe/machine appliquer la commande ou le module
  • -i : pour préciser le fichiers hosts à utiliser (par défaut /etc/ansible/hosts)
  • -m: le nom du module à exécuter
  • -u: l'utilisateur utilisé pour la connexion
  • -k: demander le mot de passe sur l'entrée standard
Et le résultat:
localhost | success >> {

"changed": false,

"ping": "pong"

}

Ça marche ! On va maintenant exécuter une commande Unix quelconque, par exemple "uptime". Cela se fait via la commande suivante:
ansible all -i hosts -m shell -a "uptime" -u vagrant -k

Et le résultat:
localhost | success | rc=0 >>

19:26:06 up 17 min, 2 users, load average: 0.28, 0.33, 0.32


Tout fonctionne on va maintenant créer un module afin d'organiser un peu notre travail.

Structure d'un rôle

Les modules se nomment dans Ansible des playbook et représente en gros une liste de tâches au format YAML.

D'après la page Best practices nous allons créer quelques fichiers à la racine de notre dossier ansible:
  • Un fichier nommé "production" qui va contenir la liste de nos serveurs de production en l'occurrence uniquement les lignes suivantes:
[application-server]

127.0.0.1 ansible_ssh_port=2222 ansible_connection=paramiko

Nous allons également déclarer un playbook maître qui aura pour seule fonction d'inclure les autres playbooks afin de mieux séparer les choses:
  • site.yml:
- include: appservers.yml

Et notre fichier appservers.yml contenant les différents rôles de nos serveurs d'application:

- hosts: application-server
 
roles:
  
- tomcat8


Et maintenant la structure standard d'un rôle:

├── appservers.yml
├── production
├── roles
│   └── tomcat8
│   ├── files
│   ├── handlers
│   ├── tasks
│   └── templates
└── site.yml


Quelques explications:

  • Sous le dossier roles, un dossier pour chaque rôle (tomcat8 par exemple)
  • Ce dossier contient des sous-dossiers:
    • tasks: le fichier principal contenant la liste des tâches associées au rôle tomcat8
    • files: des fichiers destinés à être copié en tant que tels sur les serveurs cibles
    • handlers: les handlers utilisés par nos tâches (on verra un handler en détail un peu plus tard)
    • templates: les templates permettant de générer des fichiers instanciés en fonction des variables du serveur
C'est tout pour cette fois-ci dans le prochain article on réalisera un playbook permettant d'installer Tomcat 8 sur Ubuntu 12.04 !

Edit: l'article 2 vient d'être publié !


Post 13/52