mardi 7 octobre 2014

Premier pas avec Ansible et gestion du sudo

Et voilà, à peine je commence à maîtriser le langage autour de Puppet qu'on me demande de me pencher sur Ansible. Pour les personnes qui se sauraient pas ce que font ces deux produits, il faut savoir qu'ils appartiennent à la mouvance du DevOps qui consiste à gérer son infrastructure par du code (Dev) plutôt que par un opérateur (Ops) également appelé être humain (ou bipède, interface chaise-clavier etc.).

Installation de Ansible sur votre machine

La différence entre les deux produits se trouve au niveau de leur mode de fonctionnement : Puppet fonctionne à l'aide d'agent alors que Ansible s'appuie sur le protocole SSH et l'interpréteur python. Un petit bémol tout de même, si vous utilisez des versions antérieurs à Python 2.5, vous aurez besoin d'une librairie de gestion du json dans python. Comme il se trouve que les versions de RHEL 5.x sont concernées, ça pourrait vous arriver.

Pour les autres, c'est pour ainsi dire la fête : pas de package à installer et à maintenir sur vos machines. Vous échangez vos clés SSH avec les machines que vous voulez gérer et c'est parti.

Pour le serveur Ansible, l'installation se fait en activant le support des EPEL pour les machines à base de RHEL/CentOS (cf https://fedoraproject.org/wiki/EPEL) et en lançant un bon vieux yum install ansible. Pour Ubuntu, vous pouvez vous appuyer sur le ppa suivant : ppa:rquillo/ansible (l'ajout se fait avec la commande sudo add-apt-repository ppa:rquillo/ansible suivi d'un sudo aptitude update ; sudo aptitude install ansible).

Et voilà, c'est tout !

Prenons un exemple

Maintenant que nous avons planté le décor, nous allons créer notre première recette. Créer un répertoire de travail (~/ansible/test par exemple) et, dans ce répertoire, créer un fichier hosts avec le contenu suivant :

[test]
machine1
machine2

Ce fichier va nous servir d'inventaire des différentes machines pour nos déploiements et de mécanisme de regroupement (avec ici une section [test]). Pour tester la communication ssh, il suffit de lancer la commande ansible -i ./hosts all -m ping. Ci-dessous un exemple de résultat :

ansible -i ./hosts all -m ping
machine1 | success >> {
    "changed": false, 
    "ping": "pong"
}
machine2 | success >> {
    "changed": false, 
    "ping": "pong"
}

En cas de pépin, il faudra bien-sûr échanger les clés SSH avec un ssh-copy-id MACHINE.

Maintenant que nous avons la liste de nos machines, lançons la création du fichier site.yml et ajoutons-y le contenu suivant :

---
# Playbook de test

- name: Test
  hosts: test
  tasks:
    - name: Création d'un fichier /tmp/test
      copy: dest=/tmp/test content="Ceci est test\n" owner=root group=root

Nous avons ici associé le group de machine test (ligne hosts: test) avec la création d'un fichier de test appartenant à root.

On enregistre, et on lance maintenant l'application de cette recette avec la commande ansible-playbook -i ./hosts ./site.yml. On devrait obtenir la sortie suivante :

yannig@pupuce ~/ansible/test $ ansible-playbook -i ./hosts ./site.yml

PLAY [Test] *********************************************************

GATHERING FACTS *****************************************************
ok: [machine1]
ok: [machine2]

TASK: [Création d'un fichier /tmp/test] *****************************
changed: [machine1]
changed: [machine2]

PLAY RECAP **********************************************************
machine1             : ok=2    changed=1    unreachable=0    failed=0
machine2             : ok=2    changed=1    unreachable=0    failed=0

Ça marche : j'ai maintenant des fichiers /tmp/test sur mes deux machines :).

Et puis vint la sécurité

C'est bien beau mais le test que je viens de faire, je l'ai fait sur des machines que je maîtrise totalement. Malheureusement sur la prod sur laquelle je vais devoir travailler, il est interdit de se connecter directement en tant que root. Il faut donc passer par un mécanisme d'escalade sudo. Et comme un bonheur ne vient jamais seul, il faut également ressaisir le mot de passe pour lancer le sudo ...

Et c'est là où intervient la notion de variable dans le fichier hosts. Ci-dessous un exemple permettant de gérer l'utilisation d'un mot de passe sudo pour passer en tant qu'utilisateur root :

[machineexterne:vars]
ansible_sudo_pass=xxx
ansible_remote_user=userxxx
ansible_sudo=yes
ansible_sudo_user=root

[machineexterne]
machineexterne1
machineexterne2

[test]
machine1
machine2

Il est bien sûr entendu que le compte remote_user devra disposer des droits suffisants pour faire un sudo vers root.

Pour conclure

Vous l'aurez vu, il s'agissait juste de faire ses premiers pas avec ce merveilleux outils. Les difficultés habituelles sont bien gérées (sudo, ssh) et sa légéreté de déploiement initiale devrait en convaincre plus d'un.

La documentation du site est bien organisée. Je vous laisse consulter ça à l'adresse suivante : http://docs.ansible.com/.