You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Packer构建Windows 2025 Server AMI时WinRM连接卡住求助

适配Windows Server 2025的Packer最小化示例及WinRM连接修复

问题背景

尝试通过Packer创建Windows Server 2025 AMI,参考旧版Windows的HashiCorp仓库配置无法正常工作,构建过程卡在WinRM连接阶段。

当前配置文件

Packer模板(windows.pkr.hcl)

packer {
  required_plugins {
    amazon = {
      version = ">= 1.3.2"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

locals {
    timestamp = regex_replace(timestamp(), "[- TZ:]", "")
    ami_name = var.ami_name != "" ? var.ami_name : "packer-${var.image_os}-${var.image_version}"
}

variable "allowed_inbound_ip_addresses" {
  type    = list(string)
  default = []
}

variable "aws_tags" {
  type    = map(string)
  default = {}
}

variable "region" {
  type    = string
  default = "eu-west-2"
}

variable "image_os" {
  type    = string
  default = "ubuntu"
}

variable "image_version" {
  type    = string
  default = "dev"
}

variable "ami_name" {
  type    = string
  default = ""
}

variable "ami_region" {
  type    = string
  default = "eu-west-2"
}

variable "instance_type" {
  type    = string
  default = "t2.medium"
}

variable "subnet_id" {
    type = string
    default = "subnet-someid"
}

source "amazon-ebs" "windows_image" {
    ami_name = "ado-windows-${local.timestamp}"
    instance_type = "t3.medium"
    region = "${var.region}"

    source_ami_filter {
        filters = {
            name                = "Windows_Server-2025*"
            root-device-type    = "ebs"
            virtualization-type = "hvm"
        }
        most_recent = true
        owners      = ["amazon"]
    }

    user_data_file = "${path.root}/../scripts/build/bootstrap_win.txt"
    communicator = "winrm"
    winrm_username = "Administrator"
    winrm_password = "SuperS3cr3t!!!"
    winrm_insecure = true
    winrm_use_ssl = true
    subnet_id = "${var.subnet_id}"
}


build {
    name = "ado-windows-build"
    sources = ["source.amazon-ebs.windows_image"]

    provisioner "powershell" {
        environment_vars = ["DEVOPS_LIFE_IMPROVER=PACKER"]
        inline           = ["Write-Host \"HELLO NEW USER; WELCOME TO $Env:DEVOPS_LIFE_IMPROVER\"", "Write-Host \"You need to use backtick escapes when using\"", "Write-Host \"characters such as DOLLAR`$ directly in a command\"", "Write-Host \"or in your own scripts.\""]
    }
}

用户数据脚本(bootstrap_win.txt)

# A Packer config that works with this example would be:
#
#
#    "winrm_username": "Administrator",
#    "winrm_password": "SuperS3cr3t!!!",
#    "winrm_insecure": true,
#    "winrm_use_ssl": true
#
#

<powershell>
# Create username and password
net user Administrator SuperS3cr3t!!!
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore

# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"

# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse

# Create a self-signed certificate to let ssl work
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force

# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"

# Configure WinRM to allow unencrypted communication, and provide the
# self-signed cert to the WinRM listener.
cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"

# Make sure appropriate firewall port openings exist
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"

# Restart WinRM, and set it so that it auto-launches on startup.
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm
</powershell>

问题现象

执行Packer构建时持续卡在:

==> ado-windows-build.amazon-ebs.windows_image: Waiting for WinRM to become available...

适配Windows Server 2025的最小化解决方案

1. 简化Packer模板(windows-2025.pkr.hcl)

移除冗余变量,调整WinRM核心配置:

packer {
  required_plugins {
    amazon = {
      version = ">= 1.3.2"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

locals {
  timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}

source "amazon-ebs" "windows_2025" {
  ami_name                    = "windows-server-2025-${local.timestamp}"
  instance_type               = "t3.medium"
  region                      = "eu-west-2"
  subnet_id                   = "subnet-your-actual-id" # 替换为你的子网ID
  associate_public_ip_address = true # 必须开启,确保Packer能访问WinRM端口

  source_ami_filter {
    filters = {
      name                = "Windows_Server-2025-English-Full-Base-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["amazon"]
  }

  communicator   = "winrm"
  winrm_username = "Administrator"
  winrm_password = "SuperS3cr3t!!!"
  winrm_insecure = true
  winrm_use_ssl  = true
}

build {
  sources = ["source.amazon-ebs.windows_2025"]

  provisioner "powershell" {
    inline = [
      "Write-Host 'Windows Server 2025 AMI 构建中...'",
      "Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction SilentlyContinue"
    ]
  }
}

2. 修正用户数据脚本(bootstrap-2025.txt)

适配Windows Server 2025的WinRM默认配置,用PowerShell替代旧命令:

<powershell>
# 重置Administrator密码并设置永不过期
Set-LocalUser -Name Administrator -Password (ConvertTo-SecureString "SuperS3cr3t!!!" -AsPlainText -Force)
Set-LocalUser -Name Administrator -PasswordNeverExpires $true

# 配置执行策略
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction SilentlyContinue

# 清理现有WinRM监听器
Get-ChildItem WSMan:\Localhost\Listener | Remove-Item -Recurse

# 创建自签名证书并配置HTTPS监听器
$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName $env:COMPUTERNAME
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $cert.Thumbprint -Force

# 配置WinRM服务参数
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service/auth '@{CredSSP="true"}'

# 添加WinRM HTTPS防火墙规则
New-NetFirewallRule -DisplayName "WinRM HTTPS" -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow -Enabled True

# 重启WinRM服务并设置开机自启
Restart-Service WinRM
Set-Service WinRM -StartupType Automatic
</powershell>

3. 核心修复点

  • 强制关联公网IP:Windows Server 2025实例若无公网IP,Packer无法从外部访问WinRM端口。
  • 清理默认监听器:新版Windows默认可能已有WinRM监听器,需先清理再重新配置。
  • 替换旧命令:用Set-LocalUser替代net user、New-NetFirewallRule替代netsh,避免兼容性问题。
  • 简化WinRM配置:移除冗余的客户端配置,仅保留服务端必要参数。

验证步骤

  1. 替换模板中的subnet_id为你的实际子网ID。
  2. 执行packer init .初始化插件。
  3. 执行packer build windows-2025.pkr.hcl启动构建。

内容的提问来源于stack exchange,提问作者Tom McLean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:58:10