使用Terraform在Azure部署IaaS域控制器遇用户名识别错误
问题原因
- PowerShell语法要求,字符串类型字面量赋值时必须用引号包裹,否则解释器会将其识别为可执行命令尝试调用。你在拼接PowerShell命令时,直接将
var.domainAdminUsername、var.domainAdminPassword等字符串变量插入到命令中,没有添加PowerShell要求的字符串边界符,最终生成的执行命令为$username = azadmin,因此PowerShell将azadmin识别为未知命令抛出错误,后续PSCredential构造自然也因为用户名参数无效报错。 - 额外的隐患:如果密码、域名等参数中包含空格、特殊符号,即使没有触发命令识别错误,也会出现命令解析异常。
解决方法
修改本地值拼接规则,给所有插入的字符串类型变量包上PowerShell单引号(单引号内的内容不会被PowerShell解析为变量/表达式,更安全),同时对变量中可能存在的单引号做转义处理(PowerShell中转义单引号的规则是写两个连续的单引号),修改后的代码如下:
locals { # 给字符串变量加单引号并转义内部单引号 username_command = "$username = '${replace(var.domainAdminUsername, "'", "''")}'" password_command = "$password = ConvertTo-SecureString '${replace(var.domainAdminPassword, "'", "''")}' -AsPlainText -Force" credentials_command = "$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($username,$password)" install_ad_command = "Add-WindowsFeature -name ad-domain-services -IncludeManagementTools" # 域名参数也需要加引号转义,避免域名中有特殊字符报错 configure_ad_command = "Install-ADDSDomainController -DomainName '${replace(var.domainName, "'", "''")}' -InstallDns -Credential $credentials -SafeModeAdministratorPassword $password -Force:$true" shutdown_command = "shutdown -r -t 10" exit_code_hack = "exit 0" powershell_command = "${local.username_command}; ${local.password_command}; ${local.credentials_command}; ${local.install_ad_command}; ${local.configure_ad_command}; ${local.shutdown_command}; ${local.exit_code_hack}" }
额外安全优化建议
- 建议给
var.domainAdminPassword参数添加sensitive = true属性,避免Terraform在日志、输出中明文打印密码。 - 包含密码的执行命令建议放到
azurerm_virtual_machine_extension的protected_settings字段中,而不是明文的settings字段,Azure会对protected_settings的内容做加密处理,避免敏感信息泄露。
内容的提问来源于stack exchange,提问作者RNemeth
相关产品推荐
相关产品推荐

