- Escribe tareas de automatización de servidores en código Python y ejecútalas en paralelo por SSH, realizando comandos de forma idempotente sin agentes
- pyinfra afirma ser 6 veces más rápido que Ansible en la misma carga de trabajo, usando ejecución concurrente basada en gevent y SSH
- Con la opción
--drypuedes revisar el diff de cambios por host antes de aplicar, y en la ejecución real los resultados regresan en streaming paralelo - En los hosts de destino solo se necesita shell y SSH; no hay demonios, archivos de estado ni plano de control
- Destaca una configuración centrada en código que usa directamente bucles y condicionales de Python, en lugar de codificar el flujo de control en YAML
Funciones clave y flujo de ejecución
-
Automatización de miles de servidores
- pyinfra es una herramienta de automatización agentless nativa de Python que ejecuta comandos por SSH
- La ejecución de comandos pone énfasis en concurrencia, idempotencia y velocidad, y afirma ser 6 veces más rápido que Ansible en la misma carga de trabajo
- El comando de instalación es
$ uv tool install pyinfra - Los requisitos base indicados son MIT license, Python 3.10 o superior, no agents y zero config
-
Ejemplo de código de despliegue
- Importa las operaciones
apt,filesysystemdcomo código Python para instalar paquetes, desplegar plantillas y recargar servicios - El código de ejemplo instala los paquetes
nginxycertbot, y despliegatemplates/nginx.conf.j2en/etc/nginx/sites-enabled/api - En el último paso recarga el servicio
nginxconsystemd.service("nginx", reloaded=True)
from pyinfra.operations import apt, files, systemd apt.packages( packages=["nginx", "certbot"], update=True, ) files.template( src="templates/nginx.conf.j2", dest="/etc/nginx/sites-enabled/api", ) systemd.service("nginx", reloaded=True) - Importa las operaciones
-
Inventario y resultados de ejecución
- El ejemplo de inventario incluye hosts web desde
web-01.prodhastaweb-23.prod, y hosts de base de datosdb-01.prodydb-02.prod - El comando
$ pyinfra inventory.py deploy.py --limit weblimita la ejecución solo a los objetivosweb - La salida de ejecución avanza en el orden de carga de inventario, recolección concurrente de facts, ejecución de
deploy.pyy resumen - El resumen de ejemplo registra 23 hosts exitosos, 18 cambios, 0 fallos y un total de 2.1 segundos
- El ejemplo de inventario incluye hosts web desde
-
Verificación antes de aplicar
--drypermite revisar primero el diff por host de todas las operaciones que realizará pyinfra- En la ejecución real, los resultados se transmiten en paralelo y muestran la cantidad de cambios y el tiempo de ejecución de cada host
- La ejecución de ejemplo registra 18 hosts con cambios, 6 sin cambios, 0 fallos y un total de 2.1 segundos entre 24 hosts
Características, comparación con Ansible y principios
-
Seis razones para elegir pyinfra
- Just Python: escribes el flujo de control real en Python, sin YAML ni Jinja dentro de YAML
- Concurrent SSH: ejecuta de forma concurrente con gevent y SSH, y afirma ser 6 veces más rápido que Ansible en la misma carga de trabajo
- Diff before apply: con
--dryves todos los cambios por adelantado, y las operaciones idempotentes se vuelven no-op al reejecutarse - 0 agents: en los hosts solo se necesita shell y SSH; no hay demonios, archivos de estado ni plano de control
- Scale-ready: funciona desde 1 host hasta 10,000 hosts, y soporta ejecución paralela y salida en streaming en tiempo real
- Hackable: puedes crear operaciones personalizadas en 10 líneas y conectarlo a docker, lxc y k8s que se comuniquen por shell
-
Comparación de código entre Ansible y pyinfra
- El ejemplo de Ansible usa 16 líneas en
playbook.ymlpara instalarnginx, renderizar una plantilla y recargar el servicio mediante un handler - El ejemplo de pyinfra usa 8 líneas en
deploy.pypara escribir el mismo flujo como código Python - En el ejemplo de pyinfra,
systemd.service("nginx", reloaded=True)solo se ejecuta cuandocfg.will_changedel resultado defiles.templatees verdadero
from pyinfra.operations import apt, files, systemd apt.packages(["nginx"], update=True) cfg = files.template( src="nginx.conf.j2", dest="/etc/nginx/sites-enabled/api", ) if cfg.will_change: systemd.service("nginx", reloaded=True) - El ejemplo de Ansible usa 16 líneas en
-
Declaración de principios
- Code > config: los bucles siguen siendo bucles, y el flujo de control no se codifica en YAML
- Show, then do: primero ves el diff y luego aplicas, para evitar cambios inesperados
- Stay out of the way: ejecuta directamente por SSH, sin agentes, archivos de estado ni plano de control
- Read like english: las operaciones se leen como sustantivo y verbo, por ejemplo
apt.packages,files.template,systemd.service
-
Comando para empezar
- El comando de instalación es
$ uv tool install pyinfra - Se ofrece una guía para leer el quickstart de 5 minutos y desplegar el primer host
- El comando de instalación es
1 comentarios
Opiniones en Lobste.rs
pyinfra se siente como lo que Ansible debió haber sido desde el principio. En vez de agregar flujo de control encima de YAML mezclado con plantillas, puedes escribir la automatización directamente en Python
Se sintió refrescante después de haber trabajado mucho tiempo con Ansible, y no es que yo particularmente odiara Ansible
Tal vez sería mejor un híbrido que también use Python en los servidores destino. Así habría menos infierno de comillas al actualizar archivos y también se evitarían cosas como las limitaciones de expresiones regulares de
sedMe gusta pyinfra y ojalá se usara más
Todas las empresas donde he trabajado hasta ahora usaban Ansible, con o sin Terraform en paralelo, y ninguna estaba lista para reescribir toda la automatización existente con una herramienta nueva en la que el equipo no tuviera experiencia
pyinfra requiere que SysOps sepa Python, pero personalmente creo que SysOps debería saber al menos un lenguaje de scripting. Sobre todo porque incluso en Ansible, si escribes módulos en Python, puedes reducir bastante el caos de YAML, aunque al menos en Francia no parece ser una idea muy común
Puede que tampoco sea un tema tan polémico
Usaba Ansible en mi homelab y cada vez me frustraba más. La configuración en YAML era terrible, todo se sentía como un hack y la velocidad era deprimente. Tampoco me parecía lógico necesitar
python3en el servidor solo para ejecutar unos cuantos comandos de shellConocí
pyinfragracias a Google AI Mode y, en casi un mes de uso, se ha sentido mucho más fresco. Sus ventajas son que es mucho más rápido que Ansible, puedes escribir bucles y condiciones en Python, y en el servidor solo necesitas shell, sin roles ni directorios anidados. Antes de ejecutar, genera un plan basado en el estado actual y, si no le das-y, también pide confirmaciónLas desventajas son que las tareas base son un subconjunto bastante pequeño comparado con los módulos de Ansible, el código puede volverse espagueti muy rápido, y tampoco convence mucho algo como
if 'web_server' in hosts.groups. No sé sioperation(..., filter_group='web_server')sería mejorLo peor de todo es que es demasiado doloroso escribir conectores personalizados. Parece que necesitas un
pyproject.tomlcon un entry point específico depyinfra, y hasta usandouv, desarrollar un conector interno se siente como una pesadilla. Debería poder hacerse simplemente como un archivo normal de Python dentro del proyectoLlevo varios días probando pyinfra como herramienta de despliegue para mi homelab y, comparado con Ansible, lo que más me ha gustado hasta ahora no es la sintaxis de Python sino la velocidad
Ansible siempre me pareció insoportablemente lento
Me gustaría reemplazar el uso de Ansible y Salt en la mayoría de los lugares
Es curioso que la infraestructura como código haya dado toda una vuelta. Pasamos de scripts a YAML y luego de regreso a scripts más sofisticados
Cada enfoque tiene su punto adecuado, y desde la perspectiva de un usuario de Ansible, pyinfra se ve bastante bien
La razón clave por la que terminé adoptando Ansible fue su modo dry-run y diff. Eso me daba confianza en que no iba a hacer cambios inesperados
Pero no parece que el CLI de pyinfra tenga esa opción. Puede que se me haya pasado porque no encontré una referencia con todas las opciones ordenadas alfabéticamente
—dry, y aparece de inmediato en la pantalla inicial de pyinfraPara quien tenga interés, también existe un proyecto mío similar de hace 14 años: https://github.com/sebastien/cuisine/tree/main
Usa solo SSH, sin agente, y pone una API estilo Python encima de funciones básicas de administración, pero no soporta modo dry
Nosotros usamos Ansible para aprovisionar recursos en OpenStack y hacemos el resto con pyinfra, y nos ha funcionado bastante bien durante los últimos años
La mayor desventaja es que la comunidad es pequeña, así que terminas escribiendo tus propias soluciones. Por ejemplo, guardamos en disco los secretos compartidos necesarios para los despliegues con keyring + privy, y escribimos unas cuantas líneas de código para convertir el inventario de cómputo de OpenStack en datos hosts