Blog

Seguridad en Ansible: mejores prácticas para una automatización segura

Mejores prácticas de seguridad en Ansible: protege secretos con Ansible Vault, refuerza privilegios y módulos y escanea playbooks en el CI.

Bruno Baldo·Sep 21, 2026·Actualizado el Sep 14, 2026·11 min de lectura·Revisado por Rainforest Technologies
Ansible es el caballo de batalla silencioso de la infraestructura moderna. Configura servidores, despliega aplicaciones, aplica parches a flotas y orquesta releases, a menudo con un puñado de archivos YAML legibles. Esa accesibilidad es justamente la razón por la que la seguridad en Ansible merece una atención deliberada: un playbook que alcanza cientos de hosts con privilegios elevados es uno de los artefactos más potentes, y más peligrosos, de tu entorno. Una sola credencial filtrada o una variable sin validar pasada a un comando de shell puede convertir la automatización conveniente en una vía rápida para un atacante. La buena noticia es que asegurar Ansible es, en gran medida, una cuestión de disciplina y de un conjunto de mejores prácticas de seguridad en Ansible bien conocidas. Este análisis a fondo recorre las áreas que más importan: proteger los secretos con Ansible Vault, mantener las credenciales fuera de los playbooks y los logs, aplicar el mínimo privilegio con become, elegir módulos seguros, defenderse de la inyección en plantillas, reforzar las conexiones, gestionar la cadena de suministro de tu automatización y escanearlo todo en el CI para que los playbooks de Ansible seguros se vuelvan el estándar y no la excepción. Forma parte de nuestra guía más amplia de seguridad de Infrastructure as Code, que enlaza estas prácticas específicas de cada herramienta. Gestión de secretos con Ansible Vault La automatización necesita credenciales: contraseñas de bases de datos, tokens de API, claves TLS, claves de acceso a la nube. La regla cardinal es simple. Los valores sensibles nunca deben estar en texto plano en un repositorio. Ansible Vault es la respuesta integrada. Cifra variables y archivos con una clave simétrica, de modo que puedan convivir de forma segura junto a tus playbooks. Puedes cifrar un archivo entero: ansible-vault encrypt group_vars/production/secrets.yml O cifrar cadenas individuales en línea, para que la mayor parte de un archivo de vars siga siendo legible en los diffs: db_password: !vault |       $ANSIBLE_VAULT;1.1;AES256       66386439653...... Algunos hábitos hacen que Vault sea genuinamente eficaz, en lugar de puro teatro: Nunca hagas commit de la propia contraseña de Vault. Proporciónala en tiempo de ejecución con --vault-password-file apuntando a un archivo fuera del repositorio, o un script que obtenga la clave de tu plataforma de secretos. Mantén la contraseña fuera del historial del shell y de los logs del CI. Separa los datos cifrados de los datos en claro. Un patrón común es un vars.yml legible que referencia valores cifrados guardados en un vault.yml, de modo que los revisores puedan ver la estructura sin exponer los secretos. Rota las claves y vuelve a cifrar cuando alguien se va. ansible-vault rekey vuelve a cifrar el contenido con una nueva contraseña sin cambiar el texto plano. Vault es excelente para secretos estáticos, pero, para credenciales que rotan con frecuencia o se comparten entre muchos sistemas, integra un almacén de secretos externo. Ansible puede obtener secretos en tiempo de ejecución desde vaults gestionados y gestores de secretos en la nube mediante lookup plugins, de modo que nada sensible se escriba en disco: - name: Fetch API token from an external secret store at runtime   ansible.builtin.debug:     msg: "{{ lookup('community.hashi_vault.vault_kv2_get', 'apps/payments').secret.api_token }}"   no_log: true Esto mantiene la fuente de verdad en un sistema diseñado para la rotación, la auditoría y el control de acceso, mientras que Ansible simplemente solicita lo que necesita cuando se ejecuta. También reduce la cantidad de secretos de larga duración que debes gestionar manualmente, que es donde suelen aparecer el drift y las credenciales obsoletas. Una regla práctica: usa Vault para valores que cambian rara vez y pertenecen al código (feature flags, configuración de servicios, credenciales iniciales para un entorno nuevo), y usa un almacén externo para todo lo que se comparte entre equipos, se rota según una programación o está sujeto a auditoría de cumplimiento. Mezclar ambos es normal y esperable; lo importante es que ningún secreto sin cifrar llegue jamás a un commit, a una línea de log o a un artefacto de CI. Mantener los secretos fuera de playbooks, inventory y logs El cifrado solo ayuda si los secretos no se filtran en otros lugares. Dos modos de fallo silenciosos causan la mayoría de los incidentes. Primero, la proliferación de inventory y playbooks. Contraseñas de conexión en un archivo de inventory en texto plano, tokens escritos directamente en una tarea o claves privadas incluidas en el control de versiones son todos casos comunes. Mantén las credenciales en vars cifradas con Vault o en un almacén externo, y añade los secretos del inventory a patrones del .gitignore para que no puedan hacerse commit por accidente. Segundo, los logs. Ansible muestra los resultados de las tareas por defecto, y una tarea que maneja una contraseña puede imprimirla directamente en la consola o en la salida del CI. Usa no_log: true en cualquier tarea que toque datos sensibles: - name: Create database user   community.postgresql.postgresql_user:     name: app     password: "{{ db_password }}"   no_log: true Ten en cuenta que los modos verbosos y los callbacks aún pueden mostrar datos, así que evita pasar secretos a través de command/shell, donde pueden aparecer en listados de procesos o en logs, y prefiere módulos que acepten credenciales como parámetros. Privilegios y become: mínimo privilegio por defecto La escalada de privilegios de Ansible es potente y fácil de aplicar en exceso. Definir become: true a nivel del play, de modo que cada tarea se ejecute como root, es cómodo y arriesgado. Si alguna tarea se ve comprometida o se comporta mal, lo hará con plena autoridad de root. Aplica el mínimo privilegio en su lugar: Escala privilegios solo donde haga falta. Pon become: true en las tareas individuales que lo requieran, no en el play completo. Escala al usuario correcto, no siempre a root. Usa become_user para ejecutar tareas como la cuenta de servicio específica que es dueña del recurso. Acota el sudo de forma estricta. En los hosts gestionados, concede a la cuenta de automatización derechos de sudo solo para los comandos específicos que necesita, en lugar de acceso generalizado ALL. - name: Restart the app service (scoped escalation)   ansible.builtin.systemd:     name: myapp     state: restarted   become: true   become_user: root El objetivo es que una tarea descontrolada o secuestrada tenga el menor radio de impacto posible. También ayuda separar la cuenta con la que Ansible se conecta de los privilegios a los que escala. Conéctate como un usuario de automatización sin privilegios por SSH y escala solo para las tareas específicas que lo necesiten. De ese modo, una clave SSH robada no equivale automáticamente a root en cada host gestionado, y tu política de sudo en esos hosts se convierte en una segunda línea de defensa auditable, que controlas de forma independiente de los propios playbooks. Seguridad de los módulos: prefiere módulos al shell Ansible incluye cientos de módulos idempotentes que comprenden el estado que gestionan. Recurre a ellos antes de bajar a shell, command o raw. Estos tres ejecutan comandos arbitrarios, no son idempotentes y, lo más importante, son el vector principal de inyección de comandos cuando interpolan variables sin validar: # Risky: an attacker-controlled username can inject commands - name: Add user (unsafe)   ansible.builtin.shell: "useradd {{ username }}" # Safer: the module validates and handles the value - name: Add user (safe)   ansible.builtin.user:     name: "{{ username }}"     state: present Si una variable proviene de un origen externo (una API, la entrada de un usuario, un survey), trátala como no confiable. Cuando realmente debas usar shell o command, valida las entradas, usa los filtros quote y evita construir cadenas de comando por concatenación. Prefiere command en lugar de shell siempre que sea posible, ya que command no pasa por un shell y, por lo tanto, no interpreta pipes, redirecciones ni otros metacaracteres que amplían la superficie de inyección. Los módulos te dan idempotencia, un mejor manejo de errores y una superficie de inyección mucho menor sin coste adicional. Inyección en plantillas (Jinja2) Ansible renderiza variables y plantillas a través de Jinja2, y usar entradas no confiables en plantillas puede dar lugar a inyección de plantillas del lado del servidor, en la que valores manipulados ejecutan expresiones en lugar de tratarse como datos. Nunca renderices directamente en plantillas ni en cadenas de comando valores que no controlas. Mantén los datos suministrados externamente como datos: pásalos como parámetros de módulo, aplica el filtro quote donde corresponda y ten cuidado con las construcciones que evalúan cadenas. Revisa las tareas template: que incorporan variables originadas fuera de tu inventory controlado. Seguridad de SSH y de las conexiones Ansible alcanza los hosts principalmente por SSH, así que la higiene de las conexiones es fundamental para la seguridad en Ansible. Gestiona las claves de forma adecuada. Usa claves SSH dedicadas para la automatización, protege las claves privadas y prefiere un agente SSH o una autoridad certificadora de corta duración en lugar de claves de larga duración dispersas por las máquinas. No deshabilites la verificación de claves de host. Es tentador definir host_key_checking = False para silenciar los avisos, pero eso elimina la protección frente a ataques man-in-the-middle. En su lugar, gestiona known_hosts para que los nuevos hosts se confíen de forma deliberada. Prefiere la autenticación basada en claves en lugar de contraseñas y evita incrustar contraseñas de conexión en el inventory. Cadena de suministro: fija y evalúa collections y roles Ansible moderno obtiene collections y roles desde Galaxy y otros orígenes. Cada uno es código que se ejecuta en tu entorno, así que trátalo como parte de tu cadena de suministro de software. Las dependencias sin fijar significan que un upstream comprometido o modificado puede alterar en silencio lo que hace tu automatización. Fija versiones exactas en requirements.yml y evalúa de dónde proviene el contenido: collections:   - name: community.postgresql     version: "3.4.0" roles:   - src: https://github.com/example/hardening-role     version: "v2.1.0" Instala a partir de ese manifiesto (ansible-galaxy install -r requirements.yml), revisa las actualizaciones antes de subir las versiones y favorece orígenes reputados y bien mantenidos. Reconstruir a partir de un manifiesto fijado también hace que tus ejecuciones sean reproducibles y te da un único lugar para auditar exactamente qué código de terceros se está ejecutando en tu entorno. Cuando actualices una dependencia, lee el changelog y haz el diff del cambio de la misma forma que revisarías el código de una aplicación, porque un role que gestiona el estado del sistema puede hacer cualquier cosa que pueda hacer la cuenta que lo ejecuta. Idempotencia y drift La idempotencia es una propiedad de seguridad, no solo de corrección. Un playbook que produce el mismo resultado sin importar cuántas veces se ejecute te permite volver a aplicar el estado deseado para corregir el drift de configuración. Cuando la automatización es la definición autoritativa de un sistema, los cambios inesperados destacan y las manipulaciones manuales se sobrescriben en la siguiente ejecución. Favorece los módulos y el estado declarativo (state: present, state: absent) en lugar de pasos imperativos de shell, para que tus playbooks converjan de forma confiable. Linting y escaneo de playbooks en el CI La forma más confiable de mantener seguros los playbooks de Ansible seguros es comprobarlos automáticamente en cada cambio. Dos capas funcionan en conjunto. ansible-lint detecta patrones arriesgados y antipatrones: uso de command donde existe un módulo, ausencia de no_log, sintaxis obsoleta y más. Ejecútalo en el CI para que los problemas hagan fallar el pipeline pronto: # In your CI pipeline - ansible-lint playbooks/ Junto con el linting, ejecuta un escaneo de seguridad de IaC que comprenda las configuraciones incorrectas y los secretos expuestos en toda tu automatización y en la infraestructura que define. El linting impone un buen estilo y antipatrones conocidos; el escaneo de seguridad busca los resultados arriesgados, como credenciales filtradas, escaladas demasiado permisivas y valores por defecto inseguros, y los clasifica por severidad. Juntos, convierten la seguridad de un paso de revisión manual en una barrera automatizada. Si estás asegurando IaC más allá de Ansible, el mismo enfoque CI-first se aplica a tus otras herramientas, cubiertas en nuestros análisis a fondo de seguridad en Terraform y seguridad en Kubernetes. Cómo ayuda Rainforest Rainforest incorpora Ansible al mismo flujo de seguridad que el resto de tu base de código. Nuestro escaneo de seguridad de IaC analiza tus definiciones de automatización e infraestructura en busca de configuraciones incorrectas, secretos expuestos y valores por defecto inseguros, y luego presenta los hallazgos con el contexto y la severidad que tu equipo necesita para actuar. Como se integra en el pipeline como parte de la plataforma más amplia de testing de seguridad de aplicaciones, el mismo escaneo se ejecuta en cada merge request, de modo que los playbooks arriesgados se señalan antes de llegar a producción, no después de un incidente. El resultado es una automatización en la que puedes confiar: secretos cifrados, escalada de mínimo privilegio, módulos seguros y una barrera de CI que mantiene honesto cada cambio. ¿Listo para verlo en tus propios playbooks? Agenda una demostración y lo recorreremos junto con tu stack.

Preguntas frecuentes

¿Es seguro Ansible?

Ansible puede ser muy seguro, pero la seguridad depende de cómo lo uses. Su diseño agentless, basado en SSH, y su gran biblioteca de módulos idempotentes te dan una base sólida. El riesgo proviene de cómo manejas los secretos, la escalada de privilegios, las entradas no confiables y las dependencias. Seguir prácticas como usar Ansible Vault, acotar become, preferir módulos al shell y escanear playbooks en el CI convierte a Ansible en una herramienta de automatización segura.

¿Qué es Ansible Vault?

Ansible Vault es la funcionalidad integrada de Ansible para cifrar datos sensibles como contraseñas, tokens de API y claves. Usa cifrado simétrico AES-256, de modo que puedes almacenar secretos de forma segura en el mismo repositorio que tus playbooks. Puedes cifrar archivos enteros o variables individuales, y proporcionas la contraseña de Vault en tiempo de ejecución en lugar de hacer commit de ella.

¿Cómo mantengo los secretos fuera de los playbooks de Ansible?

Cifra las variables y los archivos sensibles con Ansible Vault, u obtenlos en tiempo de ejecución desde un almacén de secretos externo usando lookup plugins, de modo que nada se escriba en disco. Nunca hagas commit de credenciales en texto plano ni de claves privadas, mantén los archivos de inventory que contienen secretos fuera del control de versiones y añade no_log: true a las tareas que manejan datos sensibles, para que no se filtren en los logs.

¿Es seguro usar los módulos shell/command?

Son seguros solo con cuidado. shell, command y raw ejecutan comandos arbitrarios, no son idempotentes y pueden permitir la inyección de comandos si interpolan variables sin validar. Prefiere un módulo específico siempre que exista uno. Cuando debas usarlos, trata la entrada externa como no confiable, valida y haz quote de los valores, y evita construir cadenas de comando por concatenación.

¿Cómo escaneo los playbooks de Ansible en busca de problemas de seguridad?

Usa dos capas en el CI. Ejecuta ansible-lint para detectar patrones arriesgados y antipatrones, y ejecuta un escaneo de seguridad de IaC para detectar configuraciones incorrectas, secretos expuestos y ajustes demasiado permisivos clasificados por severidad. El escaneo de seguridad de IaC de Rainforest se integra en tu pipeline, de modo que cada cambio en tus playbooks se comprueba automáticamente antes de llegar a producción.

Bruno Baldo

Escrito por

Bruno Baldo

CMO

Um pouco de marketing e um pouco de curiosidade e temos a receita pra criar um apaixonado por cyber!

Siga leyendo