Ansible Dynamic Inventory es la solución definitiva para gestionar infraestructuras cloud que cambian constantemente. En esta guía completa, aprenderás a configurar inventarios dinámicos para AWS, Azure y GCP, eliminando la gestión manual de hosts y permitiendo que tu infraestructura se autodescubra automáticamente.
Si trabajas con entornos cloud donde los servidores se crean y destruyen continuamente, mantener un inventario estático es una tarea imposible y propensa a errores. Los inventarios dinámicos de Ansible resuelven este problema consultando las APIs de tus proveedores cloud en tiempo real.
¿Qué es Ansible Dynamic Inventory?
Ansible Dynamic Inventory es un sistema de plugins que permite a Ansible obtener información de hosts directamente desde fuentes externas en tiempo de ejecución, en lugar de depender de archivos estáticos. Esto significa que cada vez que ejecutas un playbook, Ansible consulta automáticamente tus proveedores cloud para obtener la lista actualizada de instancias.
A diferencia de los inventarios estáticos tradicionales (archivos INI o YAML con IPs hardcodeadas), los inventarios dinámicos se adaptan automáticamente a los cambios de infraestructura. Cuando lanzas nuevas instancias EC2 o eliminas máquinas virtuales en Azure, tu inventario se actualiza sin intervención manual.
Según la documentación oficial de Ansible sobre inventarios dinámicos, este enfoque es esencial cuando tu infraestructura fluctúa constantemente en respuesta a las demandas del negocio.
Casos de Uso Principales
- Auto-scaling en AWS: Gestionar instancias EC2 que se crean/destruyen según demanda
- Entornos multi-cloud: Combinar infraestructura de AWS, Azure y GCP en un solo inventario
- Infraestructura efímera: Ambientes de desarrollo/testing que cambian frecuentemente
- Contenedores y Kubernetes: Descubrir pods y nodos dinámicamente
- Compliance y auditoría: Garantizar que la automatización alcanza todos los recursos activos
Ventajas de Ansible Dynamic Inventory vs Inventario Estático
Los inventarios dinámicos ofrecen beneficios significativos sobre los estáticos, especialmente en infraestructuras cloud modernas:
| Característica | Inventario Estático | Ansible Dynamic Inventory |
|---|---|---|
| Actualización | Manual (archivos INI/YAML) | Automática vía API |
| Escalabilidad | Limitada (mantenimiento complejo) | Ilimitada (sigue infraestructura) |
| Precisión | Propensa a errores humanos | Siempre sincronizada |
| Metadatos | Manualmente añadidos | Tags y variables del cloud |
| Multi-cloud | Archivos separados complejos | Plugins combinables nativamente |
Si gestionas más de 10 servidores en cloud o trabajas con auto-scaling, un inventario dinámico reduce drásticamente el tiempo de mantenimiento y elimina configuraciones obsoletas que causan fallos en deployments.
Arquitectura de Ansible Dynamic Inventory
La arquitectura de Ansible Dynamic Inventory se basa en plugins que actúan como puentes entre Ansible y las APIs de proveedores cloud. Cuando ejecutas un playbook, el flujo es el siguiente:
- Ansible lee la configuración del plugin (archivo
*.aws_ec2.yml,*.azure_rm.yml, etc.) - El plugin consulta la API del proveedor (AWS EC2, Azure Resource Manager, GCP Compute)
- Obtiene la lista de instancias activas con sus metadatos (tags, región, tipo de instancia)
- Crea grupos dinámicos basados en criterios configurados (por tags, zonas, security groups)
- Ansible ejecuta el playbook contra los hosts descubiertos
Componentes Clave
- Inventory Plugins: Módulos modernos recomendados (
amazon.aws.aws_ec2,azure.azcollection.azure_rm,google.cloud.gcp_compute) - Archivos de configuración YAML: Definen parámetros como regiones, filtros y agrupaciones
- Autenticación: Credenciales cloud (IAM roles, service accounts, managed identities)
- Caché opcional: Reduce llamadas API para mejorar rendimiento
Para entender mejor cómo integrar Ansible con infraestructura cloud, consulta nuestro artículo sobre Ansible Terraform para automatización completa de infraestructura cloud.
Requisitos Previos para Ansible Dynamic Inventory
Antes de configurar inventarios dinámicos, necesitas:
Software y Versiones
- Ansible Core: Versión 2.10 o superior (recomendado 2.14+)
- Python: 3.6 o superior (preferible 3.9+)
- SDK del proveedor cloud:
- AWS:
boto3 >= 1.34.0ybotocore >= 1.34.0 - Azure:
azure-mgmt-compute,azure-identity - GCP:
google-auth,google-cloud-compute
- AWS:
Credenciales y Permisos
Cada proveedor cloud requiere credenciales con permisos específicos. La documentación del plugin aws_ec2 de Ansible detalla los requisitos de autenticación para AWS:
- AWS: IAM user/role con políticas
ec2:DescribeInstances,ec2:DescribeTags,ec2:DescribeRegions - Azure: Service Principal con rol Reader en la suscripción
- GCP: Service Account con rol Compute Viewer
Instalación de Colecciones Ansible
# Instalar colección AWS ansible-galaxy collection install amazon.aws # Instalar colección Azure ansible-galaxy collection install azure.azcollection # Instalar colección GCP ansible-galaxy collection install google.cloud # Instalar dependencias Python para AWS pip3 install boto3 botocore # Instalar dependencias Python para Azure pip3 install azure-mgmt-compute azure-identity azure-mgmt-network # Instalar dependencias Python para GCP pip3 install google-auth google-cloud-compute Configurar Ansible Dynamic Inventory para AWS EC2
Vamos a crear un inventario dinámico para AWS EC2 que descubra instancias automáticamente. Este es el caso de uso más común para Ansible Dynamic Inventory.
Paso 1: Crear Archivo de Configuración
Crea un archivo llamado aws_ec2.yml en tu directorio de inventario:
# aws_ec2.yml plugin: amazon.aws.aws_ec2 # Regiones a consultar (vacío = todas las regiones) regions: - us-east-1 - us-west-2 - eu-west-1 # Filtros de instancias (solo instancias running) filters: instance-state-name: running tag:Environment: production # Excluir instancias específicas exclude_filters: - tag:Exclude: "true" # Definir hostname de las instancias hostnames: - tag:Name - dns-name - private-ip-address # Crear grupos dinámicos basados en tags keyed_groups: # Agrupar por tag Environment - key: tags.Environment prefix: env separator: "_" # Agrupar por tipo de instancia - key: instance_type prefix: instance_type # Agrupar por zona de disponibilidad - key: placement.availability_zone prefix: az # Componer variables personalizadas compose: ansible_host: public_ip_address ansible_user: "'ec2-user'" # Habilitar caché (300 segundos = 5 minutos) cache: true cache_plugin: jsonfile cache_timeout: 300 cache_connection: /tmp/ansible-aws-inventory-cache Paso 2: Configurar Autenticación AWS
Existen varias opciones para autenticación. La más segura es usar IAM roles cuando ejecutas Ansible desde una instancia EC2. Puedes consultar la documentación oficial de AWS IAM Roles para más detalles:
# Opción 1: Usar AWS Profile (recomendado para desarrollo) # Añade al aws_ec2.yml: # profile: my-aws-profile # Opción 2: Variables de entorno export AWS_ACCESS_KEY_ID="your-access-key" export AWS_SECRET_ACCESS_KEY="your-secret-key" export AWS_DEFAULT_REGION="us-east-1" # Opción 3: IAM Instance Role (recomendado para producción) # No requiere configuración adicional si el control node # es una instancia EC2 con rol IAM asignado Paso 3: Verificar el Inventario Dinámico
# Listar todos los hosts descubiertos ansible-inventory -i aws_ec2.yml --list # Ver hosts en formato gráfico ansible-inventory -i aws_ec2.yml --graph # Verificar un host específico ansible-inventory -i aws_ec2.yml --host i-0123456789abcdef0 # Probar conectividad con todos los hosts ansible all -i aws_ec2.yml -m ping Si tienes instancias EC2 tagueadas como Environment=production, aparecerán en el grupo env_production. Esto permite ejecutar playbooks solo contra subconjuntos específicos de tu infraestructura.
Configurar Ansible Dynamic Inventory para Azure
Azure Resource Manager proporciona su propio plugin de inventario dinámico. La configuración es similar a AWS pero usa conceptos específicos de Azure como Resource Groups y Subscriptions. Consulta la guía oficial de Microsoft para inventarios dinámicos de Azure.
Archivo de Configuración Azure
# azure_rm.yml plugin: azure.azcollection.azure_rm # Autenticación (usar Service Principal o Managed Identity) auth_source: auto # Filtrar por suscripciones específicas include_vm_resource_groups: - production-rg - staging-rg # Condiciones de filtrado conditional_groups: linux: "'Linux' in image.offer" windows: "'Windows' in image.offer" # Agrupar por tags keyed_groups: - prefix: tag key: tags - prefix: location key: location - prefix: vmsize key: vm_size # Componer variables compose: ansible_host: public_ipv4_addresses[0] | default(private_ipv4_addresses[0]) ansible_user: admin_username # Caché cache: true cache_plugin: jsonfile cache_timeout: 300 Autenticación en Azure
# Crear Service Principal az ad sp create-for-rbac --name ansible-sp --role Reader # Exportar credenciales export AZURE_SUBSCRIPTION_ID="your-subscription-id" export AZURE_CLIENT_ID="your-client-id" export AZURE_SECRET="your-client-secret" export AZURE_TENANT="your-tenant-id" # Verificar inventario ansible-inventory -i azure_rm.yml --graph Configurar Ansible Dynamic Inventory para GCP
Google Cloud Platform utiliza el plugin gcp_compute para descubrir instancias de Compute Engine. Revisa la documentación oficial de Google Cloud sobre Ansible para configuración detallada.
# gcp_compute.yml plugin: google.cloud.gcp_compute # Proyecto GCP projects: - my-production-project - my-staging-project # Filtros de instancias filters: - status = RUNNING - labels.environment = production # Autenticación con Service Account auth_kind: serviceaccount service_account_file: /path/to/service-account-key.json # Regiones y zonas regions: - us-central1 - europe-west1 # Agrupar por labels keyed_groups: - key: labels prefix: label - key: zone prefix: zone - key: machineType prefix: machine_type # Variables personalizadas compose: ansible_host: networkInterfaces[0].accessConfigs[0].natIP | default(networkInterfaces[0].networkIP) ansible_user: "'ansible'" cache: true cache_plugin: jsonfile cache_timeout: 300 Mejores Prácticas para Ansible Dynamic Inventory
Optimiza tu configuración de Ansible Dynamic Inventory siguiendo estas recomendaciones:
1. Usar Tags de Forma Estratégica
Los tags son la base de la organización en inventarios dinámicos. Establece una convención de naming consistente:
# Ejemplo de estructura de tags AWS Environment: production | staging | development Role: web | database | cache | worker Application: app1 | app2 | app3 Owner: team-platform | team-data Backup: daily | weekly | none Con esta estructura, puedes crear grupos automáticos como env_production_role_web que facilitan targeting específico en playbooks.
2. Habilitar Caché para Rendimiento
Las consultas API pueden ser lentas con miles de instancias. El caché reduce latencia significativamente:
cache: true cache_plugin: jsonfile cache_timeout: 300 # 5 minutos # Para pipelines CI/CD, usa timeout corto (60s) # Para playbooks manuales, usa timeout largo (600s) 3. Combinar Inventarios Estáticos y Dinámicos
Puedes mezclar ambos tipos en un directorio de inventario:
inventory/ ├── aws_ec2.yml # Inventario dinámico AWS ├── azure_rm.yml # Inventario dinámico Azure ├── static_hosts.yml # Hosts on-premise └── group_vars/ ├── all.yml └── production.yml # Usar todo el inventario ansible-playbook -i inventory/ site.yml 4. Validar Permisos Mínimos
Sigue el principio de least privilege. Para AWS, una política IAM mínima es:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:DescribeTags", "ec2:DescribeRegions" ], "Resource": "*" } ] } 5. Usar Filtros para Reducir Ruido
Excluye instancias irrelevantes desde el inicio:
filters: instance-state-name: running # Solo instancias activas tag:Managed: ansible # Solo instancias gestionadas por Ansible exclude_filters: - tag:Exclude: "true" # Excluir explícitamente - tag:Environment: sandbox # Ignorar sandboxes Si además utilizas Kubernetes, combina inventarios dinámicos con nuestra guía de Ansible Kubernetes para automatizar clusters de contenedores.
Uso Avanzado de Ansible Dynamic Inventory
Grupos Condicionales Complejos
Crea grupos basados en lógica avanzada con Jinja2:
# aws_ec2.yml keyed_groups: # Agrupar por combinación de tags - key: tags.Environment + "_" + tags.Role prefix: app separator: "" # Agrupar solo instancias grandes - key: instance_type prefix: large parent_group: large_instances groups: critical_servers: "'production' in tags.Environment and 'database' in tags.Role" development: "tags.Environment == 'dev'" Variables Personalizadas con Compose
compose: # Usar IP privada si no hay pública ansible_host: public_ip_address | default(private_ip_address) # Usuario SSH según OS ansible_user: >- 'ubuntu' if 'ubuntu' in image.name | lower else 'ec2-user' # Puerto SSH customizado por tag ansible_port: tags.SSHPort | default(22) # Variables de aplicación desde tags app_version: tags.Version | default('latest') deployment_tier: tags.Tier | default('standard') Integración con Route53 y DNS
Para AWS, puedes resolver nombres DNS desde Route53:
# aws_ec2.yml hostnames: - tag:Name - dns-name # Habilitar resolución Route53 use_contrib_script_compatible_sanitization: true # Usar FQDN como hostname compose: ansible_host: public_dns_name if public_dns_name else public_ip_address Multi-Cloud con Inventario Unificado
Combina múltiples clouds en un directorio:
inventory/ ├── aws_ec2.yml ├── azure_rm.yml ├── gcp_compute.yml └── group_vars/ └── all.yml # Ejecutar contra todos los clouds ansible-playbook -i inventory/ site.yml # Ejecutar solo AWS ansible-playbook -i inventory/aws_ec2.yml site.yml # Ejecutar solo producción en todos los clouds ansible-playbook -i inventory/ site.yml --limit env_production Para gestionar secretos de forma segura en entornos multi-cloud, revisa nuestro tutorial de Ansible Vault GitOps para automatizar secretos dinámicos.
Troubleshooting Ansible Dynamic Inventory
Error: «Unable to parse inventory file»
Causa: Archivo de configuración con sintaxis YAML incorrecta o plugin no instalado.
# Verificar sintaxis YAML yamllint aws_ec2.yml # Verificar que el plugin esté disponible ansible-doc -t inventory amazon.aws.aws_ec2 # Si falta el plugin, reinstalar colección ansible-galaxy collection install amazon.aws --force Error: «Failed to authenticate with AWS»
Causa: Credenciales AWS incorrectas o permisos insuficientes.
# Verificar credenciales aws sts get-caller-identity # Probar permisos EC2 aws ec2 describe-instances --region us-east-1 --max-results 5 # Verificar versión boto3 python3 -c "import boto3; print(boto3.__version__)" # Actualizar boto3 pip3 install --upgrade boto3 botocore Error: «No hosts matched»
Causa: Filtros demasiado restrictivos o instancias sin tags esperados.
# Listar inventario completo sin filtros ansible-inventory -i aws_ec2.yml --list | jq '.[]' # Verificar filtros aplicados ansible-inventory -i aws_ec2.yml --list | jq '._meta.hostvars' # Temporalmente comentar filtros en aws_ec2.yml # filters: # instance-state-name: running Error: «Connection timeout»
Causa: Configuración de hostname incorrecta (IP privada cuando necesitas pública).
# Verificar qué IP se asigna ansible-inventory -i aws_ec2.yml --host i-xxxxx | jq '.ansible_host' # Forzar uso de IP pública compose: ansible_host: public_ip_address # O permitir fallback compose: ansible_host: public_ip_address | default(private_ip_address) Error: «Rate limit exceeded»
Causa: Demasiadas llamadas API sin caché.
# Habilitar caché agresiva cache: true cache_plugin: jsonfile cache_timeout: 3600 # 1 hora cache_connection: /tmp/ansible-inventory-cache # Reducir regiones consultadas regions: - us-east-1 # Solo región principal # Limitar por VPC o subnet filters: vpc-id: vpc-12345678 Integración con Ansible Tower y AWX
Ansible Dynamic Inventory se integra perfectamente con Ansible Tower (Red Hat) y AWX (versión open source). Según la documentación oficial de AWX en GitHub, esto permite sincronización automática de inventarios en entornos enterprise:
- Crear Credential Type en AWX para tu cloud provider (AWS, Azure, GCP)
- Configurar Inventory Source con el plugin dinámico
- Programar sincronización automática (cada 15 minutos, 1 hora, etc.)
- Usar variables de inventario en Job Templates
Esta integración es especialmente útil para equipos grandes donde múltiples usuarios ejecutan playbooks contra infraestructura compartida.
Ejemplo Práctico: Playbook con Ansible Dynamic Inventory
Vamos a crear un playbook completo que use inventario dinámico para actualizar servidores web en AWS:
# deploy_web_app.yml --- - name: Deploy application to web servers in production hosts: env_production_role_web # Grupo dinámico generado por tags gather_facts: true become: true vars: app_version: "{{ lookup('env', 'APP_VERSION') | default('latest') }}" health_check_url: "http://{{ ansible_host }}:8080/health" pre_tasks: - name: Verify host is reachable wait_for_connection: timeout: 30 - name: Gather instance metadata from AWS tags set_fact: deployment_id: "{{ tags.DeploymentId | default('manual') }}" backup_enabled: "{{ tags.Backup | default('none') }}" tasks: - name: Stop application service systemd: name: webapp state: stopped - name: Backup current version if enabled archive: path: /opt/webapp dest: "/var/backups/webapp-{{ ansible_date_time.iso8601_basic_short }}.tar.gz" when: backup_enabled == 'daily' - name: Download new application version get_url: url: "https://releases.example.com/webapp-{{ app_version }}.tar.gz" dest: /tmp/webapp.tar.gz checksum: "sha256:https://releases.example.com/webapp-{{ app_version }}.sha256" - name: Extract application unarchive: src: /tmp/webapp.tar.gz dest: /opt/webapp remote_src: true owner: webapp group: webapp - name: Start application service systemd: name: webapp state: started enabled: true - name: Wait for application to be healthy uri: url: "{{ health_check_url }}" status_code: 200 register: health_check until: health_check.status == 200 retries: 10 delay: 5 post_tasks: - name: Report deployment success debug: msg: "Deployment {{ deployment_id }} completed successfully on {{ inventory_hostname }} ({{ ansible_host }})" # Ejecutar playbook # ansible-playbook -i aws_ec2.yml deploy_web_app.yml -e "APP_VERSION=v2.5.0" Este playbook aprovecha las capacidades de Ansible Dynamic Inventory para:
- Targetear automáticamente servidores web de producción mediante tags
- Acceder a metadatos de instancias (tags) para configuración condicional
- Escalar horizontalmente sin modificar el playbook (nuevas instancias se descubren automáticamente)
Para optimizar la monitorización de estos despliegues, combínalo con Ansible Prometheus para automatizar la monitorización completa.
Conclusión
Ansible Dynamic Inventory es una herramienta imprescindible para gestionar infraestructuras cloud modernas. Elimina la gestión manual de hosts, reduce errores operativos y permite que tus automatizaciones escalen junto con tu infraestructura.
Los beneficios clave que has aprendido incluyen:
- Sincronización automática con APIs de AWS, Azure y GCP
- Agrupación dinámica basada en tags y metadatos cloud
- Flexibilidad multi-cloud combinando múltiples proveedores
- Reducción de mantenimiento al eliminar archivos estáticos obsoletos
- Mejor compliance garantizando que todos los recursos activos están gestionados
Implementar inventarios dinámicos requiere una inversión inicial en configuración, pero el retorno se materializa rápidamente en entornos con más de 10 servidores o infraestructura que cambia frecuentemente. Con las mejores prácticas de caché, filtrado y agrupación por tags, puedes gestionar miles de instancias de forma eficiente.
Los próximos pasos recomendados incluyen integrar inventarios dinámicos con Ansible Tower/AWX para centralización enterprise, combinar con Ansible GitOps para gestión declarativa, y explorar plugins de inventario para otras plataformas como VMware, OpenStack o Docker.
Preguntas Frecuentes sobre Ansible Dynamic Inventory
¿Qué versión de Ansible necesito para inventarios dinámicos?
Se recomienda Ansible Core 2.10 o superior. Los inventory plugins modernos (recomendados sobre scripts legacy) requieren Ansible 2.9+. Para mejores características y rendimiento, usa Ansible 2.14 o posterior.
¿Los inventarios dinámicos funcionan con Ansible Tower?
Sí, tanto Ansible Tower (Red Hat) como AWX (open source) soportan inventarios dinámicos nativamente. Puedes configurar sincronización automática programada y gestionar credenciales cloud de forma centralizada mediante Credential Types.
¿Cómo gestiono secretos con inventarios dinámicos?
Las credenciales cloud (AWS keys, Azure service principals, GCP service accounts) deben gestionarse mediante:
- Variables de entorno en desarrollo
- IAM roles/Managed identities en producción (recomendado)
- Ansible Vault para archivos de service accounts
- HashiCorp Vault o AWS Secrets Manager para gestión enterprise
¿Puedo combinar inventarios estáticos y dinámicos?
Absolutamente. Ansible permite usar directorios de inventario que mezclan archivos estáticos (.ini, .yml) con plugins dinámicos (*.aws_ec2.yml, *.azure_rm.yml). Esto es útil para combinar infraestructura cloud con servidores on-premise.
¿Cómo optimizo el rendimiento con miles de instancias?
Implementa estas optimizaciones:
- Habilita caché con timeout apropiado (300-600 segundos)
- Usa filtros restrictivos por región, VPC o tags
- Limita regiones consultadas solo a las necesarias
- Incrementa paralelización con
forksen ansible.cfg - Desactiva fact gathering si no es necesario (
gather_facts: false)
¿Qué pasa si hay conflictos de nombres de host entre clouds?
Usa compose para crear nombres únicos combinando metadatos:
compose: inventory_hostname: cloud_provider + "_" + region + "_" + instance_id ansible_host: public_ip_address Esto genera nombres como aws_us-east-1_i-0123456789 y azure_eastus_vm-prod-web-01 que son únicos globalmente.
