如何通过Terraform为Azure Windows虚拟机执行DSC或PowerShell配置脚本
实现方案说明
你需要的功能可以直接通过Azure原生的**自定义脚本扩展(Custom Script Extension)**结合Terraform实现,无需依赖Windows设备、自动化账户、Blob存储等额外服务,支持直接配置内联PowerShell脚本或公网可访问的脚本URI,使用体验和AWS EC2的userdata高度一致,全流程可在Linux/macOS等非Windows系统上操作。
关键参数
type_handler_version 说明 这是Azure VM扩展的通用参数:
- 每个Azure官方发布的VM扩展都有独立的版本迭代,
type_handler_version就是你所调用的扩展组件的版本号 - 针对Windows平台的自定义脚本扩展,当前最新稳定大版本为2.x,你可以直接填写为
"2.*",Azure会自动拉取该大版本下的最新稳定小版本,无需手动跟进版本更新 - 如果你需要固定运行环境避免版本变动影响,也可以填写精确版本号如
"2.1.10"
Terraform 配置示例
以下是完整可运行的配置示例,全程在非Windows系统上即可执行:
# 资源组示例,可替换为你已有的资源组配置 resource "azurerm_resource_group" "example" { name = "example-resources" location = "East US" } # 虚拟网络示例,可替换为你已有的网络配置 resource "azurerm_virtual_network" "example" { name = "example-network" address_space = ["10.0.0.0/16"] location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name } resource "azurerm_subnet" "example" { name = "internal" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example.name address_prefixes = ["10.0.2.0/24"] } resource "azurerm_network_interface" "example" { name = "example-nic" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.example.id private_ip_address_allocation = "Dynamic" } } # Windows虚拟机配置,可替换为你已有的VM配置 resource "azurerm_windows_virtual_machine" "example" { name = "example-vm" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location size = "Standard_D2s_v5" admin_username = "adminuser" admin_password = "P@ssw0rd1234!" network_interface_ids = [azurerm_network_interface.example.id] os_disk { caching = "ReadWrite" storage_account_type = "Premium_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2022-Datacenter" version = "latest" } } # 自定义脚本扩展核心配置 resource "azurerm_virtual_machine_extension" "custom_script" { name = "custom-script-extension" virtual_machine_id = azurerm_windows_virtual_machine.example.id publisher = "Microsoft.Compute" type = "CustomScriptExtension" type_handler_version = "2.*" # 用法1:内联脚本,无需任何额外存储服务 settings = jsonencode({ commandToExecute = "powershell -ExecutionPolicy Unrestricted -Command \"Write-Host 'Script execution start'; New-Item -Path C:\\\\ -Name run_log.txt -ItemType File -Value 'Inline script executed successfully'\"" }) # 用法2:调用公网URI脚本,替换掉上面的settings即可,脚本可放在任意公网可访问的地址 # settings = jsonencode({ # fileUris = ["https://公网可访问的脚本地址/your_script.ps1"] # commandToExecute = "powershell -ExecutionPolicy Unrestricted -File your_script.ps1" # }) }
常见使用注意事项
- 脚本执行的日志默认存储在虚拟机的
C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\目录下,执行异常时可直接登录VM查看日志定位问题 - 扩展默认仅在首次附加到VM时执行一次,若需要重新运行脚本,修改
commandToExecute内容或扩展的任意参数触发Terraform更新即可 - 内联脚本中的特殊符号、路径需要按照Terraform JSON转义规则处理,和本地使用的操作系统无关
内容的提问来源于stack exchange,提问作者Kisaragi
相关产品推荐
相关产品推荐

