使用Pulumi部署Microsoft Entra Domain Services遇内部错误求助
通过Pulumi部署Microsoft Entra Domain Services(ADS)时,触发以下内部错误:
Code="InternalError" Message="Error testing domain controller connectivity through PowerShell. A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 20.xx.xx.xxx:5986"
已配置domain_name、domain_service_name、resource_group_name等必要参数,以及domain_security_settings和replica_sets,遵循Pulumi官方文档操作。尝试删除ADS资源后重新部署,但负载均衡器、公网IP、网络接口等关联资源残留;手动清理后多次重试仍失败,目标是通过Pulumi完成部署。
相关核心代码如下:
main.py
domain_name = "contoso.local" # 或 contoso.onmicrosoft.com subnet_name_3 = "ads-subnet" subnet_ip_3 = "10.0.3.0/24" # 资源组 ds_resource_group = create_ds_resource_group('ResourceGroupName') # 获取子网ID ds_subnet_id = get_ds_subnet_id(virtual_network, subnet_name_3) # 部署ADS ds_domain_services = create_ds_domain_service(domain_name, ds_resource_group.name, ds_subnet_id)
domainservice.py
import pulumi_azure_native as azure_native from pulumi import Input, Output # 创建资源组 def create_ds_resource_group(resource_group_name: str) -> Output[azure_native.resources.ResourceGroup]: return azure_native.resources.ResourceGroup('resourceGroupDs', resource_group_name=resource_group_name) # 获取指定子网ID def get_ds_subnet_id(virtual_network: Input[azure_native.network.VirtualNetwork], subnet_name_3: str) -> Output[str]: subnet_id: Output[str] = virtual_network.subnets.apply( lambda subnets: next(subnet.id for subnet in subnets if subnet.name == subnet_name_3) ) return subnet_id # 创建Entra Domain Services def create_ds_domain_service( domain_service_name: str, resource_group_name: Input[str], subnet_id: Input[str], ) -> Output[azure_native.aad.DomainService]: domain_service = azure_native.aad.DomainService( 'domainServiceDs', domain_name=domain_service_name, domain_service_name=domain_service_name, domain_security_settings=azure_native.aad.DomainSecuritySettingsArgs( ntlm_v1=azure_native.aad.NtlmV1.ENABLED, sync_ntlm_passwords=azure_native.aad.SyncNtlmPasswords.ENABLED, tls_v1=azure_native.aad.TlsV1.DISABLED, ), resource_group_name=resource_group_name, replica_sets=[ azure_native.aad.ReplicaSetArgs( location='germanywestcentral', subnet_id=subnet_id, ) ], ) return domain_service
1. 检查子网及网络安全组(NSG)配置
ADS对子网有严格要求,必须确保:
- 子网仅用于ADS,不能部署其他虚拟机或资源
- 子网关联的NSG必须放行以下关键端口:
- 5986(WinRM HTTPS,用于Azure管理节点连接ADS控制器)
- 53(DNS)、88(Kerberos)、443(管理API)、3389(RDP,可选用于排查)
- 子网未配置阻止出站到Azure管理服务的网络策略,也未启用专用端点(ADS不支持专用端点部署)
2. 解决Pulumi资源残留问题
Azure隐式创建的LB、公网IP、NIC不属于Pulumi管理范围,删除ADS后会残留。处理方式:
- 批量清理残留资源:使用Azure CLI删除所有关联资源:
# 替换为实际资源名称和资源组 az network lb delete --name <ads-lb-name> --resource-group <rg-name> az network public-ip delete --name <ads-pip-name> --resource-group <rg-name> az network nic delete --name <ads-nic-name> --resource-group <rg-name> - 同步Pulumi状态:清理后执行
pulumi refresh,让Pulumi同步Azure实际资源状态,避免后续部署冲突 - 可选:显式管理依赖:如果需要Pulumi自动清理关联资源,可在代码中为ADS添加
delete_before_replace=True参数,强制删除旧资源后再创建新资源:domain_service = azure_native.aad.DomainService( 'domainServiceDs', # 其他参数... opts=pulumi.ResourceOptions(delete_before_replace=True) )
3. 调整ADS部署参数
- 验证
domain_name:如果使用自定义域名(如.local),需确保已在Entra ID中完成域名验证;使用.onmicrosoft.com域名需确认属于当前租户 - 统一区域配置:确保
replica_sets的location与资源组的location一致,避免跨区域网络延迟导致连接超时 - 简化安全配置:先禁用
ntlm_v1和sync_ntlm_passwords,部署基础ADS实例,确认成功后再逐步启用这些安全设置,排查是否为安全策略导致的连接问题
4. 启用诊断日志排查深层问题
在Pulumi代码中添加诊断设置,收集ADS的审计日志和目录服务日志,便于定位连接失败的具体原因:
import pulumi_azure_native.insights as insights # 为ADS添加诊断设置 insights.DiagnosticSetting( "ads-diagnostic-setting", name="ads-diagnostics", resource_uri=domain_service.id, logs=[ insights.LogSettingsArgs( category="AuditLogs", enabled=True, retention_policy=insights.RetentionPolicyArgs(enabled=True, days=30) ), insights.LogSettingsArgs( category="DirectoryServiceLogs", enabled=True, retention_policy=insights.RetentionPolicyArgs(enabled=True, days=30) ) ], metrics=[ insights.MetricSettingsArgs( category="AllMetrics", enabled=True, retention_policy=insights.RetentionPolicyArgs(enabled=True, days=30) ) ] )
部署后可在Azure门户的Log Analytics工作区中查看日志,获取更详细的错误上下文。
内容的提问来源于stack exchange,提问作者Chris Neumann

