{"id":189,"date":"2026-08-30T23:41:54","date_gmt":"2026-08-30T21:41:54","guid":{"rendered":"https:\/\/asfy.fr\/index.php\/tutoriels\/ansible-installation-et-prise-en-main\/"},"modified":"2026-08-30T23:42:12","modified_gmt":"2026-08-30T21:42:12","slug":"ansible-installation-et-prise-en-main","status":"publish","type":"sv_tutoriel","link":"https:\/\/asfy.fr\/index.php\/tutoriels\/ansible-installation-et-prise-en-main\/","title":{"rendered":"Ansible : installation et prise en main"},"content":{"rendered":"<p>Configurer un serveur \u00e0 la main, puis le suivant, puis le suivant, en esp\u00e9rant avoir fait exactement les m\u00eames commandes \u00e0 chaque fois \u2014 c&rsquo;est la d\u00e9finition m\u00eame du travail qui finit par vous exploser au visage un vendredi soir. <strong>Ansible<\/strong> automatise ce travail de fa\u00e7on reproductible, sans rien installer sur les machines g\u00e9r\u00e9es. Ce tutoriel couvre l&rsquo;installation, l&rsquo;inventaire, les commandes ad-hoc, l&rsquo;\u00e9criture de playbooks et les roles.<\/p>\n<h2>Le principe : agentless, en SSH, idempotent<\/h2>\n<p>Contrairement \u00e0 des outils comme Puppet ou Chef qui n\u00e9cessitent d&rsquo;installer un agent sur chaque machine g\u00e9r\u00e9e, Ansible fonctionne en mode <strong>agentless<\/strong> : il se connecte simplement en <strong>SSH<\/strong> (ou WinRM pour Windows) depuis un \u00ab n\u0153ud de contr\u00f4le \u00bb vers les machines cibles, ex\u00e9cute des modules Python temporaires, puis nettoie derri\u00e8re lui. Rien \u00e0 installer ni \u00e0 maintenir sur les serveurs g\u00e9r\u00e9s, \u00e0 part un client SSH et Python \u2014 d\u00e9j\u00e0 pr\u00e9sents sur l&rsquo;immense majorit\u00e9 des syst\u00e8mes Linux.<\/p>\n<p>Deuxi\u00e8me principe fondamental : l&rsquo;<strong>idempotence<\/strong>. Un playbook Ansible bien \u00e9crit peut \u00eatre ex\u00e9cut\u00e9 cent fois de suite sans effet de bord : s&rsquo;il constate qu&rsquo;un paquet est d\u00e9j\u00e0 install\u00e9 ou qu&rsquo;un fichier a d\u00e9j\u00e0 le bon contenu, il ne fait rien et le signale comme tel (\u00ab ok \u00bb, pas \u00ab changed \u00bb). C&rsquo;est ce qui permet de rejouer sereinement une configuration sans craindre de casser quelque chose qui fonctionne d\u00e9j\u00e0.<\/p>\n<figure class=\"sv-diagram\">\n<svg viewBox=\"0 0 640 260\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-labelledby=\"ansibleTitle\">\n<title id=\"ansibleTitle\">Architecture agentless d&rsquo;Ansible : un n\u0153ud de contr\u00f4le se connecte en SSH vers les machines g\u00e9r\u00e9es<\/title>\n<rect x=\"10\" y=\"10\" width=\"620\" height=\"240\" rx=\"14\" fill=\"#f4f7f5\" stroke=\"#c8d6cd\"\/>\n<rect x=\"40\" y=\"90\" width=\"150\" height=\"70\" rx=\"10\" fill=\"#eaf1ec\" stroke=\"#4a7c59\" stroke-width=\"2\"\/>\n<text x=\"115\" y=\"120\" font-size=\"11\" text-anchor=\"middle\" fill=\"#2f4f3a\" font-family=\"sans-serif\" font-weight=\"bold\">N\u0153ud de contr\u00f4le<\/text>\n<text x=\"115\" y=\"136\" font-size=\"9\" text-anchor=\"middle\" fill=\"#5a6b60\" font-family=\"sans-serif\">ansible + playbooks<\/text>\n<text x=\"115\" y=\"148\" font-size=\"9\" text-anchor=\"middle\" fill=\"#5a6b60\" font-family=\"sans-serif\">+ inventaire<\/text>\n<line x1=\"190\" y1=\"105\" x2=\"330\" y2=\"65\" stroke=\"#4a7c59\" stroke-width=\"1.5\"\/>\n<line x1=\"190\" y1=\"125\" x2=\"330\" y2=\"125\" stroke=\"#4a7c59\" stroke-width=\"1.5\"\/>\n<line x1=\"190\" y1=\"145\" x2=\"330\" y2=\"185\" stroke=\"#4a7c59\" stroke-width=\"1.5\"\/>\n<text x=\"250\" y=\"60\" font-size=\"8\" text-anchor=\"middle\" fill=\"#5a6b60\" font-family=\"sans-serif\">SSH<\/text>\n<rect x=\"330\" y=\"45\" width=\"130\" height=\"40\" rx=\"6\" fill=\"#ffffff\" stroke=\"#c8d6cd\"\/>\n<text x=\"395\" y=\"69\" font-size=\"9\" text-anchor=\"middle\" fill=\"#2f4f3a\" font-family=\"sans-serif\">web01<\/text>\n<rect x=\"330\" y=\"105\" width=\"130\" height=\"40\" rx=\"6\" fill=\"#ffffff\" stroke=\"#c8d6cd\"\/>\n<text x=\"395\" y=\"129\" font-size=\"9\" text-anchor=\"middle\" fill=\"#2f4f3a\" font-family=\"sans-serif\">web02<\/text>\n<rect x=\"330\" y=\"165\" width=\"130\" height=\"40\" rx=\"6\" fill=\"#ffffff\" stroke=\"#c8d6cd\"\/>\n<text x=\"395\" y=\"189\" font-size=\"9\" text-anchor=\"middle\" fill=\"#2f4f3a\" font-family=\"sans-serif\">db01<\/text>\n<text x=\"530\" y=\"70\" font-size=\"8\" fill=\"#5a6b60\" font-family=\"sans-serif\">Aucun agent<\/text>\n<text x=\"530\" y=\"82\" font-size=\"8\" fill=\"#5a6b60\" font-family=\"sans-serif\">\u00e0 installer<\/text>\n<text x=\"530\" y=\"130\" font-size=\"8\" fill=\"#5a6b60\" font-family=\"sans-serif\">Python + SSH<\/text>\n<text x=\"530\" y=\"142\" font-size=\"8\" fill=\"#5a6b60\" font-family=\"sans-serif\">suffisent<\/text>\n<\/svg><figcaption>Le n\u0153ud de contr\u00f4le pousse la configuration en SSH ; les machines g\u00e9r\u00e9es n&rsquo;ont besoin d&rsquo;aucun agent permanent.<\/figcaption><\/figure>\n<h2>Installation<\/h2>\n<p>Plusieurs m\u00e9thodes officielles existent ; <strong>pipx<\/strong> est aujourd&rsquo;hui la m\u00e9thode recommand\u00e9e par la documentation Ansible pour installer l&rsquo;outil dans un environnement isol\u00e9, sans polluer le Python syst\u00e8me :<\/p>\n<pre><code># Avec pipx (recommand\u00e9)\nsudo apt install pipx        # ou : python3 -m pip install --user pipx\npipx ensurepath\npipx install --include-deps ansible\n\n# Alternative : gestionnaire de paquets de la distribution\nsudo apt install ansible     # Debian\/Ubuntu\nsudo dnf install ansible     # Fedora\/RHEL\n\n# V\u00e9rification\nansible --version<\/code><\/pre>\n<p>Notez la distinction entre <strong>ansible-core<\/strong> (le moteur minimal) et le paquet <strong>ansible<\/strong> complet, qui embarque en plus une large collection de modules communautaires \u2014 le paquet complet est le plus simple pour d\u00e9marrer.<\/p>\n<h2>Pr\u00e9parer l&rsquo;acc\u00e8s SSH<\/h2>\n<ol>\n<li>G\u00e9n\u00e9rez une paire de cl\u00e9s SSH d\u00e9di\u00e9e si vous n&rsquo;en avez pas d\u00e9j\u00e0 une : <code>ssh-keygen -t ed25519<\/code>.<\/li>\n<li>Copiez la cl\u00e9 publique sur chaque machine \u00e0 g\u00e9rer : <code>ssh-copy-id utilisateur@serveur<\/code>.<\/li>\n<li>V\u00e9rifiez que vous pouvez vous connecter sans mot de passe avant d&rsquo;aller plus loin \u2014 Ansible d\u00e9pend enti\u00e8rement de cet acc\u00e8s SSH fonctionnel.<\/li>\n<\/ol>\n<h2>L&rsquo;inventaire : d\u00e9clarer vos machines<\/h2>\n<p>L&rsquo;inventaire liste les machines g\u00e9r\u00e9es, organis\u00e9es en groupes. Format INI simple (<code>inventory.ini<\/code>) :<\/p>\n<pre><code>[web]\nweb01.example.local\nweb02.example.local\n\n[db]\ndb01.example.local\n\n[production:children]\nweb\ndb<\/code><\/pre>\n<p>Un format YAML \u00e9quivalent est \u00e9galement possible et souvent pr\u00e9f\u00e9r\u00e9 dans les projets plus structur\u00e9s. Pour des infrastructures dynamiques (cloud, conteneurs), Ansible propose des <strong>inventaires dynamiques<\/strong> qui interrogent une API (AWS, Proxmox, etc.) au lieu d&rsquo;un fichier statique.<\/p>\n<h2>Commandes ad-hoc : tester avant d&rsquo;automatiser<\/h2>\n<p>Avant d&rsquo;\u00e9crire un playbook complet, une commande ad-hoc permet de v\u00e9rifier rapidement une action ponctuelle :<\/p>\n<pre><code># Tester la connectivit\u00e9\nansible all -i inventory.ini -m ping\n\n# Ex\u00e9cuter une commande shell sur un groupe\nansible web -i inventory.ini -m command -a \"uptime\"\n\n# Installer un paquet (n\u00e9cessite les droits \u00e9lev\u00e9s)\nansible web -i inventory.ini -m apt -a \"name=curl state=present\" --become<\/code><\/pre>\n<p>Le module <code>ping<\/code> ne fait pas un ping r\u00e9seau classique : il v\u00e9rifie que Python est disponible sur la cible et que la connexion SSH + les identifiants fonctionnent \u2014 un premier test indispensable apr\u00e8s toute nouvelle installation.<\/p>\n<h2>\u00c9crire un premier playbook<\/h2>\n<p>Un playbook est un fichier YAML qui d\u00e9crit un \u00e9tat d\u00e9sir\u00e9, ex\u00e9cut\u00e9 dans l&rsquo;ordre, t\u00e2che par t\u00e2che :<\/p>\n<pre><code>---\n- name: Installer et d\u00e9marrer Nginx\n  hosts: web\n  become: true\n  tasks:\n    - name: Installer le paquet nginx\n      ansible.builtin.apt:\n        name: nginx\n        state: present\n        update_cache: true\n\n    - name: D\u00e9marrer et activer le service\n      ansible.builtin.service:\n        name: nginx\n        state: started\n        enabled: true\n\n    - name: D\u00e9ployer la page d'accueil\n      ansible.builtin.template:\n        src: templates\/index.html.j2\n        dest: \/var\/www\/html\/index.html\n      notify: Recharger Nginx\n\n  handlers:\n    - name: Recharger Nginx\n      ansible.builtin.service:\n        name: nginx\n        state: reloaded<\/code><\/pre>\n<p>Ex\u00e9cution : <code>ansible-playbook -i inventory.ini site.yml<\/code>. Relancez-le une seconde fois : les t\u00e2ches d\u00e9j\u00e0 satisfaites remontent en <strong>ok<\/strong> plut\u00f4t qu&rsquo;en <strong>changed<\/strong> \u2014 c&rsquo;est l&rsquo;idempotence en action, la preuve que le playbook ne casse rien \u00e0 la relance.<\/p>\n<p>Le <strong>handler<\/strong> illustre un autre concept cl\u00e9 : une action d\u00e9clench\u00e9e uniquement si une t\u00e2che pr\u00e9c\u00e9dente a r\u00e9ellement chang\u00e9 quelque chose (ici, recharger Nginx seulement si la page a \u00e9t\u00e9 modifi\u00e9e), plut\u00f4t que de la relancer syst\u00e9matiquement \u00e0 chaque ex\u00e9cution.<\/p>\n<h2>Organiser en roles<\/h2>\n<p>D\u00e8s qu&rsquo;un playbook grossit, les <strong>roles<\/strong> permettent de d\u00e9couper la configuration en blocs r\u00e9utilisables (un role \u00ab\u00a0nginx\u00a0\u00bb, un role \u00ab\u00a0postgresql\u00a0\u00bb, un role \u00ab\u00a0durcissement-securite\u00a0\u00bb\u2026) :<\/p>\n<pre><code>ansible-galaxy init roles\/nginx<\/code><\/pre>\n<p>Cette commande g\u00e9n\u00e8re l&rsquo;arborescence standard (<code>tasks\/<\/code>, <code>handlers\/<\/code>, <code>templates\/<\/code>, <code>defaults\/<\/code>, <code>vars\/<\/code>\u2026) que vous remplissez ensuite, puis r\u00e9f\u00e9rencez depuis un playbook :<\/p>\n<pre><code>---\n- name: Configurer les serveurs web\n  hosts: web\n  become: true\n  roles:\n    - nginx<\/code><\/pre>\n<h2>Prot\u00e9ger les secrets avec ansible-vault<\/h2>\n<p>Un mot de passe de base de donn\u00e9es ou une cl\u00e9 API n&rsquo;a rien \u00e0 faire en clair dans un playbook versionn\u00e9 sur Git. <strong>ansible-vault<\/strong> chiffre le contenu sensible :<\/p>\n<pre><code># Cr\u00e9er un fichier chiffr\u00e9\nansible-vault create group_vars\/db\/vault.yml\n\n# \u00c9diter un fichier existant\nansible-vault edit group_vars\/db\/vault.yml\n\n# Ex\u00e9cuter un playbook qui r\u00e9f\u00e9rence des variables chiffr\u00e9es\nansible-playbook site.yml --ask-vault-pass<\/code><\/pre>\n<h2>Bonnes pratiques<\/h2>\n<ul>\n<li><strong>Versionnez vos playbooks dans Git<\/strong>, mais jamais le mot de passe vault en clair \u2014 utilisez un fichier de mot de passe hors d\u00e9p\u00f4t ou un gestionnaire de secrets externe.<\/li>\n<li><strong>Testez d&rsquo;abord en mode <code>--check<\/code><\/strong> (simulation \u00e0 blanc) sur un environnement non critique avant d&rsquo;ex\u00e9cuter un nouveau playbook en production.<\/li>\n<li><strong>Utilisez des tags<\/strong> (<code>--tags<\/code>) pour n&rsquo;ex\u00e9cuter qu&rsquo;une partie cibl\u00e9e d&rsquo;un long playbook pendant le d\u00e9veloppement, sans tout rejouer.<\/li>\n<li><strong>Documentez vos roles<\/strong> (README, valeurs par d\u00e9faut comment\u00e9es dans <code>defaults\/main.yml<\/code>) \u2014 un role sans documentation redevient une bo\u00eete noire d\u00e8s que quelqu&rsquo;un d&rsquo;autre (ou vous, six mois plus tard) doit le r\u00e9utiliser.<\/li>\n<\/ul>\n<p>Une fois cette base ma\u00eetris\u00e9e en ligne de commande, l&rsquo;\u00e9tape naturelle suivante pour une \u00e9quipe est de piloter ces m\u00eames playbooks depuis une interface web centralis\u00e9e avec RBAC, planification et journalisation \u2014 c&rsquo;est exactement le r\u00f4le d&rsquo;<strong>AWX<\/strong>, couvert dans le tutoriel suivant.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Configurer un serveur \u00e0 la main, puis le suivant, puis le suivant, en esp\u00e9rant avoir fait exactement les m\u00eames commandes \u00e0 chaque fois \u2014 c&rsquo;est la d\u00e9finition m\u00eame du travail qui finit par vous exploser au visage un vendredi soir. Ansible automatise ce travail de fa\u00e7on reproductible, sans rien installer sur les machines g\u00e9r\u00e9es. Ce [&hellip;]<\/p>\n","protected":false},"featured_media":0,"template":"","sv_tuto_categorie":[22],"class_list":["post-189","sv_tutoriel","type-sv_tutoriel","status-publish","hentry","sv_tuto_categorie-infrastructure"],"_links":{"self":[{"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/sv_tutoriel\/189","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/sv_tutoriel"}],"about":[{"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/types\/sv_tutoriel"}],"version-history":[{"count":1,"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/sv_tutoriel\/189\/revisions"}],"predecessor-version":[{"id":191,"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/sv_tutoriel\/189\/revisions\/191"}],"wp:attachment":[{"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/media?parent=189"}],"wp:term":[{"taxonomy":"sv_tuto_categorie","embeddable":true,"href":"https:\/\/asfy.fr\/index.php\/wp-json\/wp\/v2\/sv_tuto_categorie?post=189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}