Tester ses rôles Ansible avec Serverspec
Publié le :
Pour poursuivre notre formation Ansible, au menu du jour les tests des rôles.
Introduction
Ansible est un outil Devops largement utilisé et suivi par une très grande communauté. Pour valider mes rôles, j’utilisais jusqu’à peu molecule, mais dans une démarche de veille techno, j’ai découvert Kitchen-CI ↗ et ça été une belle découverte.
En effet molecule est un produit qui évolue sans cesse, imposant des ruptures importantes à chaque nouvelle version. Et là Kitchen-CI vient vraiment simplifier la partie test des rôles Ansible. J’aurais pu aussi utiliser ansible-test, mais ce sera pour une prochaine fois quand je créerai des collections ansible.
Kitchen-CI
Kitchen-CI est un outil Ruby développé par l’équipe en charge du produit de configuration Chef.
Kitchen-CI, permet de tester le résultat de l’exécution de divers outils de provisionning dont Terraform et Ansible. Vous voyez tout de suite l’intérêt : un outil commun pour réaliser une bonne partie de vos tests.
En effet Kitchen-CI est modulaire via ses drivers et modules qui lui permettent de fonctionner avec une grande partie des plateformes Onprem et Cloud : Docker, Vagrant, Terraform, AWS, Azure.
Automatiser les tests d’un rôle Ansible
Je vais, dans ce premier billet vous expliquer comment mettre en place des tests sur un rôle Ansible et ce, de manière simple avec Docker.
Installation des prérequis
Personnellement je l’installe dans ma VM de test provisionné avec Multipass.
Commençons par installer ruby, python3 docker :
sudo apt install ruby-full ruby-all-dev docker.io python3
Donnons les droits de lancer des commandes docker à votre utilisateur
sudo usermod -a -g docker $USERsudo su - $USER
La seconde ligne permet de récupérer les droits du groupe sans à se déconnecter :)
Et ansible bien sur :
sudo pip3 install ansible ansible-lint
Maintenant on installe tous les produits Kitchen nécessaire à notre cas
gem install test-kitchen kitchen-vagrant kitchen-ansible kitchen-docker kitchen-verifier-serverspec serverspec
J’ai mis aussi vagrant.
On teste
Normalement on devrait partir d’une feuille blanche pour faire du TDD mais là on va prendre un rôle existant pour y ajouter la partie test. On récupère un rôle permettant d’installer apache fourni par Jeff Geerling :
git clone https://github.com/geerlingguy/ansible-role-apache.git
Il faut créer ces répertoires et ces fichiers :
cd ansible-role-apachetouch .kitchen.yml# pour la partie test :mkdir -p test/integration/defaultmkdir test/integration/serverspectouch test/integration/default/default.ymltouch test/integration/serverspec/install_apache_spec.rbtouch test/integration/spec_helper.rb
Dans le fichier .kitchen.yml on décrit notre infrastructure de test :
---driver: name: docker use_sudo: false require_chef_omnibus: false require_ruby_for_busser: true
provisioner: name: ansible_playbook hosts: localhost require_ansible_repo: true ansible_verbose: true ansible_verbosity: 2 ansible_diff: true # sympa ce truc require_chef_for_busser: false ssh_known_hosts: - github.com ignore_extensions_from_root: [".git"] ignore_paths_from_root: [".git",".kitchen","bin"]
platforms: - name: centos7 driver: platform: rhel image: centos:7 run_command: /usr/lib/systemd/systemd provision_command: - yum install -y iproute net-tools
verifier: name: serverspec sudo_path: true
suites: - name: default driver: run_command: '/usr/sbin/init' driver_config: privileged: true volume: /sys/fs/cgroup:/sys/fs/cgroup verifier: patterns: - rôles/ansible-role-apache/test/integration/serverspec/*_spec.rb
transport: max_ssh_sessions: 6 forward_agent: true
Quelques explications sur la structure de kitchen
Kitchen utilise des :
- drivers ici j’ai choisi Docker, j’effectuerai des tests en local.
- provisioners : j’ai bien sur choisi Ansible.
- transports: paramétrages des sessions ssh
- verifiers : j’ai choisi ServerSpec.
- platforms: permet de définir comment est construit la machine de test.
- suites: ce paramètre permet de configurer toute une stack si besoin, composé de plusieurs machines. Ici on se limite à une seule machine
Premières commandes kitchen
On peut déjà lancer les premières commandes kichen:
- kitchen list qui permet de lister les instances.
- kitchen create qui va créer les machines nécessaires au test.
$ kitchen list
Instance Driver Provisioner Verifier Transport Last Action Last Errordefault-centos7 Docker AnsiblePlaybook Serverspec Ssh <Not Created> <None>
$ kithen create.....
$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES515cf7cb09ce 18a722885fb3 "/usr/sbin/init" About a minute ago Up About a minute 0.0.0.0:32809->22/tcp defaultcentos7-ubuntu-dev-ggl8fv2o
On voit que kitchen à instancier une machine docker :)
un playbook
Ajouter ceci au fichier test/integration/default/default.yml :
---- hosts: all
- name: Installer le package httpd hosts: all gather_facts: False rôles: - { role: ansible-role-apache }
On lance l’installation
Cela se fait au moyen de la commande kitchen converge. Kitchen va installer tout ce qu’il faut pour exécuter le playbook et lancer le test. En cas d’erreur, vous pouvez vous connecter à votre instance avec la commande kitchen login. Si vous corrigez des choses relancer la commande kitchen converge.
Écriture d’un test
On va limiter le test à l’ajout du user apache. Ajouter ceci au fichier test/integration/serverspec/install_apache_spec.rb :
require_relative '../spec_helper'
describe user('apache') do it { should exist } it { should belong_to_group 'apache' } it { should have_home_directory '/usr/share/httpd'} it { should have_login_shell '/sbin/nologin'} end
Il faut aussi ajouter ceci dans le fichier test/integration/spec_helper.rb. :
require 'serverspec'set :backend, :exec
Lancement des tests
Cela se fait au moyen de la commande kitchen verify. Kitchen install à nouveau tout ce qu’il faut pour exécuter les tests.
$ kitchen verify
---> RSPEC_CMD variable is: /usr/local/bin/rspec
User "apache" is expected to exist is expected to belong to group "apache" is expected to have home directory "/usr/share/httpd" is expected to have login shell "/sbin/nologin"
Finished in 0.08071 seconds (files took 0.25256 seconds to load) 4 examples, 0 failures
Finished verifying <default-centos7> (0m3.43s).
Intégrer de nouvelles plateformes
Vous voulez ajouter une machine :) Ajouter juste ceci dans votre fichier .kitchen.yaml dans la partie platforms :
- name: oraclelinux8 driver: platform: rhel image: oraclelinux:8 run_command: /usr/lib/systemd/systemd provision_command: - dnf install -y iproute net-tools
On relance les commandes kitchen converge et kitchen verify.
$ kitchen converge...$ kitchen converge...$ kitchen verify fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["/usr/libexec/httpd-ssl-gencerts"], "delta": "0:00:00.002882", "end": "2020-12-31 13:58:09.185699", "msg": "non-zero return code", "rc": 127, "start": "2020-12-31 13:58:09.182817", "stderr": "/usr/libexec/httpd-ssl-gencerts: line 5: hostname: command not found", "stderr_lines": ["/usr/libexec/httpd-ssl-gencerts: line 5: hostname: command not found"], "stdout": "", "stdout_lines": []}
Il faut corriger ! Je vous en laisse le soin.
On peut aussi tout en une seule commande : kitchen test. Cela va provisionner, installer, tester et détruire. Tant qu’on parle de destruction, il existe la commande kitchen destroy à utiliser au besoin.
La suite de la formation ansible dans de prochains billets avec peut-être un test avec ansible-test et le développement des collections.