Lab 2 — Exercices 3 et 4 : Résumé & Guide d’exécution
📋 Fichiers et documents créés
Exercice 3 : Idempotence
-
Documentation :
EXERCISE_3_IDEMPOTENCE_ANALYSIS.md- Analyse détaillée des résultats
- Explications du problème d’idempotence
- 3 solutions (minimale, meilleure pratique)
-
Scripts de rôle (3 variantes) :
roles/sample-app/tasks/main.yml(actuelle — non-idempotente)roles/sample-app/tasks/main_idempotent.yml(idempotente minimale)roles/sample-app/tasks/main_systemd.yml(meilleure pratique avec systemd)
-
Script d’exécution :
cd /home/sable/devops_base/scripts/ansible ./exercise_3_idempotency.sh
Exercice 4 : Déploiement multi-instance
-
Documentation :
EXERCISES_3_4_ANALYSIS.md- Explication du concept multi-instance
- Approches (modification playbook, inventaire, configuration)
-
Playbook multi-instance :
create_ec2_instances_multi.yml— crée N instances (variableinstance_count)
-
Script d’exécution :
cd /home/sable/devops_base/scripts/ansible ./exercise_4_multi_instance.sh [nombre_instances] # Exemple : ./exercise_4_multi_instance.sh 3
🔍 Résultats observés — Exercice 3
Idempotence (relancer 2x le même playbook)
1ère exécution :
PLAY RECAP
... ok=6 changed=1 unreachable=0 failed=0 skipped=1
2ème exécution (IDENTIQUE) :
PLAY RECAP
... ok=6 changed=1 unreachable=0 failed=0 skipped=1
Problème identifié
La tâche “Start sample app” n’est PAS idempotente :
- Elle est une commande
shellbrute - S’exécute TOUJOURS (pas de condition
when:) - Marque TOUJOURS comme
changed - Résultat : À chaque relance, un nouveau processus Node est créé → accumulation de processus
Explication technique
# PROBLÉMATIQUE
- name: Start sample app
shell: nohup node /home/ec2-user/app.js > /tmp/app.log 2>&1 &
# ❌ Pas de condition (when:)
# ❌ Pas de changed_when: false
# ❌ Crée TOUJOURS un nouveau processusSolution 1 (minimale) :
- name: Start sample app (IDEMPOTENT)
shell: nohup node /home/ec2-user/app.js > /tmp/app.log 2>&1 &
when: app_running.rc != 0 # ✅ Ne lance que si pas actif
changed_when: false # ✅ Supprime le "changed"Solution 2 (meilleure) :
# Utiliser un service systemd — complètement idempotent
- name: Enable and start sample app service
systemd:
name: sample-app
state: started
enabled: yes🚀 Exercice 4 — Déploiement multi-instance (préparé)
Fichiers prêts
Playbook multi-instance : create_ec2_instances_multi.yml
- loop: "{{ range(0, instance_count | int) | list }}"
# Crée N instances (N = variable instance_count)Inventaire dynamique (inchangé) : inventory.aws_ec2.yml
filters:
tag:Ansible: ch2_instances # Découvre TOUTES les instances avec ce tagPlaybook de configuration (inchangé) : configure_sample_app_playbook.yml
hosts: _ch2_instances # Cible TOUS les hôtes du groupe dynamiqueWorkflow complet
-
Créer 3 instances :
ANSIBLE_PYTHON_INTERPRETER="$(which python3)" \ AWS_PROFILE=labs-devops_diallo \ ansible-playbook -v create_ec2_instances_multi.yml \ -e instance_count=3 \ -e instance_type=t3.micro -
Inventaire découvre automatiquement les 3 instances
-
Configurer toutes les 3 instances en parallèle :
ANSIBLE_PYTHON_INTERPRETER="$(which python3)" \ AWS_PROFILE=labs-devops_diallo \ ansible-playbook -i inventory.aws_ec2.yml configure_sample_app_playbook.yml -
Tester les 3 apps :
# Récupérer les IPs aws ec2 describe-instances \ --filters "Name=tag:Ansible,Values=ch2_instances" \ --query 'Reservations[].Instances[].PublicIpAddress' \ --output text \ --profile labs-devops_diallo --region us-east-2 # Tester chaque app for IP in $(aws ec2 describe-instances --filters ... --output text); do curl http://$IP:8080/ done
Avantages du design
✅ Pas de changement du code Ansible — juste changer une variable (instance_count)
✅ Inventaire auto-découvre — le plugin aws_ec2 voit toutes les instances tagguées
✅ Parallélisation automatique — Ansible se connecte aux N instances en parallèle
✅ Même configuration — tous les hôtes reçoivent la même config
📝 Pour aller plus loin
Améliorer l’idempotence du rôle
Remplacer main.yml par une version plus robuste :
# Variante minimale
cp roles/sample-app/tasks/main_idempotent.yml roles/sample-app/tasks/main.yml
# Variante meilleure (systemd)
cp roles/sample-app/tasks/main_systemd.yml roles/sample-app/tasks/main.yml
# Tester
ansible-playbook -i inventory.aws_ec2.yml configure_sample_app_playbook.yml
# Relancer → doit montrer 0 changement à la 2ème exécutionTest du déploiement multi-instance
cd /home/sable/devops_base/scripts/ansible
# Déployer 3 instances (utilise le script)
./exercise_4_multi_instance.sh 3
# Ou manuellement
ansible-playbook -v create_ec2_instances_multi.yml -e instance_count=3
# Attendre 30s
ansible-playbook -i inventory.aws_ec2.yml configure_sample_app_playbook.ymlNettoyage
Terminer les instances (toutes avec le tag Ansible=ch2_instances) :
# Lister les IDs
aws ec2 describe-instances \
--filters "Name=tag:Ansible,Values=ch2_instances" "Name=instance-state-name,Values=running" \
--query 'Reservations[].Instances[].InstanceId' \
--output text \
--profile labs-devops_diallo --region us-east-2
# Terminer (remplacer ID1 ID2 ID3)
aws ec2 terminate-instances \
--instance-ids i-0d9e97dcfeef9c1d9 [ID2] [ID3] ... \
--profile labs-devops_diallo --region us-east-2
# Nettoyer le Security Group (après termination complète)
aws ec2 delete-security-group \
--group-name sample-app-ansible \
--profile labs-devops_diallo --region us-east-2
# Supprimer la clé (optionnel)
aws ec2 delete-key-pair --key-name ansible-ch2 \
--profile labs-devops_diallo --region us-east-2📚 Lectures recommandées
- Idempotence dans Ansible : https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_execution.html#idempotence
- Module
systemd: https://docs.ansible.com/ansible/latest/collections/ansible/posix/systemd_module.html - Plugin inventaire
aws_ec2: https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html - Boucles dans Ansible (
loop,with_*) : https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html
✅ Checklist — Exercices 3 & 4
Exercice 3
- Documentation d’analyse créée (
EXERCISE_3_IDEMPOTENCE_ANALYSIS.md) - Exécution pratique réalisée (script
exercise_3_idempotency.sh) - Résultats observés : tâche “Start sample app” n’est pas idempotente
- 3 solutions fournies (minimale, meilleure pratique)
- (Optionnel) Tester une variante en remplaçant
main.yml
Exercice 4
- Playbook multi-instance créé (
create_ec2_instances_multi.yml) - Documentation fournie (
EXERCISES_3_4_ANALYSIS.md) - Script d’exécution préparé (
exercise_4_multi_instance.sh) - (Optionnel) Exécuter le script pour déployer 2-3 instances
🎓 Conclusion
Exercice 3 montre l’importance de l’idempotence dans les playbooks Ansible. Les tâches mal écrites peuvent créer des doublons ou des conflits à chaque relance. Les solutions incluent l’ajout de conditions, changed_when:, ou (meilleur) l’utilisation de services systemd.
Exercice 4 démontre la scalabilité horizontale avec Ansible. Grâce à la boucle et aux tags, déployer 3 instances ou 30 instances ne nécessite que la modification d’une seule variable. L’inventaire dynamique et la parallélisation automatique rendent cela puissant et efficace.