在Terraform locals中添加SafeModeAdministratorPassword并规避明文密码
解决Terraform部署AD域控制器时SafeModeAdministratorPassword明文暴露问题
当前配置中,密码通过Terraform变量直接嵌入PowerShell命令,会导致明文在扩展设置、Terraform日志或状态文件中暴露。以下是两种安全的解决方案:
方案一:通过VM系统身份从Key Vault读取密码(推荐)
利用Azure VM的系统分配身份访问Key Vault,直接在VM内的PowerShell脚本中获取机密,避免Terraform传递明文密码。
1. 给VM启用系统分配身份
修改Windows VM资源配置,添加系统身份:
resource "azurerm_windows_virtual_machine" "rgne1-vm01" { # 保留原有配置(如名称、资源组、大小等) identity { type = "SystemAssigned" } }
2. 配置Key Vault访问策略
允许VM的系统身份读取机密:
data "azurerm_client_config" "current" {} resource "azurerm_key_vault_access_policy" "vm-dc-access" { key_vault_id = azurerm_key_vault.kvne01.id tenant_id = data.azurerm_client_config.current.tenant_id object_id = azurerm_windows_virtual_machine.rgne1-vm01.identity[0].principal_id secret_permissions = ["Get"] }
3. 修改PowerShell脚本
在脚本中直接从Key Vault拉取密码,无需Terraform传递明文:
locals { cmd01 = "Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature -IncludeManagementTools" cmd02 = "Install-WindowsFeature DNS -IncludeAllSubFeature -IncludeManagementTools" cmd03 = "Import-Module ADDSDeployment, DnsServer, Az.KeyVault" # 用单引号避免Terraform解析内部变量,让PowerShell在VM内执行时获取Vault信息 cmd04 = '$securePass = Get-AzKeyVaultSecret -VaultName "${azurerm_key_vault.kvne01.name}" -Name "kv-sec-vm-pass" | Select-Object -ExpandProperty SecretValue; Install-ADDSForest -DomainName ${var.domain_name} -DomainNetbiosName ${var.domain_netbios_name} -DomainMode ${var.domain_mode} -ForestMode ${var.domain_mode} -DatabasePath ${var.database_path} -SysvolPath ${var.sysvol_path} -LogPath ${var.log_path} -NoRebootOnCompletion:$false -Force:$true -SafeModeAdministratorPassword $securePass' powershell = "${local.cmd01}; ${local.cmd02}; ${local.cmd03}; ${local.cmd04}" }
方案二:利用VM扩展的protected_settings传递敏感数据
Azure VM扩展的protected_settings字段会加密传递,不会暴露在日志或扩展配置中,适合直接传递敏感数据。
修改VM扩展配置
resource "azurerm_virtual_machine_extension" "dc01-ad" { name = "dc01-ad-ps1" virtual_machine_id = azurerm_windows_virtual_machine.rgne1-vm01.id depends_on = [azurerm_managed_disk.dc01-ntds] publisher = "Microsoft.Compute" type = "CustomScriptExtension" type_handler_version = "1.9" auto_upgrade_minor_version = true settings = <<SETTINGS { "commandToExecute": "powershell.exe -Command \"$securePass = ConvertTo-SecureString $env:SAFE_MODE_PASS -AsPlainText -Force; ${local.cmd01}; ${local.cmd02}; ${local.cmd03}; Install-ADDSForest -DomainName ${var.domain_name} -DomainNetbiosName ${var.domain_netbios_name} -DomainMode ${var.domain_mode} -ForestMode ${var.domain_mode} -DatabasePath ${var.database_path} -SysvolPath ${var.sysvol_path} -LogPath ${var.log_path} -NoRebootOnCompletion:$false -Force:$true -SafeModeAdministratorPassword $securePass\"" } SETTINGS protected_settings = <<PROTECTED_SETTINGS { "environmentVariables": [ { "name": "SAFE_MODE_PASS", "value": "${random_password.rndm-pass-vm.result}" } ] } PROTECTED_SETTINGS } locals { cmd01 = "Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature -IncludeManagementTools" cmd02 = "Install-WindowsFeature DNS -IncludeAllSubFeature -IncludeManagementTools" cmd03 = "Import-Module ADDSDeployment, DnsServer" }
额外安全建议
- 启用Key Vault的软删除和清除保护,防止机密被意外删除或恢复后泄露
- 加密Terraform状态文件(如使用Azure Blob存储加密,或Terraform Cloud的加密存储)
- 避免在Terraform输出中打印
random_password的结果,该资源默认标记为敏感数据,Terraform不会主动输出
内容的提问来源于stack exchange,提问作者HSar
相关产品推荐
相关产品推荐

