← Volver al blog

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