Aller au contenu principal

Ansible Vault

On utilise tous git pour stocker nos données (playbooks, inventaires, roles, collections ...) Ansible mais attention à ne pas divulguer vos données secrètes comme des mots de passe, des clés SSH, des tokens d'API, ...

Ansible met à disposition ansible-vault (un coffre-fort) qui permet de chiffrer ces données. Au besoin ansible saura déchiffrer ces données. Voyons comment l'utiliser.

Que propose ansible-vault ?

Ansible-Vault utilise l'algorithme AES256 pour fournir un cryptage symétrique associé à un mot de passe fourni par l'utilisateur. Cela signifie que le même mot de passe est utilisé pour chiffrer et déchiffrer le contenu, ce qui est plutôt simple à mettre en oeuvre. Chose importante, Ansible est capable d'identifier et de déchiffrer tous les fichiers cryptés dans le coffre-fort qu'il trouve lors de l'exécution d'un playbook ou d'une tâche.

Il existe d'autres moyens plus avancés pour sécuriser vos données comme Hashicorp Vault. Mais pour des petits projets Ansible-Vault suffira largement.

Mise en place d'un vault Ansible

On va prendre comme exemple le stockage d'un token d'API qui est stocké dans un fichier se nommant secret_api_key.yml :

# secret_api_key.yml
api_key: dEZSY!3P22Pc#s

Chiffrer le fichier avec Ansible-Vault

Pour chiffrer un fichier, il suffit d'utiliser la commande ansible-vault encrypt:

ansible-vault encrypt secret_api_key.yml
New Vault password:
Confirm New Vault password:
Encryption successful
[vagrant@ansible test]$ cat secret_api_key.yml
$ANSIBLE_VAULT;1.1;AES256
35393032626636353837396238623937383633323831353063393938653934333461663465633462
6461363731653533346664653038363233343664623431370a363031623332393230653630626231
64303665613265653130393133356164653765656633386663663030643335303639656338623866
3032653036323932330a383539343661633165643439643061393635333738616334383666633437
39623464383537303339333462303366386338643931363937393062386336363339

Ansible vous demandera d'entrer deux fois votre mot de passe (à stocker dans un bon vieux keypass).

Afficher le contenu d'un fichier Vault Ansible

Pour afficher le contenu d'un fichier Ansible-Vault crypté sans le modifier, il suffit d'utiliser l'option view :

ansible-vault view secret_api_key.yml
Vault password:
api_key: dEZSY!3P22Pc#s

Éditer un fichier Vault Ansible

De même pour l'éditer sans en changer le mot de passe, cette fois, on utilise l'option edit :

ansible-vault edit secret_api_key.yml

L'éditeur utilise est celui qui est défini dans la variable EDITOR. Si vous voulez en changer pour passer à nano (par défaut c'est vi), dans votre fichier ~/.bashrc ajouter ceci :

export EDITOR=nano

Déchiffrer un fichier Vault Ansible

On a notre disposition l'option decrypt:

ansible-vault decrypt secret_api_key.yml

Changer le mot de passe d'un vault Ansible

Il est possible de changer le mot de passe avec l'option rekey :

ansible-vault rekey secret_api_key.yml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful

Utilisation d'un secret dans un playbook

Imaginons que nous voulions créer un fichier contenant la clé de l'API sur un serveur (ici, nous utiliserons localhost)

Le playbook:

---
- hosts: localhost
  gather_facts: false
  tasks:

    - name: Création du fichier si besoin
      file:
        path: ./configuration.ini
        state: touch

    - name: Put api key in file
      lineinfile:
        path: configuration.ini
        line: "API_KEY={{ api_key }}"

Maintenant lançons le playbook avec les options -e @fichier_secret et --ask-vault-pass :

ansible-playbook -i localhost -c local -e @secret_api_key.yml --ask-vault-pass api.yml
Vault password:
localhost does not match 'all'

PLAY [localhost] *************************************************************************************

TASK [Création du fichier si besoin] *****************************************************************
changed: [localhost]

TASK [Ensure API key is present in config file] ******************************************************
changed: [localhost]

PLAY RECAP *******************************************************************************************
localhost                  : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[vagrant@ansible test]$ cat configuration.ini
API_KEY=dEZSY!3P22Pc#s

Pour éviter d'indiquer le fichier dans le playbook, il suffit d'ajouter l'option vars_file:

---
- hosts: localhost
  gather_facts: false
  vars_files:
    - secret_api_key.yml
  tasks:

    - name: Création du fichier si besoin
      file:
        path: ./configuration.ini
        state: touch

...

Utilisation de plusieurs fichiers secrets

Il est possible d'utiliser plusieurs fichiers vault via avec l'option --vault-id associée à une étiquette. Cela permet par exemple de gérer plusieurs environnements.

ansible-vault create --vault-id prod@prompt prod-secrets.yml

Le contenu de celui de prod :

$ANSIBLE_VAULT;1.2;AES256;prod
65396563333264393539336238306361613563323937323534646639303531313561386232383130
6536623835326237386634643761373936333734616565610a623061646239333634383132626635
30376365396464626363396166656335363836656437633539326261636232643933386333656630
3865633931353038350a613034386139636161623439616262613930333333363634306461346661
3832

Vous remarquerez que l'id est en fin de première ligne.

Utilisation d'un vault Ansible dans un pipeline CI gitlab

Vous avez remarqué que la commande ansible-vault nécessite à chaque fois de d'entrer le mot de passe. Mais comment faire dans un pipeline d'intégration continue ?

Il suffit de créer un fichier variable protégé gitlab. Pour cela, il faut aller dans settings/CI-CD/Variables :

Dans votre fichier .gitlab-ci.yml on va utiliser l'option --vault-password-file:

deploy:
  only:
    - master
  script:
    - ansible-playbook -i inventory/prod.yml --vault-password-file $PROD_PASSWORD playbook.yml