Skip to content

Ansible

Ansible configure les LXC après leur provisioning par Terraform. Il installe Docker, déploie les fichiers .env contenant les secrets, et configure les services.

Règle d’or : Terraform crée les LXC, Ansible les configure.


Terminal window
# Fedora / RHEL
sudo dnf install ansible
# Ubuntu / Debian
sudo apt install ansible
# pip (toutes distributions)
pip install ansible

ansible/
├── ansible.cfg
├── .vault_pass # local uniquement — jamais committé
├── .gitignore
├── inventory/
│ ├── hosts.yml
│ └── group_vars/
│ ├── all/
│ │ ├── vars.yml # variables partagées
│ │ └── vault.yml # secrets globaux chiffrés
│ ├── <groupe>/
│ │ ├── vars.yml # références vers vault
│ │ └── vault.yml # secrets chiffrés
│ └── ...
├── roles/
│ ├── docker/ # Installation Docker CE
│ ├── env/ # Déploiement fichiers .env
│ └── ssh_keys/ # Clés SSH autorisées
└── playbooks/
├── docker.yml
└── <service>-env.yml

[defaults]
roles_path = ./roles
inventory = ./inventory/hosts.yml
host_key_checking = False
vault_password_file = .vault_pass
Terminal window
echo "<MOT_DE_PASSE_VAULT>" > ~/.vault_pass
chmod 600 ~/.vault_pass
ln -s ~/.vault_pass /path/to/ansible/.vault_pass

inventory/hosts.yml
all:
children:
<groupe>:
hosts:
<hostname>:
ansible_host: <IP>
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/id_rsa

Exemple avec plusieurs groupes :

all:
children:
lxc:
children:
core:
hosts:
core:
ansible_host: <CORE_IP>
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/id_rsa
apps:
hosts:
apps:
ansible_host: <APPS_IP>
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/id_rsa
dmz:
hosts:
blog-prod:
ansible_host: <DMZ_IP>
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/id_rsa

Les secrets sont chiffrés avec Ansible Vault (AES256) dans inventory/group_vars/<groupe>/vault.yml. Le .vault_pass est local et gitignored — référencé dans ansible.cfg.

# vars.yml — référence la variable vault
db_password: "{{ vault_db_password }}"
# vault.yml — valeur chiffrée (préfixe vault_)
vault_db_password: "le_vrai_mot_de_passe"
Terminal window
# Créer un nouveau fichier vault
ansible-vault create inventory/group_vars/<groupe>/vault.yml
# Éditer
ansible-vault edit inventory/group_vars/<groupe>/vault.yml
# Voir le contenu déchiffré
ansible-vault view inventory/group_vars/<groupe>/vault.yml
# Chiffrer un fichier existant
ansible-vault encrypt inventory/group_vars/<groupe>/vault.yml
# Chiffrer une valeur seule
ansible-vault encrypt_string 'valeur_secrete' --name 'vault_ma_variable'

Installe Docker CE et Docker Compose sur Ubuntu 24.04 LXC.

roles/docker/tasks/main.yml
---
- name: Install dependencies
apt:
name: [ca-certificates, curl, gnupg]
state: present
update_cache: true
- name: Create keyrings directory
file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Add Docker GPG key
get_url:
url: https://download.docker.com/linux/ubuntu/gpg
dest: /etc/apt/keyrings/docker.asc
mode: '0644'
- name: Get architecture
command: dpkg --print-architecture
register: dpkg_arch
changed_when: false
- name: Get Ubuntu codename
shell: ". /etc/os-release && echo $VERSION_CODENAME"
register: ubuntu_codename
changed_when: false
- name: Add Docker repository
apt_repository:
repo: "deb [arch={{ dpkg_arch.stdout }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ubuntu_codename.stdout }} stable"
state: present
filename: docker
- name: Install Docker
apt:
name: [docker-ce, docker-ce-cli, containerd.io, docker-compose-plugin]
state: present
update_cache: true
- name: Enable and start Docker
systemd:
name: docker
enabled: true
state: started

playbooks/docker.yml
---
- hosts: lxc
roles:
- docker
Terminal window
# Installer Docker sur tous les LXC
ansible-playbook playbooks/docker.yml
# Sur un groupe spécifique
ansible-playbook playbooks/docker.yml --limit apps

Les fichiers .env sont généralement exclus du rsync CI/CD. Ce pattern permet de les déployer via Ansible à partir des secrets vault :

roles/env/tasks/main.yml
---
- name: Déployer le fichier .env
template:
src: "{{ env_template }}"
dest: "{{ env_base_dir }}/{{ service_name }}/.env"
owner: root
group: root
mode: '0600'
notify: Restart service
# playbooks/<service>-env.yml
---
- hosts: <groupe>
vars:
service_name: <SERVICE>
env_template: <SERVICE>.env.j2
roles:
- env

Terminal window
# Tester la connexion à tous les hosts
ansible all -m ping
# Dry-run d'un playbook
ansible-playbook playbooks/<playbook>.yml --check --diff
# Exécuter une commande ad-hoc
ansible <groupe> -m shell -a "docker ps --format '{{.Names}}'"
# Vérifier Docker sur tous les LXC
ansible all -m shell -a "docker --version && docker compose version"
# Lister l'inventaire
ansible-inventory --list
# Voir les variables d'un host
ansible-inventory --host <hostname>