Infrastructure as Code

Ansible

Cheatsheet Ansible — inventaire, playbooks, roles, modules et bonnes pratiques

ansibleautomatisationconfigurationplaybooksroles

Concepts clés

ConceptDescription
InventaireListe des machines cibles (hosts)
PlaybookFichier YAML décrivant les tâches à exécuter
RoleCollection réutilisable de tâches, handlers, variables
ModuleUnité d'action (apt, copy, service, template...)
TaskAppel d'un module avec des paramètres
HandlerTâche déclenchée par un notify (ex: redémarrer nginx)
FactsInformations collectées sur les machines cibles

Inventaire

# inventory.ini
[web]
web-01 ansible_host=10.0.1.10
web-02 ansible_host=10.0.1.11
 
[db]
db-01 ansible_host=10.0.2.10
 
[production:children]
web
db
 
[all:vars]
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/deploy_key

Commandes ad-hoc

$ansible all -i inventory.ini -m ping
Tester la connectivité de tous les hosts
$ansible web -m shell -a 'uptime'
Exécuter une commande sur le groupe web
$ansible db -m apt -a 'name=postgresql state=present' --become
Installer PostgreSQL sur les serveurs DB
$ansible all -m setup
Collecter les facts de toutes les machines

Playbook

# deploy.yml
---
- name: Deploy web application
  hosts: web
  become: true
  vars:
    app_version: "2.1.0"
    app_port: 3000
 
  tasks:
    - name: Install Node.js
      apt:
        name: nodejs
        state: present
        update_cache: true
 
    - name: Create app directory
      file:
        path: /opt/app
        state: directory
        owner: deploy
        group: deploy
        mode: "0755"
 
    - name: Copy application files
      copy:
        src: ./dist/
        dest: /opt/app/
        owner: deploy
      notify: Restart app
 
    - name: Deploy systemd service
      template:
        src: templates/app.service.j2
        dest: /etc/systemd/system/app.service
      notify: Restart app
 
    - name: Ensure app is running
      systemd:
        name: app
        state: started
        enabled: true
        daemon_reload: true
 
  handlers:
    - name: Restart app
      systemd:
        name: app
        state: restarted
$ansible-playbook -i inventory.ini deploy.yml
$ansible-playbook deploy.yml --check
Dry run — affiche ce qui serait changé sans l'appliquer
$ansible-playbook deploy.yml --diff
Affiche les différences dans les fichiers modifiés
$ansible-playbook deploy.yml --limit web-01
Exécuter uniquement sur un host spécifique
$ansible-playbook deploy.yml --tags deploy
Exécuter uniquement les tâches avec le tag 'deploy'

Roles

roles/
└── nginx/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    ├── templates/
    │   └── nginx.conf.j2
    ├── files/
    ├── vars/
    │   └── main.yml
    └── defaults/
        └── main.yml
# Utilisation dans un playbook
- hosts: web
  roles:
    - nginx
    - { role: app, app_version: "2.1.0" }
$ansible-galaxy init mon-role
Créer la structure d'un rôle
$ansible-galaxy install geerlingguy.docker
Installer un role depuis Galaxy

Templates Jinja2

# templates/nginx.conf.j2
server {
    listen {{ app_port | default(80) }};
    server_name {{ ansible_fqdn }};
 
    location / {
        proxy_pass http://127.0.0.1:{{ backend_port }};
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
 
{% if ssl_enabled %}
    listen 443 ssl;
    ssl_certificate {{ ssl_cert_path }};
    ssl_certificate_key {{ ssl_key_path }};
{% endif %}
}

Modules courants

ModuleUsage
apt / yumGestion des paquets
copyCopier des fichiers
templateDéployer des templates Jinja2
fileGérer fichiers et répertoires
service / systemdGérer les services
user / groupGérer utilisateurs et groupes
gitCloner des repos
docker_containerGérer des conteneurs Docker
uriRequêtes HTTP
wait_forAttendre qu'un port soit ouvert

Bonnes pratiques

  • Idempotence : relancer le playbook ne doit rien casser
  • Handlers : utiliser notify pour les redémarrages de services
  • Vault : chiffrer les secrets avec ansible-vault
  • Tags : taguer les tâches pour des exécutions sélectives
  • Check mode : toujours tester avec --check avant d'appliquer
$ansible-vault encrypt vars/secrets.yml
Chiffrer un fichier de secrets
$ansible-playbook deploy.yml --ask-vault-pass
Exécuter avec un fichier vault