Module 2 – Configuration immuable avec Ansible & Packer

Industrialisez Ansible et Packer : rôles testés avec Molecule, images immuables, pipeline de configuration et publication sur registry.

Après l’infrastructure, place à la configuration immuable. Nous combinons Packer pour construire des images et Ansible pour configurer serveurs et conteneurs.

Objectifs

  • Créer des images “golden” reproductibles avec Packer et des rôles Ansible.
  • Industrialiser les playbooks (galaxy, tests Molecule, lint).
  • Déployer automatiquement la configuration dans un pipeline.

1. Organisation Ansible

playbooks/
├── inventories/
│   ├── dev/
│   │   └── hosts.ini
│   └── staging/
├── roles/
│   ├── base/
│   ├── app/
│   └── observability/
├── group_vars/
│   └── all.yml
├── requirements.yml
└── site.yml

Installer les dépendances :

ansible-galaxy install -r requirements.yml
pip install molecule[docker] ansible-lint yamllint

2. Rôle “base”

# roles/base/tasks/main.yml
- name: Update apt cache
  ansible.builtin.apt:
    update_cache: yes

- name: Install packages
  ansible.builtin.apt:
    name:
      - curl
      - htop
      - fail2ban
    state: present

- name: Configure motd
  ansible.builtin.template:
    src: motd.j2
    dest: /etc/motd
    owner: root
    group: root
    mode: '0644'

Variables globales :

# group_vars/all.yml
motd_message: "DevOps Training"

3. Tests Molecule

molecule init role base -d docker
cat <<'EOF' > roles/base/molecule/default/converge.yml
---
- name: Converge
  hosts: all
  become: true
  roles:
    - role: base
EOF
molecule test

Ajoutez ansible-lint et yamllint dans la pipeline.

4. Image Packer

{
  "builders": [
    {
      "type": "docker",
      "image": "ubuntu:22.04",
      "commit": true
    }
  ],
  "provisioners": [
    {
      "type": "ansible",
      "playbook_file": "playbooks/site.yml",
      "user": "root",
      "extra_arguments": ["--inventory", "playbooks/inventories/docker/hosts.ini"]
    }
  ],
  "post-processors": [
    {
      "type": "docker-tag",
      "repository": "ghcr.io/acme/base-image",
      "tag": "latest"
    }
  ]
}

Exécuter packer build packer/docker.json pour produire l’image.

5. Déploiement

Playbook principal :

---
- name: Provision web servers
  hosts: web
  become: true
  roles:
    - base
    - app

Inventaire dynamique (ex. Terraform output) : utilisez terraform output -json + script Python pour générer hosts.ini.

6. Lab guidé

  1. Initialiser un rôle app qui déploie une application Go (binaire) + service systemd.
  2. Créer un scénario Molecule (driver Docker) et vérifier que systemctl status app renvoie active (running).
  3. Construire une image Packer basée sur ubuntu:22.04 intégrant le rôle base.
  4. Publier l’image sur GHCR (docker push ghcr.io/<org>/base-image:latest).
  5. Déployer le playbook site.yml sur un serveur de test (VM ou container) et valider le motd + service.

Challenge optionnel

  • Ajouter des tests Molecule sur AWS EC2 (driver ec2) pour valider l’infra cloud.
  • Intégrer ansible-navigator pour une exécution containerisée.
  • Générer une SBOM de l’image avec syft et signer l’image avec cosign.

Solution détaillée

  1. Molecule : molecule test doit s’exécuter sans échec. molecule converge + molecule verify confirment la création du service systemd.
  2. Packer : sortie finale Build 'docker' finished. docker images | grep base-image doit afficher l’image taguée.
  3. Registry : docker login ghcr.io puis docker push ghcr.io/acme/base-image:latest (vérifiez dans l’interface GHCR).
  4. Playbook : ansible-playbook -i inventories/dev/hosts.ini site.ymlchanged= vs ok=. ansible web -m shell -a 'cat /etc/motd' affiche le motd configuré.
  5. SBOM (challenge) : syft ghcr.io/acme/base-image:latest -o json > sbom.json puis cosign sign ghcr.io/acme/base-image:latest. Documentez la commande dans docs/security.md.

Conservez les manifests Packer/Ansible et le rapport Molecule dans le dépôt pour audit.

Pièges fréquents

  • Utiliser become: yes sans limiter au nécessaire → perdez en idempotence.
  • Oublier gather_facts: false dans certains tasks, rallonge l’exécution.
  • Ne pas versionner requirements.yml → difficile de reproduire la stack sur CI.

Ressources

Checklist

  • ✅ Rôles Ansible testés avec Molecule.
  • ✅ Image Packer construite et publiée.
  • ✅ Playbook site.yml déployé avec succès.
  • ✅ Rapport SBOM (optionnel) et notes enregistrés.