From ea64263b418a555ef5d18684e23bb39fc61a13a8 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin <127750046+shamil-mubarakshin@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:17:44 +0100 Subject: [PATCH] [windows] Change packer templates from json to hcl (#8999) --- docs/create-image-and-azure-resources.md | 2 +- helpers/GenerateResourcesAndImage.ps1 | 21 +- .../azure-pipelines/windows2019.yml | 2 +- .../azure-pipelines/windows2022.yml | 2 +- images.CI/linux-and-win/build-image.ps1 | 8 +- images/windows/templates/windows-2019.json | 368 -------------- images/windows/templates/windows-2019.pkr.hcl | 455 ++++++++++++++++++ images/windows/templates/windows-2022.json | 355 -------------- images/windows/templates/windows-2022.pkr.hcl | 441 +++++++++++++++++ 9 files changed, 919 insertions(+), 735 deletions(-) delete mode 100644 images/windows/templates/windows-2019.json create mode 100644 images/windows/templates/windows-2019.pkr.hcl delete mode 100644 images/windows/templates/windows-2022.json create mode 100644 images/windows/templates/windows-2022.pkr.hcl diff --git a/docs/create-image-and-azure-resources.md b/docs/create-image-and-azure-resources.md index 45ab1d4bd..877f5f0e7 100644 --- a/docs/create-image-and-azure-resources.md +++ b/docs/create-image-and-azure-resources.md @@ -217,7 +217,7 @@ Where: - `InstallPassword` - password for the user used to install software (Windows only); - `Location` - location where resources will be created (e.g., "East US"); - `ImageName` and `ImageResourceGroupName` - name of the resource group where the managed image will be stored; -- `TemplatePath` - path to the Packer template file (e.g., "images/windows/templates/windows-2022.json"). +- `TemplatePath` - path to the Packer template file (e.g., "images/windows/templates/windows-2022.pkr.hcl"). ### Required variables diff --git a/helpers/GenerateResourcesAndImage.ps1 b/helpers/GenerateResourcesAndImage.ps1 index b8bab020f..272b0ce1d 100644 --- a/helpers/GenerateResourcesAndImage.ps1 +++ b/helpers/GenerateResourcesAndImage.ps1 @@ -19,10 +19,10 @@ Function Get-PackerTemplatePath { switch ($ImageType) { # Note: Double Join-Path is required to support PowerShell 5.1 ([ImageType]::Windows2019) { - $relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2019.json" + $relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2019.pkr.hcl" } ([ImageType]::Windows2022) { - $relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2022.json" + $relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2022.pkr.hcl" } ([ImageType]::Ubuntu2004) { $relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-20.04.json" @@ -155,7 +155,7 @@ Function GenerateResourcesAndImage { if ($Force -and $ReuseResourceGroup) { throw "Force and ReuseResourceGroup cannot be used together." } - + Show-LatestCommit -ErrorAction SilentlyContinue # Validate packer is installed @@ -229,6 +229,13 @@ Function GenerateResourcesAndImage { $InstallPassword = $env:UserName + [System.GUID]::NewGuid().ToString().ToUpper() + Write-Host "Downloading packer plugins..." + & $PackerBinary init $TemplatePath + + if ($LastExitCode -ne 0) { + throw "Packer plugins download failed." + } + Write-Host "Validating packer template..." & $PackerBinary validate ` "-var=client_id=fake" ` @@ -242,7 +249,7 @@ Function GenerateResourcesAndImage { "-var=allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" ` "-var=azure_tags=$($TagsJson)" ` $TemplatePath - + if ($LastExitCode -ne 0) { throw "Packer template validation failed." } @@ -290,7 +297,7 @@ Function GenerateResourcesAndImage { # Resource group already exists, ask the user what to do $title = "Resource group '$ResourceGroupName' already exists" $message = "Do you want to delete the resource group and all resources in it?" - + $options = @( [System.Management.Automation.Host.ChoiceDescription]::new("&Yes", "Delete the resource group and all resources in it."), [System.Management.Automation.Host.ChoiceDescription]::new("&No", "Keep the resource group and continue."), @@ -346,7 +353,7 @@ Function GenerateResourcesAndImage { if ($LastExitCode -ne 0) { throw "Failed to create service principal '$ServicePrincipalName'." } - + $ServicePrincipalAppId = $ServicePrincipal.appId $ServicePrincipalPassword = $ServicePrincipal.password $TenantId = $ServicePrincipal.tenant @@ -383,7 +390,7 @@ Function GenerateResourcesAndImage { Write-Error $_ } finally { Write-Verbose "`nCleaning up..." - + # Remove ADServicePrincipal and ADApplication if ($ADCleanupRequired) { Write-Host "Removing ADServicePrincipal..." diff --git a/images.CI/linux-and-win/azure-pipelines/windows2019.yml b/images.CI/linux-and-win/azure-pipelines/windows2019.yml index d81c173e0..c8bb7f943 100644 --- a/images.CI/linux-and-win/azure-pipelines/windows2019.yml +++ b/images.CI/linux-and-win/azure-pipelines/windows2019.yml @@ -18,4 +18,4 @@ jobs: parameters: image_type: windows2019 image_readme_name: Windows2019-Readme.md - image_template_name: windows-2019.json + image_template_name: windows-2019.pkr.hcl diff --git a/images.CI/linux-and-win/azure-pipelines/windows2022.yml b/images.CI/linux-and-win/azure-pipelines/windows2022.yml index 07e523563..b24e1d487 100644 --- a/images.CI/linux-and-win/azure-pipelines/windows2022.yml +++ b/images.CI/linux-and-win/azure-pipelines/windows2022.yml @@ -18,4 +18,4 @@ jobs: parameters: image_type: windows2022 image_readme_name: Windows2022-Readme.md - image_template_name: windows-2022.json + image_template_name: windows-2022.pkr.hcl diff --git a/images.CI/linux-and-win/build-image.ps1 b/images.CI/linux-and-win/build-image.ps1 index e44b9872d..7abfdfd92 100644 --- a/images.CI/linux-and-win/build-image.ps1 +++ b/images.CI/linux-and-win/build-image.ps1 @@ -22,8 +22,6 @@ if (-not (Test-Path $TemplatePath)) $ImageTemplateName = [io.path]::GetFileName($TemplatePath).Split(".")[0] $InstallPassword = [System.GUID]::NewGuid().ToString().ToUpper() -packer validate -syntax-only $TemplatePath - $SensitiveData = @( 'OSType', 'StorageAccountLocation', @@ -37,6 +35,12 @@ $SensitiveData = @( Write-Host "Show Packer Version" packer --version +Write-Host "Download packer plugins" +packer init $TemplatePath + +Write-Host "Validate packer template" +packer validate -syntax-only $TemplatePath + Write-Host "Build $ImageTemplateName VM" packer build -var "client_id=$ClientId" ` -var "client_secret=$ClientSecret" ` diff --git a/images/windows/templates/windows-2019.json b/images/windows/templates/windows-2019.json deleted file mode 100644 index d6e74585e..000000000 --- a/images/windows/templates/windows-2019.json +++ /dev/null @@ -1,368 +0,0 @@ -{ - "variables": { - "client_id": "{{env `ARM_CLIENT_ID`}}", - "client_secret": "{{env `ARM_CLIENT_SECRET`}}", - "client_cert_path": "{{env `ARM_CLIENT_CERT_PATH`}}", - "subscription_id": "{{env `ARM_SUBSCRIPTION_ID`}}", - "tenant_id": "{{env `ARM_TENANT_ID`}}", - "object_id": "{{env `ARM_OBJECT_ID`}}", - "managed_image_resource_group_name": "{{env `ARM_RESOURCE_GROUP`}}", - "managed_image_storage_account_type": "Premium_LRS", - "build_resource_group_name": "{{env `BUILD_RESOURCE_GROUP_NAME`}}", - "temp_resource_group_name": "{{env `TEMP_RESOURCE_GROUP_NAME`}}", - "location": "{{env `ARM_RESOURCE_LOCATION`}}", - "virtual_network_name": "{{env `VNET_NAME`}}", - "virtual_network_resource_group_name": "{{env `VNET_RESOURCE_GROUP`}}", - "virtual_network_subnet_name": "{{env `VNET_SUBNET`}}", - "private_virtual_network_with_public_ip": "{{env `PRIVATE_VIRTUAL_NETWORK_WITH_PUBLIC_IP`}}", - "allowed_inbound_ip_addresses": "{{env `AGENT_IP`}}", - "vm_size": "Standard_F8s_v2", - "image_folder": "C:\\image", - "imagedata_file": "C:\\imagedata.json", - "helper_script_folder": "C:\\Program Files\\WindowsPowerShell\\Modules\\", - "agent_tools_directory": "C:\\hostedtoolcache\\windows", - "install_user": "installer", - "install_password": null, - "managed_image_name": "packer-win19-dev", - "image_version": "dev", - "image_os": "win19" - }, - "sensitive-variables": [ - "install_password", - "client_secret" - ], - "builders": [ - { - "name": "image", - "type": "azure-arm", - "client_id": "{{user `client_id`}}", - "client_secret": "{{user `client_secret`}}", - "client_cert_path": "{{user `client_cert_path`}}", - "subscription_id": "{{user `subscription_id`}}", - "object_id": "{{user `object_id`}}", - "tenant_id": "{{user `tenant_id`}}", - "os_disk_size_gb": "256", - "location": "{{user `location`}}", - "vm_size": "{{user `vm_size`}}", - "managed_image_name": "{{user `managed_image_name`}}", - "managed_image_resource_group_name": "{{user `managed_image_resource_group_name`}}", - "managed_image_storage_account_type": "{{user `managed_image_storage_account_type`}}", - "build_resource_group_name": "{{user `build_resource_group_name`}}", - "temp_resource_group_name": "{{user `temp_resource_group_name`}}", - "virtual_network_name": "{{user `virtual_network_name`}}", - "virtual_network_resource_group_name": "{{user `virtual_network_resource_group_name`}}", - "virtual_network_subnet_name": "{{user `virtual_network_subnet_name`}}", - "private_virtual_network_with_public_ip": "{{user `private_virtual_network_with_public_ip`}}", - "allowed_inbound_ip_addresses": "{{user `allowed_inbound_ip_addresses`}}", - "os_type": "Windows", - "image_publisher": "MicrosoftWindowsServer", - "image_offer": "WindowsServer", - "image_sku": "2019-Datacenter", - "communicator": "winrm", - "winrm_use_ssl": "true", - "winrm_insecure": "true", - "winrm_username": "packer" - } - ], - "provisioners": [ - { - "type": "powershell", - "inline": [ - "New-Item -Path {{user `image_folder`}} -ItemType Directory -Force" - ] - }, - { - "type": "file", - "sources": [ - "{{ template_dir }}/../assets", - "{{ template_dir }}/../scripts", - "{{ template_dir }}/../toolsets" - ], - "destination": "{{user `image_folder`}}\\" - }, - { - "type": "file", - "source": "{{ template_dir }}/../../../helpers/software-report-base", - "destination": "{{user `image_folder`}}\\scripts\\docs-gen\\" - }, - { - "type": "powershell", - "inline": [ - "Move-Item '{{user `image_folder`}}\\assets\\post-gen' 'C:\\post-generation'", - "Remove-Item -Recurse '{{user `image_folder`}}\\assets'", - "Move-Item '{{user `image_folder`}}\\scripts\\docs-gen' '{{user `image_folder`}}\\SoftwareReport'", - "Move-Item '{{user `image_folder`}}\\scripts\\helpers' '{{user `helper_script_folder`}}\\ImageHelpers'", - "New-Item -Type Directory -Path '{{user `helper_script_folder`}}\\TestsHelpers\\'", - "Move-Item '{{user `image_folder`}}\\scripts\\tests\\Helpers.psm1' '{{user `helper_script_folder`}}\\TestsHelpers\\TestsHelpers.psm1'", - "Move-Item '{{user `image_folder`}}\\scripts\\tests' '{{user `image_folder`}}\\tests'", - "Remove-Item -Recurse '{{user `image_folder`}}\\scripts'", - "Move-Item '{{user `image_folder`}}\\toolsets\\toolset-2019.json' '{{user `image_folder`}}\\toolset.json'", - "Remove-Item -Recurse '{{user `image_folder`}}\\toolsets'" - ] - }, - { - "type": "windows-shell", - "inline": [ - "net user {{user `install_user`}} {{user `install_password`}} /add /passwordchg:no /passwordreq:yes /active:yes /Y", - "net localgroup Administrators {{user `install_user`}} /add", - "winrm set winrm/config/service/auth @{Basic=\"true\"}", - "winrm get winrm/config/service/auth" - ] - }, - { - "type": "powershell", - "inline": [ - "if (-not ((net localgroup Administrators) -contains '{{user `install_user`}}')) { exit 1 }" - ] - }, - { - "type": "powershell", - "inline": [ - "bcdedit.exe /set TESTSIGNING ON" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "powershell", - "valid_exit_codes": [ - 0, - 3010 - ], - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-NET48.ps1" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "windows-restart", - "restart_timeout": "10m" - }, - { - "type": "powershell", - "environment_vars": [ - "IMAGE_VERSION={{user `image_version`}}", - "IMAGE_OS={{user `image_os`}}", - "AGENT_TOOLSDIRECTORY={{user `agent_tools_directory`}}", - "IMAGEDATA_FILE={{user `imagedata_file`}}" - ], - "scripts": [ - "{{ template_dir }}/../scripts/build/Configure-WindowsDefender.ps1", - "{{ template_dir }}/../scripts/build/Configure-PowerShell.ps1", - "{{ template_dir }}/../scripts/build/Install-PowerShellModules.ps1", - "{{ template_dir }}/../scripts/build/Install-WindowsFeatures.ps1", - "{{ template_dir }}/../scripts/build/Install-Chocolatey.ps1", - "{{ template_dir }}/../scripts/build/Configure-BaseImage.ps1", - "{{ template_dir }}/../scripts/build/Configure-ImageDataFile.ps1", - "{{ template_dir }}/../scripts/build/Configure-SystemEnvironment.ps1", - "{{ template_dir }}/../scripts/build/Configure-DotnetSecureChannel.ps1" - ], - "execution_policy": "unrestricted" - }, - { - "type": "windows-restart", - "restart_timeout": "30m" - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-VCRedist.ps1", - "{{ template_dir }}/../scripts/build/Install-Docker.ps1", - "{{ template_dir }}/../scripts/build/Install-DockerWinCred.ps1", - "{{ template_dir }}/../scripts/build/Install-DockerCompose.ps1", - "{{ template_dir }}/../scripts/build/Install-PowershellCore.ps1", - "{{ template_dir }}/../scripts/build/Install-WebPlatformInstaller.ps1", - "{{ template_dir }}/../scripts/build/Install-Runner.ps1" - ] - }, - { - "type": "windows-restart", - "restart_timeout": "10m" - }, - { - "type": "powershell", - "valid_exit_codes": [ - 0, - 3010 - ], - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-VisualStudio.ps1", - "{{ template_dir }}/../scripts/build/Install-KubernetesTools.ps1", - "{{ template_dir }}/../scripts/build/Install-NET48-devpack.ps1" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-Wix.ps1", - "{{ template_dir }}/../scripts/build/Install-WDK.ps1", - "{{ template_dir }}/../scripts/build/Install-VSExtensions.ps1", - "{{ template_dir }}/../scripts/build/Install-AzureCli.ps1", - "{{ template_dir }}/../scripts/build/Install-AzureDevOpsCli.ps1", - "{{ template_dir }}/../scripts/build/Install-ChocolateyPackages.ps1", - "{{ template_dir }}/../scripts/build/Install-JavaTools.ps1", - "{{ template_dir }}/../scripts/build/Install-Kotlin.ps1", - "{{ template_dir }}/../scripts/build/Install-OpenSSL.ps1" - ] - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-ServiceFabricSDK.ps1" - ], - "execution_policy": "remotesigned" - }, - { - "type": "windows-restart", - "restart_timeout": "10m" - }, - { - "type": "windows-shell", - "inline": [ - "wmic product where \"name like '%%microsoft azure powershell%%'\" call uninstall /nointeractive" - ] - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-ActionsCache.ps1", - "{{ template_dir }}/../scripts/build/Install-Ruby.ps1", - "{{ template_dir }}/../scripts/build/Install-PyPy.ps1", - "{{ template_dir }}/../scripts/build/Install-Toolset.ps1", - "{{ template_dir }}/../scripts/build/Configure-Toolset.ps1", - "{{ template_dir }}/../scripts/build/Install-NodeJS.ps1", - "{{ template_dir }}/../scripts/build/Install-AndroidSDK.ps1", - "{{ template_dir }}/../scripts/build/Install-PowershellAzModules.ps1", - "{{ template_dir }}/../scripts/build/Install-Pipx.ps1", - "{{ template_dir }}/../scripts/build/Install-Git.ps1", - "{{ template_dir }}/../scripts/build/Install-GitHub-CLI.ps1", - "{{ template_dir }}/../scripts/build/Install-PHP.ps1", - "{{ template_dir }}/../scripts/build/Install-Rust.ps1", - "{{ template_dir }}/../scripts/build/Install-Sbt.ps1", - "{{ template_dir }}/../scripts/build/Install-Chrome.ps1", - "{{ template_dir }}/../scripts/build/Install-EdgeDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-Firefox.ps1", - "{{ template_dir }}/../scripts/build/Install-Selenium.ps1", - "{{ template_dir }}/../scripts/build/Install-IEWebDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-Apache.ps1", - "{{ template_dir }}/../scripts/build/Install-Nginx.ps1", - "{{ template_dir }}/../scripts/build/Install-Msys2.ps1", - "{{ template_dir }}/../scripts/build/Install-WinAppDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-R.ps1", - "{{ template_dir }}/../scripts/build/Install-AWSTools.ps1", - "{{ template_dir }}/../scripts/build/Install-DACFx.ps1", - "{{ template_dir }}/../scripts/build/Install-MysqlCli.ps1", - "{{ template_dir }}/../scripts/build/Install-SQLPowerShellTools.ps1", - "{{ template_dir }}/../scripts/build/Install-SQLOLEDBDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-DotnetSDK.ps1", - "{{ template_dir }}/../scripts/build/Install-Mingw64.ps1", - "{{ template_dir }}/../scripts/build/Install-Haskell.ps1", - "{{ template_dir }}/../scripts/build/Install-Stack.ps1", - "{{ template_dir }}/../scripts/build/Install-Miniconda.ps1", - "{{ template_dir }}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", - "{{ template_dir }}/../scripts/build/Install-Mercurial.ps1", - "{{ template_dir }}/../scripts/build/Install-Zstd.ps1", - "{{ template_dir }}/../scripts/build/Install-NSIS.ps1", - "{{ template_dir }}/../scripts/build/Install-CloudFoundryCli.ps1", - "{{ template_dir }}/../scripts/build/Install-Vcpkg.ps1", - "{{ template_dir }}/../scripts/build/Install-PostgreSQL.ps1", - "{{ template_dir }}/../scripts/build/Install-Bazel.ps1", - "{{ template_dir }}/../scripts/build/Install-AliyunCli.ps1", - "{{ template_dir }}/../scripts/build/Install-RootCA.ps1", - "{{ template_dir }}/../scripts/build/Install-MongoDB.ps1", - "{{ template_dir }}/../scripts/build/Install-GoogleCloudCLI.ps1", - "{{ template_dir }}/../scripts/build/Install-CodeQLBundle.ps1", - "{{ template_dir }}/../scripts/build/Install-BizTalkBuildComponent.ps1", - "{{ template_dir }}/../scripts/build/Configure-Diagnostics.ps1", - "{{ template_dir }}/../scripts/build/Configure-DynamicPort.ps1", - "{{ template_dir }}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", - "{{ template_dir }}/../scripts/build/Configure-Shell.ps1", - "{{ template_dir }}/../scripts/build/Configure-DeveloperMode.ps1", - "{{ template_dir }}/../scripts/build/Install-LLVM.ps1" - ] - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-WindowsUpdates.ps1" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "windows-restart", - "check_registry": true, - "restart_check_command": "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"", - "restart_timeout": "30m" - }, - { - "type": "powershell", - "pause_before": "2m", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", - "{{ template_dir }}/../scripts/tests/RunAll-Tests.ps1" - ] - }, - { - "type": "powershell", - "inline": [ - "if (-not (Test-Path {{user `image_folder`}}\\tests\\testResults.xml)) { throw '{{user `image_folder`}}\\tests\\testResults.xml not found' }" - ] - }, - { - "type": "powershell", - "inline": [ - "pwsh -File '{{user `image_folder`}}\\SoftwareReport\\Generate-SoftwareReport.ps1'" - ], - "environment_vars": [ - "IMAGE_VERSION={{user `image_version`}}" - ] - }, - { - "type": "powershell", - "inline": [ - "if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", - "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }" - ] - }, - { - "type": "file", - "source": "C:\\software-report.md", - "destination": "{{ template_dir }}/../Windows2019-Readme.md", - "direction": "download" - }, - { - "type": "file", - "source": "C:\\software-report.json", - "destination": "{{ template_dir }}/../software-report.json", - "direction": "download" - }, - { - "type": "powershell", - "skip_clean": true, - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-NativeImages.ps1", - "{{ template_dir }}/../scripts/build/Configure-System.ps1", - "{{ template_dir }}/../scripts/build/Configure-User.ps1" - ], - "environment_vars": [ - "INSTALL_USER={{user `install_user`}}" - ] - }, - { - "type": "windows-restart", - "restart_timeout": "10m" - }, - { - "type": "powershell", - "inline": [ - "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", - "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit", - "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" - ] - } - ] -} diff --git a/images/windows/templates/windows-2019.pkr.hcl b/images/windows/templates/windows-2019.pkr.hcl new file mode 100644 index 000000000..7ac73077f --- /dev/null +++ b/images/windows/templates/windows-2019.pkr.hcl @@ -0,0 +1,455 @@ +packer { + required_plugins { + azure = { + source = "github.com/hashicorp/azure" + version = "~> 2" + } + } +} + +locals { + managed_image_name = var.managed_image_name != "" ? var.managed_image_name : "packer-${var.image_os}-${var.image_version}" +} + +variable "agent_tools_directory" { + type = string + default = "C:\\hostedtoolcache\\windows" +} + +variable "allowed_inbound_ip_addresses" { + type = list(string) + default = [] +} + +variable "azure_tags" { + type = map(string) + default = {} +} + +variable "build_resource_group_name" { + type = string + default = "${env("BUILD_RESOURCE_GROUP_NAME")}" +} + +variable "client_cert_path" { + type = string + default = "${env("ARM_CLIENT_CERT_PATH")}" +} + +variable "client_id" { + type = string + default = "${env("ARM_CLIENT_ID")}" +} + +variable "client_secret" { + type = string + default = "${env("ARM_CLIENT_SECRET")}" + sensitive = true +} + +variable "helper_script_folder" { + type = string + default = "C:\\Program Files\\WindowsPowerShell\\Modules\\" +} + +variable "image_folder" { + type = string + default = "C:\\image" +} + +variable "image_os" { + type = string + default = "win19" +} + +variable "image_version" { + type = string + default = "dev" +} + +variable "imagedata_file" { + type = string + default = "C:\\imagedata.json" +} + +variable "install_password" { + type = string + default = "" + sensitive = true +} + +variable "install_user" { + type = string + default = "installer" +} + +variable "location" { + type = string + default = "${env("ARM_RESOURCE_LOCATION")}" +} + +variable "managed_image_name" { + type = string + default = "" +} + +variable "managed_image_resource_group_name" { + type = string + default = "${env("ARM_RESOURCE_GROUP")}" +} + +variable "managed_image_storage_account_type" { + type = string + default = "Premium_LRS" +} + +variable "object_id" { + type = string + default = "${env("ARM_OBJECT_ID")}" +} + +variable "private_virtual_network_with_public_ip" { + type = bool + default = false +} + +variable "subscription_id" { + type = string + default = "${env("ARM_SUBSCRIPTION_ID")}" +} + +variable "temp_resource_group_name" { + type = string + default = "${env("TEMP_RESOURCE_GROUP_NAME")}" +} + +variable "tenant_id" { + type = string + default = "${env("ARM_TENANT_ID")}" +} + +variable "virtual_network_name" { + type = string + default = "${env("VNET_NAME")}" +} + +variable "virtual_network_resource_group_name" { + type = string + default = "${env("VNET_RESOURCE_GROUP")}" +} + +variable "virtual_network_subnet_name" { + type = string + default = "${env("VNET_SUBNET")}" +} + +variable "vm_size" { + type = string + default = "Standard_F8s_v2" +} + +source "azure-arm" "image" { + allowed_inbound_ip_addresses = "${var.allowed_inbound_ip_addresses}" + build_resource_group_name = "${var.build_resource_group_name}" + client_cert_path = "${var.client_cert_path}" + client_id = "${var.client_id}" + client_secret = "${var.client_secret}" + communicator = "winrm" + image_offer = "WindowsServer" + image_publisher = "MicrosoftWindowsServer" + image_sku = "2019-Datacenter" + location = "${var.location}" + managed_image_name = "${local.managed_image_name}" + managed_image_resource_group_name = "${var.managed_image_resource_group_name}" + managed_image_storage_account_type = "${var.managed_image_storage_account_type}" + object_id = "${var.object_id}" + os_disk_size_gb = "256" + os_type = "Windows" + private_virtual_network_with_public_ip = "${var.private_virtual_network_with_public_ip}" + subscription_id = "${var.subscription_id}" + temp_resource_group_name = "${var.temp_resource_group_name}" + tenant_id = "${var.tenant_id}" + virtual_network_name = "${var.virtual_network_name}" + virtual_network_resource_group_name = "${var.virtual_network_resource_group_name}" + virtual_network_subnet_name = "${var.virtual_network_subnet_name}" + vm_size = "${var.vm_size}" + winrm_insecure = "true" + winrm_use_ssl = "true" + winrm_username = "packer" + + dynamic "azure_tag" { + for_each = var.azure_tags + content { + name = azure_tag.key + value = azure_tag.value + } + } +} + +build { + sources = ["source.azure-arm.image"] + + provisioner "powershell" { + inline = ["New-Item -Path ${var.image_folder} -ItemType Directory -Force"] + } + + provisioner "file" { + destination = "${var.image_folder}\\" + sources = [ + "${path.root}/../assets", + "${path.root}/../scripts", + "${path.root}/../toolsets" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\scripts\\docs-gen\\" + source = "${path.root}/../../../helpers/software-report-base" + } + + provisioner "powershell" { + inline = [ + "Move-Item '${var.image_folder}\\assets\\post-gen' 'C:\\post-generation'", + "Remove-Item -Recurse '${var.image_folder}\\assets'", + "Move-Item '${var.image_folder}\\scripts\\docs-gen' '${var.image_folder}\\SoftwareReport'", + "Move-Item '${var.image_folder}\\scripts\\helpers' '${var.helper_script_folder}\\ImageHelpers'", + "New-Item -Type Directory -Path '${var.helper_script_folder}\\TestsHelpers\\'", + "Move-Item '${var.image_folder}\\scripts\\tests\\Helpers.psm1' '${var.helper_script_folder}\\TestsHelpers\\TestsHelpers.psm1'", + "Move-Item '${var.image_folder}\\scripts\\tests' '${var.image_folder}\\tests'", + "Remove-Item -Recurse '${var.image_folder}\\scripts'", + "Move-Item '${var.image_folder}\\toolsets\\toolset-2019.json' '${var.image_folder}\\toolset.json'", + "Remove-Item -Recurse '${var.image_folder}\\toolsets'" + ] + } + + provisioner "windows-shell" { + inline = [ + "net user ${var.install_user} ${var.install_password} /add /passwordchg:no /passwordreq:yes /active:yes /Y", + "net localgroup Administrators ${var.install_user} /add", + "winrm set winrm/config/service/auth @{Basic=\"true\"}", + "winrm get winrm/config/service/auth" + ] + } + + provisioner "powershell" { + inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + inline = ["bcdedit.exe /set TESTSIGNING ON"] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + scripts = ["${path.root}/../scripts/build/Install-NET48.ps1"] + valid_exit_codes = [0, 3010] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_OS=${var.image_os}", "AGENT_TOOLSDIRECTORY=${var.agent_tools_directory}", "IMAGEDATA_FILE=${var.imagedata_file}"] + execution_policy = "unrestricted" + scripts = [ + "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", + "${path.root}/../scripts/build/Configure-PowerShell.ps1", + "${path.root}/../scripts/build/Install-PowerShellModules.ps1", + "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", + "${path.root}/../scripts/build/Install-Chocolatey.ps1", + "${path.root}/../scripts/build/Configure-BaseImage.ps1", + "${path.root}/../scripts/build/Configure-ImageDataFile.ps1", + "${path.root}/../scripts/build/Configure-SystemEnvironment.ps1", + "${path.root}/../scripts/build/Configure-DotnetSecureChannel.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "30m" + } + + provisioner "powershell" { + scripts = [ + "${path.root}/../scripts/build/Install-VCRedist.ps1", + "${path.root}/../scripts/build/Install-Docker.ps1", + "${path.root}/../scripts/build/Install-DockerWinCred.ps1", + "${path.root}/../scripts/build/Install-DockerCompose.ps1", + "${path.root}/../scripts/build/Install-PowershellCore.ps1", + "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1", + "${path.root}/../scripts/build/Install-Runner.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + scripts = [ + "${path.root}/../scripts/build/Install-VisualStudio.ps1", + "${path.root}/../scripts/build/Install-KubernetesTools.ps1", + "${path.root}/../scripts/build/Install-NET48-devpack.ps1" + ] + valid_exit_codes = [0, 3010] + } + + provisioner "powershell" { + scripts = [ + "${path.root}/../scripts/build/Install-Wix.ps1", + "${path.root}/../scripts/build/Install-WDK.ps1", + "${path.root}/../scripts/build/Install-VSExtensions.ps1", + "${path.root}/../scripts/build/Install-AzureCli.ps1", + "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", + "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-JavaTools.ps1", + "${path.root}/../scripts/build/Install-Kotlin.ps1", + "${path.root}/../scripts/build/Install-OpenSSL.ps1" + ] + } + + provisioner "powershell" { + execution_policy = "remotesigned" + scripts = ["${path.root}/../scripts/build/Install-ServiceFabricSDK.ps1"] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "windows-shell" { + inline = ["wmic product where \"name like '%%microsoft azure powershell%%'\" call uninstall /nointeractive"] + } + + provisioner "powershell" { + scripts = [ + "${path.root}/../scripts/build/Install-ActionsCache.ps1", + "${path.root}/../scripts/build/Install-Ruby.ps1", + "${path.root}/../scripts/build/Install-PyPy.ps1", + "${path.root}/../scripts/build/Install-Toolset.ps1", + "${path.root}/../scripts/build/Configure-Toolset.ps1", + "${path.root}/../scripts/build/Install-NodeJS.ps1", + "${path.root}/../scripts/build/Install-AndroidSDK.ps1", + "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", + "${path.root}/../scripts/build/Install-Pipx.ps1", + "${path.root}/../scripts/build/Install-Git.ps1", + "${path.root}/../scripts/build/Install-GitHub-CLI.ps1", + "${path.root}/../scripts/build/Install-PHP.ps1", + "${path.root}/../scripts/build/Install-Rust.ps1", + "${path.root}/../scripts/build/Install-Sbt.ps1", + "${path.root}/../scripts/build/Install-Chrome.ps1", + "${path.root}/../scripts/build/Install-EdgeDriver.ps1", + "${path.root}/../scripts/build/Install-Firefox.ps1", + "${path.root}/../scripts/build/Install-Selenium.ps1", + "${path.root}/../scripts/build/Install-IEWebDriver.ps1", + "${path.root}/../scripts/build/Install-Apache.ps1", + "${path.root}/../scripts/build/Install-Nginx.ps1", + "${path.root}/../scripts/build/Install-Msys2.ps1", + "${path.root}/../scripts/build/Install-WinAppDriver.ps1", + "${path.root}/../scripts/build/Install-R.ps1", + "${path.root}/../scripts/build/Install-AWSTools.ps1", + "${path.root}/../scripts/build/Install-DACFx.ps1", + "${path.root}/../scripts/build/Install-MysqlCli.ps1", + "${path.root}/../scripts/build/Install-SQLPowerShellTools.ps1", + "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", + "${path.root}/../scripts/build/Install-DotnetSDK.ps1", + "${path.root}/../scripts/build/Install-Mingw64.ps1", + "${path.root}/../scripts/build/Install-Haskell.ps1", + "${path.root}/../scripts/build/Install-Stack.ps1", + "${path.root}/../scripts/build/Install-Miniconda.ps1", + "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + "${path.root}/../scripts/build/Install-Mercurial.ps1", + "${path.root}/../scripts/build/Install-Zstd.ps1", + "${path.root}/../scripts/build/Install-NSIS.ps1", + "${path.root}/../scripts/build/Install-CloudFoundryCli.ps1", + "${path.root}/../scripts/build/Install-Vcpkg.ps1", + "${path.root}/../scripts/build/Install-PostgreSQL.ps1", + "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-AliyunCli.ps1", + "${path.root}/../scripts/build/Install-RootCA.ps1", + "${path.root}/../scripts/build/Install-MongoDB.ps1", + "${path.root}/../scripts/build/Install-GoogleCloudCLI.ps1", + "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", + "${path.root}/../scripts/build/Install-BizTalkBuildComponent.ps1", + "${path.root}/../scripts/build/Configure-Diagnostics.ps1", + "${path.root}/../scripts/build/Configure-DynamicPort.ps1", + "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", + "${path.root}/../scripts/build/Configure-Shell.ps1", + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" + ] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + scripts = ["${path.root}/../scripts/build/Install-WindowsUpdates.ps1"] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" + restart_timeout = "30m" + } + + provisioner "powershell" { + pause_before = "2m0s" + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", + "${path.root}/../scripts/tests/RunAll-Tests.ps1" + ] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path ${var.image_folder}\\tests\\testResults.xml)) { throw '${var.image_folder}\\tests\\testResults.xml not found' }"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}"] + inline = ["pwsh -File '${var.image_folder}\\SoftwareReport\\Generate-SoftwareReport.ps1'"] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }"] + } + + provisioner "file" { + destination = "${path.root}/../Windows2019-Readme.md" + direction = "download" + source = "C:\\software-report.md" + } + + provisioner "file" { + destination = "${path.root}/../software-report.json" + direction = "download" + source = "C:\\software-report.json" + } + + provisioner "powershell" { + environment_vars = ["INSTALL_USER=${var.install_user}"] + scripts = [ + "${path.root}/../scripts/build/Install-NativeImages.ps1", + "${path.root}/../scripts/build/Configure-System.ps1", + "${path.root}/../scripts/build/Configure-User.ps1" + ] + skip_clean = true + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = [ + "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + ] + } + +} diff --git a/images/windows/templates/windows-2022.json b/images/windows/templates/windows-2022.json deleted file mode 100644 index 8c303142c..000000000 --- a/images/windows/templates/windows-2022.json +++ /dev/null @@ -1,355 +0,0 @@ -{ - "variables": { - "client_id": "{{env `ARM_CLIENT_ID`}}", - "client_secret": "{{env `ARM_CLIENT_SECRET`}}", - "client_cert_path": "{{env `ARM_CLIENT_CERT_PATH`}}", - "subscription_id": "{{env `ARM_SUBSCRIPTION_ID`}}", - "tenant_id": "{{env `ARM_TENANT_ID`}}", - "object_id": "{{env `ARM_OBJECT_ID`}}", - "managed_image_resource_group_name": "{{env `ARM_RESOURCE_GROUP`}}", - "managed_image_storage_account_type": "Premium_LRS", - "build_resource_group_name": "{{env `BUILD_RESOURCE_GROUP_NAME`}}", - "temp_resource_group_name": "{{env `TEMP_RESOURCE_GROUP_NAME`}}", - "location": "{{env `ARM_RESOURCE_LOCATION`}}", - "virtual_network_name": "{{env `VNET_NAME`}}", - "virtual_network_resource_group_name": "{{env `VNET_RESOURCE_GROUP`}}", - "virtual_network_subnet_name": "{{env `VNET_SUBNET`}}", - "private_virtual_network_with_public_ip": "{{env `PRIVATE_VIRTUAL_NETWORK_WITH_PUBLIC_IP`}}", - "allowed_inbound_ip_addresses": "{{env `AGENT_IP`}}", - "vm_size": "Standard_F8s_v2", - "image_folder": "C:\\image", - "imagedata_file": "C:\\imagedata.json", - "helper_script_folder": "C:\\Program Files\\WindowsPowerShell\\Modules\\", - "agent_tools_directory": "C:\\hostedtoolcache\\windows", - "install_user": "installer", - "install_password": null, - "managed_image_name": "packer-win22-dev", - "image_version": "dev", - "image_os": "win22" - }, - "sensitive-variables": [ - "install_password", - "client_secret" - ], - "builders": [ - { - "name": "image", - "type": "azure-arm", - "client_id": "{{user `client_id`}}", - "client_secret": "{{user `client_secret`}}", - "client_cert_path": "{{user `client_cert_path`}}", - "subscription_id": "{{user `subscription_id`}}", - "object_id": "{{user `object_id`}}", - "tenant_id": "{{user `tenant_id`}}", - "os_disk_size_gb": "256", - "location": "{{user `location`}}", - "vm_size": "{{user `vm_size`}}", - "managed_image_name": "{{user `managed_image_name`}}", - "managed_image_resource_group_name": "{{user `managed_image_resource_group_name`}}", - "managed_image_storage_account_type": "{{user `managed_image_storage_account_type`}}", - "build_resource_group_name": "{{user `build_resource_group_name`}}", - "temp_resource_group_name": "{{user `temp_resource_group_name`}}", - "virtual_network_name": "{{user `virtual_network_name`}}", - "virtual_network_resource_group_name": "{{user `virtual_network_resource_group_name`}}", - "virtual_network_subnet_name": "{{user `virtual_network_subnet_name`}}", - "private_virtual_network_with_public_ip": "{{user `private_virtual_network_with_public_ip`}}", - "allowed_inbound_ip_addresses": "{{user `allowed_inbound_ip_addresses`}}", - "os_type": "Windows", - "image_publisher": "MicrosoftWindowsServer", - "image_offer": "WindowsServer", - "image_sku": "2022-Datacenter", - "communicator": "winrm", - "winrm_use_ssl": "true", - "winrm_insecure": "true", - "winrm_username": "packer" - } - ], - "provisioners": [ - { - "type": "powershell", - "inline": [ - "New-Item -Path {{user `image_folder`}} -ItemType Directory -Force" - ] - }, - { - "type": "file", - "sources": [ - "{{ template_dir }}/../assets", - "{{ template_dir }}/../scripts", - "{{ template_dir }}/../toolsets" - ], - "destination": "{{user `image_folder`}}\\" - }, - { - "type": "file", - "source": "{{ template_dir }}/../../../helpers/software-report-base", - "destination": "{{user `image_folder`}}\\scripts\\docs-gen\\" - }, - { - "type": "powershell", - "inline": [ - "Move-Item '{{user `image_folder`}}\\assets\\post-gen' 'C:\\post-generation'", - "Remove-Item -Recurse '{{user `image_folder`}}\\assets'", - "Move-Item '{{user `image_folder`}}\\scripts\\docs-gen' '{{user `image_folder`}}\\SoftwareReport'", - "Move-Item '{{user `image_folder`}}\\scripts\\helpers' '{{user `helper_script_folder`}}\\ImageHelpers'", - "New-Item -Type Directory -Path '{{user `helper_script_folder`}}\\TestsHelpers\\'", - "Move-Item '{{user `image_folder`}}\\scripts\\tests\\Helpers.psm1' '{{user `helper_script_folder`}}\\TestsHelpers\\TestsHelpers.psm1'", - "Move-Item '{{user `image_folder`}}\\scripts\\tests' '{{user `image_folder`}}\\tests'", - "Remove-Item -Recurse '{{user `image_folder`}}\\scripts'", - "Move-Item '{{user `image_folder`}}\\toolsets\\toolset-2022.json' '{{user `image_folder`}}\\toolset.json'", - "Remove-Item -Recurse '{{user `image_folder`}}\\toolsets'" - ] - }, - { - "type": "windows-shell", - "inline": [ - "net user {{user `install_user`}} {{user `install_password`}} /add /passwordchg:no /passwordreq:yes /active:yes /Y", - "net localgroup Administrators {{user `install_user`}} /add", - "winrm set winrm/config/service/auth @{Basic=\"true\"}", - "winrm get winrm/config/service/auth" - ] - }, - { - "type": "powershell", - "inline": [ - "if (-not ((net localgroup Administrators) -contains '{{user `install_user`}}')) { exit 1 }" - ] - }, - { - "type": "powershell", - "inline": [ - "bcdedit.exe /set TESTSIGNING ON" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "powershell", - "environment_vars": [ - "IMAGE_VERSION={{user `image_version`}}", - "IMAGE_OS={{user `image_os`}}", - "AGENT_TOOLSDIRECTORY={{user `agent_tools_directory`}}", - "IMAGEDATA_FILE={{user `imagedata_file`}}" - ], - "scripts": [ - "{{ template_dir }}/../scripts/build/Configure-WindowsDefender.ps1", - "{{ template_dir }}/../scripts/build/Configure-PowerShell.ps1", - "{{ template_dir }}/../scripts/build/Install-PowerShellModules.ps1", - "{{ template_dir }}/../scripts/build/Install-WindowsFeatures.ps1", - "{{ template_dir }}/../scripts/build/Install-Chocolatey.ps1", - "{{ template_dir }}/../scripts/build/Configure-BaseImage.ps1", - "{{ template_dir }}/../scripts/build/Configure-ImageDataFile.ps1", - "{{ template_dir }}/../scripts/build/Configure-SystemEnvironment.ps1", - "{{ template_dir }}/../scripts/build/Configure-DotnetSecureChannel.ps1" - ], - "execution_policy": "unrestricted" - }, - { - "type": "windows-restart", - "check_registry": true, - "restart_check_command": "powershell -command \"& {while ( (Get-WindowsOptionalFeature -Online -FeatureName Containers -ErrorAction SilentlyContinue).State -ne 'Enabled' ) { Start-Sleep 30; Write-Output 'InProgress' }}\"", - "restart_timeout": "10m" - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-Docker.ps1", - "{{ template_dir }}/../scripts/build/Install-DockerWinCred.ps1", - "{{ template_dir }}/../scripts/build/Install-DockerCompose.ps1", - "{{ template_dir }}/../scripts/build/Install-PowershellCore.ps1", - "{{ template_dir }}/../scripts/build/Install-WebPlatformInstaller.ps1", - "{{ template_dir }}/../scripts/build/Install-Runner.ps1" - ] - }, - { - "type": "windows-restart", - "restart_timeout": "30m" - }, - { - "type": "powershell", - "valid_exit_codes": [ - 0, - 3010 - ], - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-VisualStudio.ps1", - "{{ template_dir }}/../scripts/build/Install-KubernetesTools.ps1" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "windows-restart", - "check_registry": true, - "restart_timeout": "10m" - }, - { - "type": "powershell", - "pause_before": "2m", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-Wix.ps1", - "{{ template_dir }}/../scripts/build/Install-WDK.ps1", - "{{ template_dir }}/../scripts/build/Install-VSExtensions.ps1", - "{{ template_dir }}/../scripts/build/Install-AzureCli.ps1", - "{{ template_dir }}/../scripts/build/Install-AzureDevOpsCli.ps1", - "{{ template_dir }}/../scripts/build/Install-ChocolateyPackages.ps1", - "{{ template_dir }}/../scripts/build/Install-JavaTools.ps1", - "{{ template_dir }}/../scripts/build/Install-Kotlin.ps1", - "{{ template_dir }}/../scripts/build/Install-OpenSSL.ps1" - ] - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-ServiceFabricSDK.ps1" - ], - "execution_policy": "remotesigned" - }, - { - "type": "windows-restart", - "restart_timeout": "10m" - }, - { - "type": "windows-shell", - "inline": [ - "wmic product where \"name like '%%microsoft azure powershell%%'\" call uninstall /nointeractive" - ] - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-ActionsCache.ps1", - "{{ template_dir }}/../scripts/build/Install-Ruby.ps1", - "{{ template_dir }}/../scripts/build/Install-PyPy.ps1", - "{{ template_dir }}/../scripts/build/Install-Toolset.ps1", - "{{ template_dir }}/../scripts/build/Configure-Toolset.ps1", - "{{ template_dir }}/../scripts/build/Install-NodeJS.ps1", - "{{ template_dir }}/../scripts/build/Install-AndroidSDK.ps1", - "{{ template_dir }}/../scripts/build/Install-PowershellAzModules.ps1", - "{{ template_dir }}/../scripts/build/Install-Pipx.ps1", - "{{ template_dir }}/../scripts/build/Install-Git.ps1", - "{{ template_dir }}/../scripts/build/Install-GitHub-CLI.ps1", - "{{ template_dir }}/../scripts/build/Install-PHP.ps1", - "{{ template_dir }}/../scripts/build/Install-Rust.ps1", - "{{ template_dir }}/../scripts/build/Install-Sbt.ps1", - "{{ template_dir }}/../scripts/build/Install-Chrome.ps1", - "{{ template_dir }}/../scripts/build/Install-EdgeDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-Firefox.ps1", - "{{ template_dir }}/../scripts/build/Install-Selenium.ps1", - "{{ template_dir }}/../scripts/build/Install-IEWebDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-Apache.ps1", - "{{ template_dir }}/../scripts/build/Install-Nginx.ps1", - "{{ template_dir }}/../scripts/build/Install-Msys2.ps1", - "{{ template_dir }}/../scripts/build/Install-WinAppDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-R.ps1", - "{{ template_dir }}/../scripts/build/Install-AWSTools.ps1", - "{{ template_dir }}/../scripts/build/Install-DACFx.ps1", - "{{ template_dir }}/../scripts/build/Install-MysqlCli.ps1", - "{{ template_dir }}/../scripts/build/Install-SQLPowerShellTools.ps1", - "{{ template_dir }}/../scripts/build/Install-SQLOLEDBDriver.ps1", - "{{ template_dir }}/../scripts/build/Install-DotnetSDK.ps1", - "{{ template_dir }}/../scripts/build/Install-Mingw64.ps1", - "{{ template_dir }}/../scripts/build/Install-Haskell.ps1", - "{{ template_dir }}/../scripts/build/Install-Stack.ps1", - "{{ template_dir }}/../scripts/build/Install-Miniconda.ps1", - "{{ template_dir }}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", - "{{ template_dir }}/../scripts/build/Install-Mercurial.ps1", - "{{ template_dir }}/../scripts/build/Install-Zstd.ps1", - "{{ template_dir }}/../scripts/build/Install-NSIS.ps1", - "{{ template_dir }}/../scripts/build/Install-Vcpkg.ps1", - "{{ template_dir }}/../scripts/build/Install-PostgreSQL.ps1", - "{{ template_dir }}/../scripts/build/Install-Bazel.ps1", - "{{ template_dir }}/../scripts/build/Install-AliyunCli.ps1", - "{{ template_dir }}/../scripts/build/Install-RootCA.ps1", - "{{ template_dir }}/../scripts/build/Install-MongoDB.ps1", - "{{ template_dir }}/../scripts/build/Install-CodeQLBundle.ps1", - "{{ template_dir }}/../scripts/build/Configure-Diagnostics.ps1" - ] - }, - { - "type": "powershell", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-WindowsUpdates.ps1", - "{{ template_dir }}/../scripts/build/Configure-DynamicPort.ps1", - "{{ template_dir }}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", - "{{ template_dir }}/../scripts/build/Configure-Shell.ps1", - "{{ template_dir }}/../scripts/build/Configure-DeveloperMode.ps1", - "{{ template_dir }}/../scripts/build/Install-LLVM.ps1" - ], - "elevated_user": "{{user `install_user`}}", - "elevated_password": "{{user `install_password`}}" - }, - { - "type": "windows-restart", - "check_registry": true, - "restart_check_command": "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"", - "restart_timeout": "30m" - }, - { - "type": "powershell", - "pause_before": "2m", - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", - "{{ template_dir }}/../scripts/tests/RunAll-Tests.ps1" - ] - }, - { - "type": "powershell", - "inline": [ - "if (-not (Test-Path {{user `image_folder`}}\\tests\\testResults.xml)) { throw '{{user `image_folder`}}\\tests\\testResults.xml not found' }" - ] - }, - { - "type": "powershell", - "inline": [ - "pwsh -File '{{user `image_folder`}}\\SoftwareReport\\Generate-SoftwareReport.ps1'" - ], - "environment_vars": [ - "IMAGE_VERSION={{user `image_version`}}" - ] - }, - { - "type": "powershell", - "inline": [ - "if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", - "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }" - ] - }, - { - "type": "file", - "source": "C:\\software-report.md", - "destination": "{{ template_dir }}/../Windows2022-Readme.md", - "direction": "download" - }, - { - "type": "file", - "source": "C:\\software-report.json", - "destination": "{{ template_dir }}/../software-report.json", - "direction": "download" - }, - { - "type": "powershell", - "skip_clean": true, - "scripts": [ - "{{ template_dir }}/../scripts/build/Install-NativeImages.ps1", - "{{ template_dir }}/../scripts/build/Configure-System.ps1", - "{{ template_dir }}/../scripts/build/Configure-User.ps1" - ], - "environment_vars": [ - "INSTALL_USER={{user `install_user`}}" - ] - }, - { - "type": "windows-restart", - "restart_timeout": "10m" - }, - { - "type": "powershell", - "inline": [ - "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", - "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /mode:vm /quiet /quit", - "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" - ] - } - ] -} diff --git a/images/windows/templates/windows-2022.pkr.hcl b/images/windows/templates/windows-2022.pkr.hcl new file mode 100644 index 000000000..19411aa1d --- /dev/null +++ b/images/windows/templates/windows-2022.pkr.hcl @@ -0,0 +1,441 @@ +packer { + required_plugins { + azure = { + source = "github.com/hashicorp/azure" + version = "~> 2" + } + } +} + +locals { + managed_image_name = var.managed_image_name != "" ? var.managed_image_name : "packer-${var.image_os}-${var.image_version}" +} + +variable "agent_tools_directory" { + type = string + default = "C:\\hostedtoolcache\\windows" +} + +variable "allowed_inbound_ip_addresses" { + type = list(string) + default = [] +} + +variable "azure_tags" { + type = map(string) + default = {} +} + +variable "build_resource_group_name" { + type = string + default = "${env("BUILD_RESOURCE_GROUP_NAME")}" +} + +variable "client_cert_path" { + type = string + default = "${env("ARM_CLIENT_CERT_PATH")}" +} + +variable "client_id" { + type = string + default = "${env("ARM_CLIENT_ID")}" +} + +variable "client_secret" { + type = string + default = "${env("ARM_CLIENT_SECRET")}" + sensitive = true +} + +variable "helper_script_folder" { + type = string + default = "C:\\Program Files\\WindowsPowerShell\\Modules\\" +} + +variable "image_folder" { + type = string + default = "C:\\image" +} + +variable "image_os" { + type = string + default = "win22" +} + +variable "image_version" { + type = string + default = "dev" +} + +variable "imagedata_file" { + type = string + default = "C:\\imagedata.json" +} + +variable "install_password" { + type = string + default = "" + sensitive = true +} + +variable "install_user" { + type = string + default = "installer" +} + +variable "location" { + type = string + default = "${env("ARM_RESOURCE_LOCATION")}" +} + +variable "managed_image_name" { + type = string + default = "" +} + +variable "managed_image_resource_group_name" { + type = string + default = "${env("ARM_RESOURCE_GROUP")}" +} + +variable "managed_image_storage_account_type" { + type = string + default = "Premium_LRS" +} + +variable "object_id" { + type = string + default = "${env("ARM_OBJECT_ID")}" +} + +variable "private_virtual_network_with_public_ip" { + type = bool + default = false +} + +variable "subscription_id" { + type = string + default = "${env("ARM_SUBSCRIPTION_ID")}" +} + +variable "temp_resource_group_name" { + type = string + default = "${env("TEMP_RESOURCE_GROUP_NAME")}" +} + +variable "tenant_id" { + type = string + default = "${env("ARM_TENANT_ID")}" +} + +variable "virtual_network_name" { + type = string + default = "${env("VNET_NAME")}" +} + +variable "virtual_network_resource_group_name" { + type = string + default = "${env("VNET_RESOURCE_GROUP")}" +} + +variable "virtual_network_subnet_name" { + type = string + default = "${env("VNET_SUBNET")}" +} + +variable "vm_size" { + type = string + default = "Standard_F8s_v2" +} + +source "azure-arm" "image" { + allowed_inbound_ip_addresses = "${var.allowed_inbound_ip_addresses}" + build_resource_group_name = "${var.build_resource_group_name}" + client_cert_path = "${var.client_cert_path}" + client_id = "${var.client_id}" + client_secret = "${var.client_secret}" + communicator = "winrm" + image_offer = "WindowsServer" + image_publisher = "MicrosoftWindowsServer" + image_sku = "2022-Datacenter" + location = "${var.location}" + managed_image_name = "${local.managed_image_name}" + managed_image_resource_group_name = "${var.managed_image_resource_group_name}" + managed_image_storage_account_type = "${var.managed_image_storage_account_type}" + object_id = "${var.object_id}" + os_disk_size_gb = "256" + os_type = "Windows" + private_virtual_network_with_public_ip = "${var.private_virtual_network_with_public_ip}" + subscription_id = "${var.subscription_id}" + temp_resource_group_name = "${var.temp_resource_group_name}" + tenant_id = "${var.tenant_id}" + virtual_network_name = "${var.virtual_network_name}" + virtual_network_resource_group_name = "${var.virtual_network_resource_group_name}" + virtual_network_subnet_name = "${var.virtual_network_subnet_name}" + vm_size = "${var.vm_size}" + winrm_insecure = "true" + winrm_use_ssl = "true" + winrm_username = "packer" + + dynamic "azure_tag" { + for_each = var.azure_tags + content { + name = azure_tag.key + value = azure_tag.value + } + } +} + +build { + sources = ["source.azure-arm.image"] + + provisioner "powershell" { + inline = ["New-Item -Path ${var.image_folder} -ItemType Directory -Force"] + } + + provisioner "file" { + destination = "${var.image_folder}\\" + sources = [ + "${path.root}/../assets", + "${path.root}/../scripts", + "${path.root}/../toolsets" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\scripts\\docs-gen\\" + source = "${path.root}/../../../helpers/software-report-base" + } + + provisioner "powershell" { + inline = [ + "Move-Item '${var.image_folder}\\assets\\post-gen' 'C:\\post-generation'", + "Remove-Item -Recurse '${var.image_folder}\\assets'", + "Move-Item '${var.image_folder}\\scripts\\docs-gen' '${var.image_folder}\\SoftwareReport'", + "Move-Item '${var.image_folder}\\scripts\\helpers' '${var.helper_script_folder}\\ImageHelpers'", + "New-Item -Type Directory -Path '${var.helper_script_folder}\\TestsHelpers\\'", + "Move-Item '${var.image_folder}\\scripts\\tests\\Helpers.psm1' '${var.helper_script_folder}\\TestsHelpers\\TestsHelpers.psm1'", + "Move-Item '${var.image_folder}\\scripts\\tests' '${var.image_folder}\\tests'", + "Remove-Item -Recurse '${var.image_folder}\\scripts'", + "Move-Item '${var.image_folder}\\toolsets\\toolset-2022.json' '${var.image_folder}\\toolset.json'", + "Remove-Item -Recurse '${var.image_folder}\\toolsets'" + ] + } + + provisioner "windows-shell" { + inline = [ + "net user ${var.install_user} ${var.install_password} /add /passwordchg:no /passwordreq:yes /active:yes /Y", + "net localgroup Administrators ${var.install_user} /add", + "winrm set winrm/config/service/auth @{Basic=\"true\"}", + "winrm get winrm/config/service/auth" + ] + } + + provisioner "powershell" { + inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + inline = ["bcdedit.exe /set TESTSIGNING ON"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_OS=${var.image_os}", "AGENT_TOOLSDIRECTORY=${var.agent_tools_directory}", "IMAGEDATA_FILE=${var.imagedata_file}"] + execution_policy = "unrestricted" + scripts = [ + "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", + "${path.root}/../scripts/build/Configure-PowerShell.ps1", + "${path.root}/../scripts/build/Install-PowerShellModules.ps1", + "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", + "${path.root}/../scripts/build/Install-Chocolatey.ps1", + "${path.root}/../scripts/build/Configure-BaseImage.ps1", + "${path.root}/../scripts/build/Configure-ImageDataFile.ps1", + "${path.root}/../scripts/build/Configure-SystemEnvironment.ps1", + "${path.root}/../scripts/build/Configure-DotnetSecureChannel.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {while ( (Get-WindowsOptionalFeature -Online -FeatureName Containers -ErrorAction SilentlyContinue).State -ne 'Enabled' ) { Start-Sleep 30; Write-Output 'InProgress' }}\"" + restart_timeout = "10m" + } + + provisioner "powershell" { + scripts = [ + "${path.root}/../scripts/build/Install-Docker.ps1", + "${path.root}/../scripts/build/Install-DockerWinCred.ps1", + "${path.root}/../scripts/build/Install-DockerCompose.ps1", + "${path.root}/../scripts/build/Install-PowershellCore.ps1", + "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1", + "${path.root}/../scripts/build/Install-Runner.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "30m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + scripts = [ + "${path.root}/../scripts/build/Install-VisualStudio.ps1", + "${path.root}/../scripts/build/Install-KubernetesTools.ps1" + ] + valid_exit_codes = [0, 3010] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + provisioner "powershell" { + pause_before = "2m0s" + scripts = [ + "${path.root}/../scripts/build/Install-Wix.ps1", + "${path.root}/../scripts/build/Install-WDK.ps1", + "${path.root}/../scripts/build/Install-VSExtensions.ps1", + "${path.root}/../scripts/build/Install-AzureCli.ps1", + "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", + "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-JavaTools.ps1", + "${path.root}/../scripts/build/Install-Kotlin.ps1", + "${path.root}/../scripts/build/Install-OpenSSL.ps1" + ] + } + + provisioner "powershell" { + execution_policy = "remotesigned" + scripts = ["${path.root}/../scripts/build/Install-ServiceFabricSDK.ps1"] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "windows-shell" { + inline = ["wmic product where \"name like '%%microsoft azure powershell%%'\" call uninstall /nointeractive"] + } + + provisioner "powershell" { + scripts = [ + "${path.root}/../scripts/build/Install-ActionsCache.ps1", + "${path.root}/../scripts/build/Install-Ruby.ps1", + "${path.root}/../scripts/build/Install-PyPy.ps1", + "${path.root}/../scripts/build/Install-Toolset.ps1", + "${path.root}/../scripts/build/Configure-Toolset.ps1", + "${path.root}/../scripts/build/Install-NodeJS.ps1", + "${path.root}/../scripts/build/Install-AndroidSDK.ps1", + "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", + "${path.root}/../scripts/build/Install-Pipx.ps1", + "${path.root}/../scripts/build/Install-Git.ps1", + "${path.root}/../scripts/build/Install-GitHub-CLI.ps1", + "${path.root}/../scripts/build/Install-PHP.ps1", + "${path.root}/../scripts/build/Install-Rust.ps1", + "${path.root}/../scripts/build/Install-Sbt.ps1", + "${path.root}/../scripts/build/Install-Chrome.ps1", + "${path.root}/../scripts/build/Install-EdgeDriver.ps1", + "${path.root}/../scripts/build/Install-Firefox.ps1", + "${path.root}/../scripts/build/Install-Selenium.ps1", + "${path.root}/../scripts/build/Install-IEWebDriver.ps1", + "${path.root}/../scripts/build/Install-Apache.ps1", + "${path.root}/../scripts/build/Install-Nginx.ps1", + "${path.root}/../scripts/build/Install-Msys2.ps1", + "${path.root}/../scripts/build/Install-WinAppDriver.ps1", + "${path.root}/../scripts/build/Install-R.ps1", + "${path.root}/../scripts/build/Install-AWSTools.ps1", + "${path.root}/../scripts/build/Install-DACFx.ps1", + "${path.root}/../scripts/build/Install-MysqlCli.ps1", + "${path.root}/../scripts/build/Install-SQLPowerShellTools.ps1", + "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", + "${path.root}/../scripts/build/Install-DotnetSDK.ps1", + "${path.root}/../scripts/build/Install-Mingw64.ps1", + "${path.root}/../scripts/build/Install-Haskell.ps1", + "${path.root}/../scripts/build/Install-Stack.ps1", + "${path.root}/../scripts/build/Install-Miniconda.ps1", + "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + "${path.root}/../scripts/build/Install-Mercurial.ps1", + "${path.root}/../scripts/build/Install-Zstd.ps1", + "${path.root}/../scripts/build/Install-NSIS.ps1", + "${path.root}/../scripts/build/Install-Vcpkg.ps1", "${path.root}/../scripts/build/Install-PostgreSQL.ps1", "${path.root}/../scripts/build/Install-Bazel.ps1", "${path.root}/../scripts/build/Install-AliyunCli.ps1", "${path.root}/../scripts/build/Install-RootCA.ps1", "${path.root}/../scripts/build/Install-MongoDB.ps1", "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", "${path.root}/../scripts/build/Configure-Diagnostics.ps1"] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", + "${path.root}/../scripts/build/Configure-DynamicPort.ps1", + "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", + "${path.root}/../scripts/build/Configure-Shell.ps1", + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" + restart_timeout = "30m" + } + + provisioner "powershell" { + pause_before = "2m0s" + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", + "${path.root}/../scripts/tests/RunAll-Tests.ps1" + ] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path ${var.image_folder}\\tests\\testResults.xml)) { throw '${var.image_folder}\\tests\\testResults.xml not found' }"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}"] + inline = ["pwsh -File '${var.image_folder}\\SoftwareReport\\Generate-SoftwareReport.ps1'"] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }"] + } + + provisioner "file" { + destination = "${path.root}/../Windows2022-Readme.md" + direction = "download" + source = "C:\\software-report.md" + } + + provisioner "file" { + destination = "${path.root}/../software-report.json" + direction = "download" + source = "C:\\software-report.json" + } + + provisioner "powershell" { + environment_vars = ["INSTALL_USER=${var.install_user}"] + scripts = [ + "${path.root}/../scripts/build/Install-NativeImages.ps1", + "${path.root}/../scripts/build/Configure-System.ps1", + "${path.root}/../scripts/build/Configure-User.ps1" + ] + skip_clean = true + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = [ + "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /mode:vm /quiet /quit", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + ] + } + +}