Automatización de tareas repetitivas con Ansible en entornos mixtos Windows/Linux
Guía práctica para implementar Ansible en infraestructuras heterogéneas, superando los desafíos de la administración multi-plataforma con ejemplos de producción.
Introducción
Tras una década administrando infraestructuras empresariales, he visto cómo la automatización pasó de ser una conveniencia a una necesidad crítica. En entornos mixtos Windows/Linux, donde coexisten servidores heterogéneos, la gestión manual se convierte rápidamente en un cuello de botella operacional. Ansible emerge como solución agnóstica, permitiendo orquestar cambios simultáneamente en máquinas Windows y Linux sin agentes especializados.
Este artículo aborda los desafíos reales que encontrará al implementar Ansible en ambientes híbridos de producción, proporcionando patrones validados y configuraciones que funcionan.
Arquitectura de Ansible en entornos mixtos
El enfoque agnóstico de Ansible
A diferencia de soluciones propietarias, Ansible utiliza SSH para Linux y WinRM (Windows Remote Management) para Windows. Esta dualidad requiere configuración específica, pero proporciona máxima flexibilidad.
Requisitos fundamentales:
- Linux: SSH habilitado, Python 2.7+ o Python 3.5+
- Windows: PowerShell 3.0+, WinRM habilitado y configurado correctamente
El paso más frecuentemente omitido en producción es la configuración de WinRM. Sin ella, sus playbooks fallarán silenciosamente en hosts Windows.
# Ejecutar en Windows como Administrator
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file
# Verificar estado
Get-Item WSMan:\localhost\Client\TrustedHosts
Inventario segmentado
La estructura del inventario es crítica. He visto fallos masivos por mezclar hosts sin diferenciar su naturaleza:
# inventario.yml
all:
vars:
ansible_connection: ssh
ansible_user: adminuser
children:
linux_servers:
vars:
ansible_connection: ssh
ansible_python_interpreter: /usr/bin/python3
hosts:
web01.empresa.com:
web02.empresa.com:
db01.empresa.com:
windows_servers:
vars:
ansible_connection: winrm
ansible_port: 5985
ansible_winrm_transport: basic
ansible_winrm_server_cert_validation: ignore
hosts:
srv-app01.empresa.com:
srv-app02.empresa.com:
dc01.empresa.com:
Playbooks para automatización híbrida
Caso práctico: Actualización de certificados SSL
En producción, he necesitado desplegar certificados renovados simultáneamente en servicios Linux (Nginx, Apache) y Windows (IIS). El siguiente playbook lo automatiza:
---
- name: "Despliegue de certificados SSL en infraestructura mixta"
hosts: all
gather_facts: yes
vars:
cert_source: "/tmp/certificados"
cert_domain: "empresa.com"
tasks:
# Tareas Linux
- name: "Copiar certificado a servidores Linux"
copy:
src: "{{ cert_source }}/{{ cert_domain }}.crt"
dest: "/etc/ssl/certs/"
owner: root
group: root
mode: '0644'
when: ansible_os_family == "Debian" or ansible_os_family == "RedHat"
notify: "restart_linux_service"
- name: "Copiar clave privada (Linux)"
copy:
src: "{{ cert_source }}/{{ cert_domain }}.key"
dest: "/etc/ssl/private/"
owner: root
group: root
mode: '0600'
when: ansible_os_family == "Debian" or ansible_os_family == "RedHat"
notify: "restart_linux_service"
# Tareas Windows
- name: "Importar certificado en Windows"
win_certificate_store:
path: "{{ cert_source }}\\{{ cert_domain }}.pfx"
state: present
store_location: LocalMachine
store_name: My
when: ansible_os_family == "Windows"
notify: "restart_iis"
- name: "Verificar binding IIS"
win_shell: |
Get-WebBinding -Protocol https | Where-Object {$_.bindingInformation -like "*{{ cert_domain }}*"}
register: binding_check
when: ansible_os_family == "Windows"
handlers:
- name: "restart_linux_service"
service:
name: "{{ web_service }}"
state: restarted
when: ansible_os_family == "Debian" or ansible_os_family == "RedHat"
- name: "restart_iis"
win_service:
name: W3SVC
state: restarted
when: ansible_os_family == "Windows"
Errores comunes en producción
1. Credenciales mal configuradas
El error más frecuente: asumir que las credenciales SSH funcionarán también para WinRM. Necesita variables diferenciadas:
linux_servers:
vars:
ansible_user: "{{ linux_user }}"
ansible_ssh_private_key_file: "/home/ansible/.ssh/id_rsa"
windows_servers:
vars:
ansible_user: "{{ windows_domain }}\\{{ windows_user }}"
ansible_password: "{{ windows_password }}"
2. Caracteres especiales en rutas Windows
Las rutas Windows requieren escaping adecuado. Utilice siempre dobles barras invertidas o raw strings en YAML.
3. Timeout en WinRM
Los hosts Windows pueden tardar más en responder. Establezca timeouts apropiados:
[defaults]
timeout = 30
[winrm]
operation_timeout_sec = 120
read_timeout_sec = 120
Validación y testing
Nunca despliegue directamente en producción. Utilice --syntax-check y --check:
ansible-playbook playbook.yml --syntax-check
ansible-playbook playbook.yml -i inventario.yml --check
ansible-playbook playbook.yml -i inventario.yml -vvv # verbose para debugging
Para entornos críticos, implemente testing en staging idéntico a producción.
Conclusión
Ansible proporciona un framework robusto para automatizar infraestructuras heterogéneas, pero requiere comprensión profunda de las diferencias entre plataformas. La clave está en segmentar claramente su inventario, diferenciar variables por grupo y validar exhaustivamente antes de ejecutar en producción.
Con una estructura sólida de roles y playbooks bien documentados, reducirá significativamente el tiempo de provisioning, minimizará errores manuales y habilitará despliegues confiables en sus entornos Windows/Linux. Tras implementar estos patrones, ha visto ciclos