Problema
En entornos Azure con Windows Server VMs se suele habilitar la extensión AADLoginForWindows para que los usuarios de Entra (Azure AD) inicien sesión mediante RDP. Cuando la automatización necesita ejecutar comandos dentro de la máquina –por ejemplo, Ansible, pipelines de CI/CD o scripts de mantenimiento– el método tradicional (WinRM/WinSSH con credenciales locales) deja de ser viable. Crear y gestionar usuarios locales en cada VM rompe la escalabilidad y aumenta la superficie de ataque. El desafío es encontrar una forma de autenticarse desde herramientas externas sin depender de cuentas locales y sin reescribir flujos que asumen estar “dentro” de la VM.
Causa
-
Extensión AADLoginForWindows solo cubre RDP/SSH
La extensión registra la VM como Azure AD‑joined, lo que permite autenticación de escritorio, pero no expone un token que WinRM o WinSSH puedan consumir directamente. -
WinRM/WinSSH requieren credenciales de tipo NTLM/Kerberos
Los protocolos de gestión remota de Windows esperan un nombre de usuario y una contraseña (o un ticket Kerberos). Un service principal de Entra no genera esos artefactos de forma nativa. -
Ausencia de un dominio interno
Sin Azure AD Domain Services (Azure AD DS) o un AD híbrido, no hay un controlador de dominio que emita tickets Kerberos para los service principals. -
Expectativas de los agentes de automatización
Herramientas como Ansible o Azure Pipelines asumen que pueden conectarse mediante WinRM usando credenciales estáticas o un archivo de clave. Cuando esas credenciales no existen, el flujo se rompe.
Solución
1. Utilizar Azure VM Run Command como puente
Azure VM Run Command permite ejecutar scripts PowerShell o Bash dentro de la VM sin necesidad de abrir puertos ni disponer de credenciales locales. La llamada se hace a través de Azure CLI o SDK, autenticándose con un service principal de Entra. El flujo típico es:
- Crear o reutilizar un service principal con permisos
Microsoft.Compute/virtualMachines/runCommand/actionsobre el recurso VM. - Invocar Run Command con el script que necesite ejecutarse (por ejemplo, un módulo de Ansible o un comando PowerShell).
- Recoger la salida y continuar la pipeline.
Esta técnica elimina la dependencia de usuarios locales y mantiene todo bajo el control de Azure RBAC.
2. Habilitar Azure AD DS para Kerberos‑based WinRM
Si la organización ya cuenta con Azure AD DS, las VMs pueden unirse a ese dominio gestionado. Azure AD DS expone Kerberos y NTLM, por lo que un service principal puede obtener un ticket mediante el flujo Azure AD OAuth → Kerberos (preview). Con el ticket, WinRM acepta la autenticación y Ansible puede usar el módulo winrm sin credenciales locales.
Pasos resumidos:
- Provisionar Azure AD DS y sincronizar los usuarios o grupos de Entra que necesiten acceso.
- Unir la VM a Azure AD DS (puede hacerse con la extensión
DomainJoin). - Configurar WinRM para Kerberos (
winrm quickconfig -transport:https). - Obtener un ticket Kerberos usando
kinitcon el client ID y secret del service principal. - Ejecutar Ansible apuntando a la VM con
ansible_uservacío yansible_connection=winrm.
3. Emplear Managed Identity + Azure Automation Runbooks
Cuando la automatización se ejecuta dentro de Azure (por ejemplo, Azure DevOps o GitHub Actions), se puede asignar una System‑Assigned Managed Identity a la VM o al agente de ejecución. Un Runbook de Azure Automation, ejecutado bajo esa identidad, llama a Invoke-AzVMRunCommand. El script se mantiene en el propio Runbook, lo que evita cualquier credencial estática.
4. Alternativa rápida: Azure Bastion con RDP/SSH y PowerShell Direct
Si la única necesidad es lanzar scripts puntuales y no se requiere una sesión persistente, Azure Bastion permite abrir una conexión RDP/SSH basada en Azure AD y, desde allí, usar PowerShell Direct (cuando la VM está en el mismo host) o Invoke‑Command sobre la sesión RDP. Esta opción es menos automatizable pero útil para tareas ad‑hoc.
Cuándo aplicar esta solución
| Señal | Solución recomendada |
|---|---|
| Necesitas ejecutar scripts desde CI/CD sin exponer contraseñas | Azure VM Run Command + Service Principal |
| Tu organización ya usa Azure AD DS o planea migrar a un dominio gestionado | Kerberos‑based WinRM con Azure AD DS |
| La automatización se ejecuta dentro de Azure y puedes usar Managed Identities | Automation Runbooks + Managed Identity |
| Solo necesitas accesos ocasionales y no quieres cambiar la arquitectura | Bastion + PowerShell Direct |
No apliques estas técnicas si la VM está aislada en una red sin conectividad a Azure Resource Manager (por ejemplo, VNet sin salida a Internet) o si la política de la empresa prohíbe el uso de Azure AD DS.
Código
# 1. Crear service principal (si no existe)
az ad sp create-for-rbac --name "ansible-runner" \
--role "Virtual Machine Contributor" \
--scopes "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Compute/virtualMachines/<vm-name>" \
--years 2
# 2. Ejecutar un script PowerShell dentro de la VM
az vm run-command invoke \
--resource-group <rg> \
--name <vm-name> \
--command-id RunPowerShellScript \
--scripts "Write-Host 'Hello from Azure VM'; Get-Service | Where-Object {$_.Status -eq 'Running'}" \
--parameters '' \
--output json
Para Kerberos con Azure AD DS:
# Obtener token OAuth para el SP
az account get-access-token --resource https://kerberos.windows.net/ --query accessToken -o tsv > token.txt
# Convertir token a ticket Kerberos (requiere kinit de la versión preview)
kinit -i <client-id> -s <client-secret> -t token.txt
# Probar WinRM con Kerberos
ansible -i <ip>, -m win_ping all -e "ansible_connection=winrm ansible_winrm_transport=kerberos"
Verificación
- Run Command: La salida del comando
az vm run-command invokedebe contener el textoHello from Azure VMy la lista de servicios en ejecución. Un código de salida0indica éxito. - Kerberos WinRM: Ejecuta
ansible -m win_pingcontra la VM. Si la respuesta esSUCCESS, la autenticación Kerberos está funcionando. - Automation Runbook: Revisa el historial del Runbook en el portal; debe mostrar
RunCommandcompletado sin errores.
En caso de fallos, verifica que el service principal tenga los permisos Microsoft.Compute/virtualMachines/runCommand/action y que la VM tenga la extensión AADLoginForWindows actualizada a la última versión.
Notas adicionales
- Rotación de secretos: Cuando uses client secret en el service principal, programa una rotación automática (Azure Key Vault + Azure Automation) para evitar expiraciones inesperadas.
- Limitaciones de Run Command: El script se ejecuta con privilegios de administrador local, pero no persiste cambios de configuración del sistema que requieran reinicio.
- Auditoría: Todas las llamadas a Run Command quedan registradas en Azure Activity Log; úsalo para trazabilidad y cumplimiento.
- Redes privadas: Si la VM está en una red sin salida a Internet, habilita Private Link para Azure Resource Manager o usa Azure Bastion como fallback.
- Compatibilidad: La funcionalidad Kerberos‑based WinRM está en preview; revisa la documentación oficial antes de adoptarla en producción.