1) Installation & prérequis
Contrôleur (poste d'admin)
# Debian/Ubuntu
sudo apt update
sudo apt install -y ansible sshpass python3-venv
# (optionnel) environnement virtuel
python3 -m venv .venv && source .venv/bin/activate
pip install --upgrade pip ansible ansible-lint
Cibles (gérés par Ansible)
# Linux: Python doit être dispo (souvent déjà présent)
# SSH activé, clé publique copiée :
ssh-copy-id debian@vps.example
Windows (option) : WinRM à configurer (non couvert ici).
2) Arborescence recommandée
ansible/
├─ ansible.cfg
├─ inventories/
│ ├─ prod/
│ │ ├─ hosts.ini
│ │ ├─ group_vars/
│ │ │ └─ all.yml
│ │ └─ host_vars/
│ │ └─ vps-ovh.yml
├─ roles/
│ ├─ common/
│ │ ├─ tasks/main.yml
│ │ └─ files/ ...
│ └─ nginx_site/
│ ├─ tasks/main.yml
│ ├─ templates/site.conf.j2
│ └─ files/site/ (index.html, assets/...)
├─ playbooks/
│ ├─ site.yml
│ └─ check.yml
└─ vault/
└─ secrets.yml (chiffré)
3) Configuration de base
ansible.cfg
[defaults]
inventory = inventories/prod/hosts.ini
interpreter_python = auto
host_key_checking = False
stdout_callback = yaml
timeout = 30
remote_user = debian
retry_files_enabled = False
[privilege_escalation]
become = True
become_method = sudo
become_ask_pass = False
inventaire (hosts.ini)
[web]
vps-ovh ansible_host=51.210.181.58
[web:vars]
ansible_user=debian
ansible_become=true
site_root=/var/www/nico-cv
server_name=nicolas-sapin.fr www.nicolas-sapin.fr
4) Variables & Vault
group_vars/all.yml
nginx_packages:
- nginx
- certbot
- python3-certbot-nginx
tls_email: "admin@nicolas-sapin.fr"
cache_max_age: 2592000 # 30j
# (ex) mot de passe sudo si nécessaire (utiliser Vault)
# ansible_become_password: !vault |
# $ANSIBLE_VAULT;1.1;AES256;[...]
Vault (chiffrage)
# créer le fichier chiffré
ansible-vault create vault/secrets.yml
# éditer plus tard
ansible-vault edit vault/secrets.yml
# utiliser dans un play:
# vars_files:
# - ../vault/secrets.yml
# exécution : ajouter --ask-vault-pass ou --vault-password-file
5) Rôle nginx_site (site statique + HTTPS)
Ce rôle installe Nginx, déploie le contenu du site, crée le vhost, puis active le HTTPS via Certbot.
tasks/main.yml
---
- name: Packages requis
apt:
name: "{{ nginx_packages }}"
state: present
update_cache: true
- name: Créer le dossier site
file:
path: "{{ site_root }}"
state: directory
owner: www-data
group: www-data
mode: "0755"
- name: Déployer le contenu (HTML/CSS/JS)
copy:
src: "files/site/"
dest: "{{ site_root }}/"
owner: www-data
group: www-data
mode: "0644"
notify: Reload nginx
- name: Vhost HTTP (temporaire)
template:
src: "templates/site.conf.j2"
dest: "/etc/nginx/sites-available/nicolas-sapin.fr"
owner: root
group: root
mode: "0644"
- name: Activer vhost
file:
src: "/etc/nginx/sites-available/nicolas-sapin.fr"
dest: "/etc/nginx/sites-enabled/nicolas-sapin.fr"
state: link
notify: Reload nginx
- name: Vérifier conf Nginx
command: nginx -t
register: nginx_test
changed_when: false
failed_when: nginx_test.rc != 0
- name: Certbot — émettre/renouveler
command: >
certbot --nginx -d {{ server_name | replace(' ', ' -d ') }} -m {{ tls_email }} --agree-tos --no-eff-email
args:
creates: "/etc/letsencrypt/live/{{ (server_name.split(' '))[0] }}/fullchain.pem"
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
templates/site.conf.j2
server {
listen 80;
listen [::]:80;
server_name {{ server_name }};
root {{ site_root }};
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(?:css|js|png|jpg|jpeg|gif|ico|svg|webp|pdf|woff2?)$ {
expires 30d;
add_header Cache-Control "public, max-age={{ cache_max_age }}, immutable";
try_files $uri =404;
}
access_log /var/log/nginx/nicolas-sapin_access.log;
error_log /var/log/nginx/nicolas-sapin_error.log;
}
6) Playbooks
playbooks/site.yml
---
- name: Déployer le site CV sur Nginx (HTTPS)
hosts: web
become: true
vars_files:
- ../vault/secrets.yml
roles:
- nginx_site
playbooks/check.yml (dry-run)
---
- name: Vérifier les changements potentiels
hosts: web
gather_facts: false
tasks:
- name: Ping
ping:
# Dry-run global :
ansible-playbook playbooks/site.yml --check --diff
# Limiter :
ansible-playbook playbooks/site.yml --limit vps-ovh --tags nginx
# Exécuter réellement :
ansible-playbook playbooks/site.yml
7) Bonnes pratiques
- Idempotence : utiliser les modules Ansible (apt, template, copy, file…) plutôt que
command. - Variables : centraliser dans
group_vars/host_vars, exposer le moins possible. - Secrets :
ansible-vault, jamais de secrets en clair dans Git. - Handlers : ne redémarrer/recharger les services qu’en cas de changement.
- Tags : exécuter par domaine (
--tags nginx,--tags site). - CI/CD : ansible-lint, pre-commit, tests en staging avant prod.
- Accès : login par clé SSH, pas de root direct,
becomecontrôlé.
8) Dépannage
- Permission denied (SCP/Copy) : vérifier propriétaire
www-dataet droits de{{ site_root }}. - Failed to connect via SSH : clé non copiée, ou
HostKeyCheckingactif ; testerssh debian@IP. - become password requis : fournir
--ask-become-passou variable chiffrée dans Vault. - apt lock : attendre la fin de
apt-dailyou utiliserretries/delay. - Nginx reload failed :
nginx -t, voir/var/log/nginx/*_error.log. - Certbot : s’assurer que le vhost HTTP répond et que les DNS pointent correctement.
← Retour aux réalisations
Ansible
Nginx
Let’s Encrypt