vcpkg/scripts/azure-pipelines/windows/create-image.ps1

272 lines
10 KiB
PowerShell
Raw Normal View History

# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Creates a Windows virtual machine image, set up for vcpkg's CI.
.DESCRIPTION
create-image.ps1 creates an Azure Windows VM image, set up for vcpkg's CI system.
This script assumes you have installed Azure tools into PowerShell by following the instructions
at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1
or are running from Azure Cloud Shell.
#>
$Location = 'westus3'
$DatePrefixComponent = Get-Date -Format 'yyyy-MM-dd'
$Prefix = "Win-$DatePrefixComponent"
$GalleryImageVersion = $DatePrefixComponent.Replace('-','.')
$VMSize = 'Standard_D8ads_v5'
$ProtoVMName = 'PROTOTYPE'
$WindowsServerSku = '2022-datacenter-azure-edition'
$ErrorActionPreference = 'Stop'
$ProgressActivity = 'Creating Windows Image'
$TotalProgress = 17
$CurrentProgress = 1
# Assigning this to another variable helps when running the commands in this script manually for
# debugging
$Root = $PSScriptRoot
Import-Module "$Root/../create-vmss-helpers.psm1" -DisableNameChecking -Force
$AdminPW = New-Password
$AdminPWSecure = ConvertTo-SecureString $AdminPW -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ("AdminUser", $AdminPWSecure)
$VirtualNetwork = Get-AzVirtualNetwork -ResourceGroupName 'vcpkg-image-minting' -Name 'vcpkg-image-mintingNetwork'
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating prototype VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$NicName = $Prefix + 'NIC'
$Nic = New-AzNetworkInterface `
-Name $NicName `
-ResourceGroupName 'vcpkg-image-minting' `
-Location $Location `
-Subnet $VirtualNetwork.Subnets[0] `
-EnableAcceleratedNetworking
$VM = New-AzVMConfig -Name $ProtoVMName -VMSize $VMSize -SecurityType TrustedLaunch -IdentityType SystemAssigned
$VM = Set-AzVMOperatingSystem `
-VM $VM `
-Windows `
-ComputerName $ProtoVMName `
-Credential $Credential `
-ProvisionVMAgent
$VM = Add-AzVMNetworkInterface -VM $VM -Id $Nic.Id
$VM = Set-AzVMOSDisk -VM $VM -StorageAccountType 'Premium_LRS' -CreateOption 'FromImage'
$VM = Set-AzVMSourceImage `
-VM $VM `
-PublisherName 'MicrosoftWindowsServer' `
-Offer 'WindowsServer' `
-Skus $WindowsServerSku `
-Version latest
$VM = Set-AzVMBootDiagnostic -VM $VM -Disable
New-AzVm `
-ResourceGroupName 'vcpkg-image-minting' `
-Location $Location `
-VM $VM
$VMCreated = Get-AzVM -ResourceGroupName 'vcpkg-image-minting' -Name $ProtoVMName
$VMCreatedOsDisk = $VMCreated.StorageProfile.OsDisk.Name
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Granting permissions to use vcpkg-image-minting storage account' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$VcpkgImageMintingAccount = Get-AzStorageAccount -ResourceGroupName 'vcpkg-image-minting' -Name 'vcpkgimageminting'
# Grant 'Storage Blob Data Reader' (RoleDefinitionId 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1) to the VM
New-AzRoleAssignment `
-Scope $VcpkgImageMintingAccount.ID `
-RoleDefinitionId '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' `
-ObjectId $VMCreated.Identity.PrincipalId
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script deploy-tlssettings.ps1 in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ProvisionImageResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName 'vcpkg-image-minting' `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$Root\deploy-tlssettings.ps1"
Write-Host "deploy-tlssettings.ps1 output: $($ProvisionImageResult.value.Message)"
Write-Host 'Waiting 1 minute for VM to reboot...'
Start-Sleep -Seconds 60
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script deploy-psexec.ps1 in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$DeployPsExecResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName 'vcpkg-image-minting' `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$Root\deploy-psexec.ps1"
Write-Host "deploy-psexec.ps1 output: $($DeployPsExecResult.value.Message)"
####################################################################################################
function Invoke-ScriptWithPrefix {
param(
[string]$ScriptName,
[switch]$AddAdminPw
)
Write-Progress `
-Activity $ProgressActivity `
-Status "Running provisioning script $ScriptName in VM" `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$DropToAdminUserPrefix = Get-Content "$Root\drop-to-admin-user-prefix.ps1" -Encoding utf8NoBOM -Raw
$UtilityPrefixContent = Get-Content "$Root\utility-prefix.ps1" -Encoding utf8NoBOM -Raw
$tempScriptFilename = "$env:TEMP\temp-script.txt"
try {
$script = Get-Content "$Root\$ScriptName" -Encoding utf8NoBOM -Raw
if ($AddAdminPw) {
$script = $script.Replace('# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1', $DropToAdminUserPrefix)
}
$script = $script.Replace('# REPLACE WITH UTILITY-PREFIX.ps1', $UtilityPrefixContent);
Set-Content -Path $tempScriptFilename -Value $script -Encoding utf8NoBOM
$parameter = $null
if ($AddAdminPw) {
$parameter = @{AdminUserPassword = $AdminPW;}
}
$InvokeResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName 'vcpkg-image-minting' `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath $tempScriptFilename `
-Parameter $parameter
Write-Host "$ScriptName output: $($InvokeResult.value.Message)"
} finally {
Remove-Item $tempScriptFilename -Force
}
}
Invoke-ScriptWithPrefix -ScriptName 'deploy-azcopy.ps1'
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-windows-sdks.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-visual-studio.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-mpi.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-cuda.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-inteloneapi.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-pwsh.ps1' -AddAdminPw
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script deploy-settings.txt (as a .ps1) in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ProvisionImageResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName 'vcpkg-image-minting' `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$Root\deploy-settings.txt"
Write-Host "deploy-settings.txt output: $($ProvisionImageResult.value.Message)"
Restart-AzVM -ResourceGroupName 'vcpkg-image-minting' -Name $ProtoVMName
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script sysprep.ps1 in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$SysprepResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName 'vcpkg-image-minting' `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$Root\sysprep.ps1"
Write-Host "sysprep.ps1 output: $($SysprepResult.value.Message)"
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Waiting for VM to shut down' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Wait-Shutdown -ResourceGroupName 'vcpkg-image-minting' -Name $ProtoVMName
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Converting VM to Image' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Stop-AzVM `
-ResourceGroupName 'vcpkg-image-minting' `
-Name $ProtoVMName `
-Force
Set-AzVM `
-ResourceGroupName 'vcpkg-image-minting' `
-Name $ProtoVMName `
-Generalized
New-AzGalleryImageVersion `
-ResourceGroupName 'vcpkg-image-minting' `
-GalleryName 'vcpkg_gallery_wus3' `
-GalleryImageDefinitionName 'PrWinWus3-TrustedLaunch' `
-Name $GalleryImageVersion `
-Location $Location `
-SourceImageId $VMCreated.ID `
-ReplicaCount 1 `
-StorageAccountType 'Premium_LRS' `
-PublishingProfileExcludeFromLatest
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Deleting unused temporary resources' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Remove-AzRoleAssignment `
-Scope $VcpkgImageMintingAccount.ID `
-RoleDefinitionId '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' `
-ObjectId $VMCreated.Identity.PrincipalId
Remove-AzVM -Id $VMCreated.ID -Force
Remove-AzDisk -ResourceGroupName 'vcpkg-image-minting' -Name $VMCreatedOsDisk -Force
Remove-AzNetworkInterface -ResourceGroupName 'vcpkg-image-minting' -Name $NicName -Force
####################################################################################################
Write-Progress -Activity $ProgressActivity -Completed
Write-Host "Generated Image: $GalleryImageVersion"
Write-Host 'Finished!'