Problema
En entornos donde Elastic Beanstalk despliega aplicaciones basadas en Windows Server, cada instancia nueva necesita pertenecer a un dominio de Active Directory para que las políticas de grupo, autenticación Kerberos y recursos compartidos funcionen correctamente. Sin automatización, el proceso de unión al dominio se vuelve manual: se abre una sesión remota, se ejecuta Add-Computer, se reinicia la máquina y se verifica la membresía. En despliegues con auto‑escalado, este flujo rompe la promesa de “elasticidad”, ya que cada nuevo nodo requiere intervención humana. El patrón que se repite es la falta de un mecanismo confiable que, al crear la instancia, la registre automáticamente en AD y la deje lista para recibir tráfico.
Causa
- Configuración estática de la imagen – Las AMI de Windows Server usadas por Elastic Beanstalk suelen estar “limpias”, sin credenciales ni scripts de unión.
- Falta de integración entre EB y AD – Elastic Beanstalk no expone, por defecto, variables de entorno que contengan la información del dominio, ni un hook para ejecutar el proceso de unión antes de que la aplicación arranque.
- Credenciales de dominio inseguras – Cuando se intenta pasar la cuenta de unión mediante variables de entorno sin cifrar, la autenticación falla o se expone a auditorías.
- Timing de red – En VPCs con rutas de DNS interno, la instancia puede intentar unirse antes de que el resolutor interno esté activo, provocando errores de “domain not found”.
- Políticas de seguridad de GPO – Algunas GPO bloquean la creación de cuentas de equipo si la OU de destino no está predefinida, lo que genera un rechazo silencioso.
Solución
Una estrategia reutilizable combina tres piezas: (a) una configuración de Elastic Beanstalk que inyecte los parámetros necesarios, (b) un script PowerShell que realice la unión de forma idempotente y (c) AWS Secrets Manager para almacenar de forma segura las credenciales del dominio.
-
Crear un secreto en Secrets Manager
- Nombre:
ad/domain-join - Campos:
username,password,domain,ou(opcional). - Concede al rol de instancia de Elastic Beanstalk permiso
secretsmanager:GetSecretValuesobre este secreto.
- Nombre:
-
Definir un archivo de configuración
.ebextensionsfiles: "C:\\ProgramData\\Amazon\\ElasticBeanstalk\\hooks\\config\\01_domain_join.ps1": mode: "000755" owner: root content: | # PowerShell script placeholder (real code in next section) container_commands: 01_fetch_secret: command: | powershell -Command ^ $secret = Get-SECSecretValue -SecretId "ad/domain-join" -Region $env:AWS_DEFAULT_REGION; ^ $json = $secret.SecretString | ConvertFrom-Json; ^ Set-Item -Path Env:AD_USER $json.username; ^ Set-Item -Path Env:AD_PASS $json.password; ^ Set-Item -Path Env:AD_DOMAIN $json.domain; ^ Set-Item -Path Env:AD_OU $json.ouEste hook se ejecuta durante la fase config de la instancia, antes de que el contenedor de la aplicación se inicie.
-
Script PowerShell idempotente (
01_domain_join.ps1)param( [string]$User = $env:AD_USER, [string]$Pass = $env:AD_PASS, [string]$Domain = $env:AD_DOMAIN, [string]$OU = $env:AD_OU ) function Join-Domain { $securePass = ConvertTo-SecureString $Pass -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential ("$Domain\$User", $securePass) $targetOU = if ($OU) { "OU=$OU,DC=$($Domain -replace '\.',',DC=')" } else { "" } try { if ((Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) { Write-Host "La máquina ya pertenece al dominio." return } Add-Computer -DomainName $Domain -Credential $cred -OUPath $targetOU -Restart -Force -ErrorAction Stop Write-Host "Unión exitosa. Reiniciando..." } catch { Write-Error "Fallo al unir al dominio: $_" exit 1 } } Join-DomainEl script verifica primero si la máquina ya está en un dominio; si lo está, no intenta nada. Usa
Add-Computercon la opción-Restartpara que la instancia se reinicie automáticamente y quede lista para la aplicación. -
Ajustes de red
- Asegúrate de que la VPC tenga una zona de búsqueda DNS que apunte a los controladores de dominio.
- En el Security Group de la instancia, permite tráfico LDAP/LDAPS (puertos 389/636) y Kerberos (88/464) hacia los DC.
-
Política de GPO
- Precrea la OU destino y delega permisos de “Create Computer objects” al usuario de unión.
- Desactiva la restricción “Domain member: Require strong (Windows 2000 or later) session key” si la cuenta de unión usa contraseñas simples (no recomendado, pero útil en pruebas).
Cuándo aplicar esta solución
- Entornos de auto‑escalado donde cada instancia Windows Server necesita pertenecer al dominio inmediatamente.
- Aplicaciones que dependen de políticas de grupo (por ejemplo, scripts de inicio, mapeo de unidades, auditoría).
- Despliegues en VPCs híbridas con conectividad a un AD on‑premise mediante VPN o Direct Connect.
No es necesario cuando:
- La aplicación se ejecuta en contenedores Linux y no requiere AD.
- La unión al dominio se gestiona mediante herramientas externas como System Center Configuration Manager (SCCM) o Azure AD DS.
Código
# Crear secreto en Secrets Manager (AWS CLI)
aws secretsmanager create-secret \
--name ad/domain-join \
--secret-string '{"username":"joinuser","password":"P@ssw0rd!","domain":"corp.example.com","ou":"Servers"}' \
--region us-east-1
# Conceder permiso al rol de instancia (IAM policy JSON)
aws iam put-role-policy \
--role-name aws-elasticbeanstalk-ec2-role \
--policy-name AllowADSecretAccess \
--policy-document '{
"Version":"2012-10-17",
"Statement":[{
"Effect":"Allow",
"Action":["secretsmanager:GetSecretValue"],
"Resource":"arn:aws:secretsmanager:*:*:secret:ad/domain-join*"
}]
}'
Verificación
- Despliegue una nueva versión de la aplicación en Elastic Beanstalk.
- Cuando la instancia aparezca en la consola de EC2, revisa los logs de EB (
/var/log/eb-activity.log) para confirmar que01_fetch_secrety01_domain_join.ps1se ejecutaron sin errores. - Conéctate vía RDP y ejecuta
whoami /fqdnonltest /dsgetdc:corp.example.com. El nombre completo del equipo debe incluir el dominio. - Verifica que la OU esperada contiene el nuevo equipo en “Active Directory Users and Computers”.
- Si la instancia se reinició, revisa que la aplicación haya arrancado correctamente después del reinicio.
Notas adicionales
- Rotación de credenciales: Usa la función de rotación automática de Secrets Manager para cambiar la contraseña del usuario de unión sin tocar la configuración de EB.
- Timeouts: En entornos con alta latencia VPN, aumenta el valor de
-TimeoutenAdd-Computer(p. ej.,-Timeout 300). - Logs: Añade
-Verboseal script PowerShell y redirige la salida aC:\ProgramData\Amazon\ElasticBeanstalk\logs\domain_join.logpara facilitar el diagnóstico. - Pruebas en staging: Siempre valida la unión en un entorno de pruebas antes de propagar a producción; un error de OU puede bloquear la creación de cientos de máquinas en un despliegue de auto‑escalado.