
Pour piloter du parc AWS depuis Ansible, le plugin amazon.aws.aws_ec2 est le standard de fait. Il interroge l'API AWS et retourne toutes vos instances EC2 d'une région ou d'un compte, groupées automatiquement par tag, par VPC, par AZ. C'est le plugin officiel maintenu par Red Hat.
Cette page est didactique, sans lab pratique car AWS suppose un compte cloud et engendre de la facturation. Elle vous donne les patterns à appliquer le jour où vous gérez un parc AWS depuis Ansible.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Configurer le plugin
amazon.aws.aws_ec2(région, filtres, credentials). - Grouper automatiquement les instances par tag, par VPC, par état.
- Combiner avec un inventaire statique pour les hôtes on-prem.
- Comprendre les bonnes pratiques sécurité (IAM role > clés statiques).
- Anticiper les pièges courants (rate limiting, multi-région).
Prérequis
Section intitulée « Prérequis »- Compte AWS avec instances EC2 lancées.
amazon.awscollection installée.- Credentials AWS configurés (variables d'env ou IAM role sur le control node).
- Avoir lu Concepts des plugins d'inventaire.
Installation et activation
Section intitulée « Installation et activation »Deux installations distinctes sont nécessaires, et confondre les deux est la cause d'échec la plus fréquente. La collection amazon.aws apporte le code du plugin côté Ansible ; les bibliothèques Python boto3 et botocore portent le dialogue avec l'API AWS. Elles doivent être installées dans l'interpréteur Python qu'utilise Ansible, pas dans un autre environnement virtuel, sinon le plugin remonte boto3 module not found alors que pip list montre bien le paquet.
ansible-galaxy collection install amazon.awspip install boto3 botocoreLe plugin nécessite boto3 et botocore côté control node. Activer dans ansible.cfg :
[inventory]enable_plugins = host_list, script, auto, yaml, ini, amazon.aws.aws_ec2Configuration minimale
Section intitulée « Configuration minimale »Le nom du fichier n'est pas libre. Le plugin ne se déclenche que sur un fichier dont le nom se termine par aws_ec2.yml ou aws_ec2.yaml : inventory/aws_ec2.yml convient, production.aws_ec2.yml aussi, mais inventory/ec2.yml sera ignoré sans message d'erreur. Créer inventory/aws_ec2.yml :
---plugin: amazon.aws.aws_ec2regions: - eu-west-3Tester :
ansible-inventory -i inventory/aws_ec2.yml --graphToutes vos instances EC2 de la région eu-west-3 apparaissent. Par défaut, elles sont nommées par leur instance_id (ex: i-0abc123def456).
Donner aux instances un nom lisible
Section intitulée « Donner aux instances un nom lisible »Par défaut, l'instance s'appelle i-0abc.... Pour utiliser le tag Name (ce que vous voyez dans la console AWS) :
plugin: amazon.aws.aws_ec2regions: - eu-west-3hostnames: - tag:Name - dns-name - private-ip-addresshostnames: est une liste : Ansible essaie le premier critère, puis le second si le premier est vide. Ici : tag Name en priorité, sinon DNS public, sinon IP privée.
Grouper par tag (le plus utile)
Section intitulée « Grouper par tag (le plus utile) »Les tags AWS sont la clé d'un parc bien organisé. Le plugin les expose automatiquement :
plugin: amazon.aws.aws_ec2regions: - eu-west-3
keyed_groups: # Un groupe par valeur du tag Environment (prod, staging, dev) - prefix: env key: tags.Environment
# Un groupe par valeur du tag Role (web, db, lb) - prefix: role key: tags.Role
# Groupes hiérarchiques par région et AZ - prefix: region key: placement.region - prefix: az key: placement.availability_zoneRésultat : ansible-inventory --graph montre :
@all: |--@env_prod: | |--web1.example.com | |--db1.example.com |--@env_staging: | |--web-staging.example.com |--@role_web: | |--web1.example.com | |--web-staging.example.com |--@role_db: | |--db1.example.com |--@region_eu-west-3: | |--... (toutes les instances) |--@az_eu-west-3a: | |--web1.example.comVous pouvez maintenant cibler env_prod:&role_web pour déployer uniquement sur les webservers de prod.
Filtres, réduire la liste
Section intitulée « Filtres, réduire la liste »Si vous avez 500 instances dont seulement 50 vous concernent, filtrer côté API plutôt que côté playbook change le temps de réponse : AWS ne renvoie que les instances retenues, et le plugin n'a pas à construire des groupes que personne n'utilisera. Les clés utilisées ici sont celles de l'API EC2, pas des noms Ansible : instance-state-name, vpc-id, ou tag:<Nom> pour un tag précis.
plugin: amazon.aws.aws_ec2regions: - eu-west-3
filters: # Uniquement les instances en cours d'exécution instance-state-name: running
# Uniquement celles tagged Environment=prod tag:Environment: prod
# Uniquement celles dans un VPC spécifique vpc-id: vpc-0123abcdefAvantage : moins de payload réseau, plus rapide, et vos collègues qui regardent l'inventaire ne voient pas les instances qui ne les concernent pas.
Credentials AWS, les bonnes pratiques
Section intitulée « Credentials AWS, les bonnes pratiques »À proscrire, les clés dans le fichier
Section intitulée « À proscrire, les clés dans le fichier »plugin: amazon.aws.aws_ec2aws_access_key_id: AKIAIOSFODNN7EXAMPLE # ← clés en clair !aws_secret_access_key: wJalrXUtnFEMI/K7MDENG/EXAMPLEJamais de clés en clair dans le fichier d'inventaire, qui finit dans Git, dans les logs CI, partagé en équipe.
Variables d'environnement
Section intitulée « Variables d'environnement »Acceptable pour un poste de développement ou un job CI où la plateforme injecte les valeurs. Deux limites à connaître : les variables restent visibles dans l'environnement de tous les processus enfants lancés depuis ce shell, et un export tapé à la main atterrit dans l'historique du shell. Préfixez la ligne d'un espace ou passez par un fichier sourcé hors du dépôt.
export AWS_ACCESS_KEY_ID=AKIA...export AWS_SECRET_ACCESS_KEY=...export AWS_REGION=eu-west-3ansible-inventory -i inventory/aws_ec2.yml --listAWS Profile
Section intitulée « AWS Profile »plugin: amazon.aws.aws_ec2aws_profile: productionregions: - eu-west-3Le fichier d'inventaire ne contient alors qu'un nom de profil, ce qui le rend commitable sans risque : les secrets vivent dans ~/.aws/credentials, hors du dépôt, avec des permissions 0600. C'est aussi la solution la plus pratique quand vous jonglez entre plusieurs comptes AWS, puisque changer de compte revient à changer une seule ligne.
Avec ~/.aws/credentials :
[production]aws_access_key_id = AKIA...aws_secret_access_key = ...IAM Role (control node sur EC2)
Section intitulée « IAM Role (control node sur EC2) »Si Ansible tourne sur une instance EC2, attacher un IAM role à cette instance avec une policy EC2:Describe*. Pas de clés à gérer du tout, l'instance reçoit ses credentials via le metadata service AWS.
plugin: amazon.aws.aws_ec2regions: - eu-west-3# Pas de credentials : l'IAM role est utilisé automatiquementC'est le pattern le plus sûr en production.
Variables exposées par le plugin
Section intitulée « Variables exposées par le plugin »Pour chaque instance, le plugin expose un dict de facts très riche, accessible dans vos playbooks :
- name: Afficher l'IP privée de chaque webserver hosts: env_prod:&role_web tasks: - name: Afficher les attributs EC2 de l'hôte ansible.builtin.debug: msg: | {{ inventory_hostname }} : - private IP : {{ private_ip_address }} - public IP : {{ public_ip_address | default('aucune') }} - instance ID: {{ instance_id }} - VPC : {{ vpc_id }} - AZ : {{ placement.availability_zone }} - tag Owner : {{ tags.Owner | default('non défini') }}Les noms de ces variables viennent directement de la réponse de l'API DescribeInstances, convertie du CamelCase de l'API vers le snake_case d'Ansible : PrivateIpAddress devient private_ip_address, VpcId devient vpc_id. Aucun préfixe n'est ajouté par défaut, d'où le risque de collision avec vos propres variables de playbook ; l'option hostvars_prefix: 'aws_' du plugin permet de les isoler si besoin. Les tags font exception à la conversion : leurs clés gardent la casse d'origine, d'où tags.Environment et non tags.environment.
Cache, éviter de marteler l'API
Section intitulée « Cache, éviter de marteler l'API »Sur un compte avec 200+ instances, chaque commande Ansible déclenche une API call DescribeInstances. Au-delà de quelques runs/min, AWS rate-limit. Activer le cache :
plugin: amazon.aws.aws_ec2regions: - eu-west-3
cache: truecache_plugin: jsonfilecache_timeout: 600 # 10 minutescache_connection: /tmp/ansible_aws_ec2_cachePour rafraîchir après création d'instances :
ansible-inventory -i inventory/aws_ec2.yml --list --refresh-cacheMulti-région
Section intitulée « Multi-région »Pour gérer un parc multi-région :
plugin: amazon.aws.aws_ec2regions: - eu-west-3 - us-east-1 - ap-southeast-1Toutes les instances des 3 régions sont fusionnées en un seul inventaire. Le keyed_groups: region les groupe automatiquement par région.
Combiner avec un inventaire on-prem
Section intitulée « Combiner avec un inventaire on-prem »Pattern courant : on-prem (statique) + AWS (dynamique) dans le même run :
inventory/├── 01-static.yml ← serveurs on-prem└── 02-aws_ec2.yml ← plugin AWSansible-playbook -i inventory/ playbook.ymlLe playbook.yml peut cibler webservers (groupe défini dans le statique on-prem) et env_prod (groupe AWS) sans problème.
Pièges courants
Section intitulée « Pièges courants »Les deux premières lignes concernent l'environnement Python et les credentials : elles se manifestent au tout premier appel, avant même que l'API AWS soit contactée. Les suivantes apparaissent plus tard, quand l'inventaire fonctionne mais ne remonte pas ce que vous attendez. Dans ce second cas, le réflexe utile est ansible-inventory --list -vvv, qui affiche l'appel API exact envoyé par le plugin, filtres compris.
| Symptôme | Cause | Fix |
|---|---|---|
boto3 module not found | Module Python manquant | pip install boto3 botocore |
Unable to locate credentials | Pas de credentials configurés | Variables d'env ou aws_profile: ou IAM role |
RequestLimitExceeded (429) | Trop d'API calls (rate limit) | Activer le cache (cache: true) |
| Instances absentes | Filtre trop restrictif | --list -vvv pour voir l'API call exacte |
Hostname = i-0abc... | Pas de hostnames: configuré | hostnames: [tag:Name, ...] |
| Multi-région lent | Une seule call par région | Préférer un cache long (>= 600s) |
Comparaison rapide
Section intitulée « Comparaison rapide »Ce tableau situe le plugin AWS face aux deux autres sources dynamiques couvertes dans cette section. La ligne à regarder en premier est « Retourne IP ? » : elle décide si vous pouvez lancer un playbook immédiatement après la découverte, ou s'il vous faudra une étape intermédiaire pour résoudre les adresses. La ligne « Groupage » vient ensuite, car c'est elle qui détermine la quantité de configuration manuelle à écrire pour obtenir des groupes exploitables.
| Critère | AWS EC2 | libvirt | Proxmox |
|---|---|---|---|
| Setup | Cloud + IAM | Local libvirt | Token API |
| Coût | Cloud bill | Zéro | Zéro |
| Retourne IP ? | Oui (privée + publique) | Non sans QEMU agent | Oui |
| Groupage | Tags AWS | Manuel via groups: | Tags Proxmox |
| Multi-source | Oui (multi-région) | Limité au host local | Limité au cluster |
À retenir
Section intitulée « À retenir »amazon.aws.aws_ec2= standard pour Ansible + AWS. Maintenu par Red Hat.hostnames:= utiliser le tagNameau lieu de l'instance ID pour des hostnames lisibles.keyed_groups:sur les tags AWS = pattern n°1 pour grouper automatiquement.filters:réduire le payload côté API pour les gros parcs.- Credentials : IAM role > AWS profile > variables d'env > jamais en clair dans le YAML.
- Cache mandatory au-delà de quelques runs/min (rate limit AWS).
- Multi-région supportée nativement via
regions:liste.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Plugin NetBox : agréger plusieurs clouds et le bare-metal dans une source unique, quand les tags AWS ne suffisent plus.
- Écrire un script custom : le recours pour un fournisseur cloud sans plugin maintenu.
- Trouver le bon module : la collection
amazon.awss'installe comme les autres, avec les mêmes garde-fous supply chain.