Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions docs/create-image-and-azure-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ In any case, you will need these software installed:

This repository includes a script that assists in generating images in Azure.
All you need is an Azure subscription, a resource group in that subscription and a build agent configured as described above.
We suggest starting with building the UbuntuMinimal image because it includes only basic software and builds in less than 30 minutes.

All the commands below should be executed in PowerShell.

Expand All @@ -99,7 +98,7 @@ Finally, run the `GenerateResourcesAndImage` function, setting the mandatory arg
- `ResourceGroupName` - the name of the resource group that will store the resulting artifact (e.g., "imagegen-test").
The resource group must already exist in your Azure subscription;
- `AzureLocation` - the location where resources will be created (e.g., "East US");
- `ImageType` - the type of image to build (we suggest choosing "UbuntuMinimal" here; other valid options are "Windows2019", "Windows2022", "Windows2025", "Ubuntu2204", "Ubuntu2404").
- `ImageType` - the type of image to build (valid options are "Windows2019", "Windows2022", "Windows2025", "Ubuntu2204", "Ubuntu2404").

This function automatically creates all required Azure resources and initiates the Packer image generation for the selected image type.

Expand Down Expand Up @@ -200,11 +199,14 @@ Then, you can invoke Packer in your CI/CD pipeline using the following commands:

```powershell
packer plugins install github.com/hashicorp/azure 2.2.1
packer build -var "subscription_id=$SubscriptionId" `

packer build -only "$BuildName*" `
-var "subscription_id=$SubscriptionId" `
-var "client_id=$ClientId" `
-var "client_secret=$ClientSecret" `
-var "install_password=$InstallPassword" `
-var "location=$Location" `
-var "image_os=$ImageOS" `
-var "managed_image_name=$ImageName" `
-var "managed_image_resource_group_name=$ImageResourceGroupName" `
-var "tenant_id=$TenantId" `
Expand All @@ -213,13 +215,15 @@ packer build -var "subscription_id=$SubscriptionId" `

Where:

- `BuildName` - name of the build defined in Packer template's `build{}` block (e.g. "ubuntu-24_04", "windows-2025");
- `SubscriptionId` - your Azure Subscription ID;
- `ClientId` and `ClientSecret` - Service Principal credentials;
- `TenantId` - Azure Tenant ID;
- `InstallPassword` - password for the user used to install software (Windows only);
- `Location` - location where resources will be created (e.g., "East US");
- `ImageOS` - the type of OS that will be deployed as a temporary VM (e.g. "ubuntu24", "win25");
- `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.pkr.hcl").
- `TemplatePath` - path to the folder with Packer template files (e.g., "images/windows/templates").

### Required variables

Expand Down
43 changes: 27 additions & 16 deletions helpers/GenerateResourcesAndImage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ enum ImageType {
Windows2025 = 3
Ubuntu2204 = 4
Ubuntu2404 = 5
UbuntuMinimal = 6
}

Function Get-PackerTemplatePath {
Function Get-PackerTemplate {
param (
[Parameter(Mandatory = $True)]
[string] $RepositoryRoot,
Expand All @@ -20,33 +19,41 @@ 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.pkr.hcl"
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "build.windows-2019.pkr.hcl"
$imageOS = "win19"
}
([ImageType]::Windows2022) {
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2022.pkr.hcl"
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "build.windows-2022.pkr.hcl"
$imageOS = "win22"
}
([ImageType]::Windows2025) {
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2025.pkr.hcl"
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "build.windows-2025.pkr.hcl"
$imageOS = "win25"
}
([ImageType]::Ubuntu2204) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-22.04.pkr.hcl"
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "build.ubuntu-22_04.pkr.hcl"
$imageOS = "ubuntu22"
}
([ImageType]::Ubuntu2404) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-24.04.pkr.hcl"
}
([ImageType]::UbuntuMinimal) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-minimal.pkr.hcl"
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "build.ubuntu-24_04.pkr.hcl"
$imageOS = "ubuntu24"
}
default { throw "Unknown type of image" }
}

$imageTemplatePath = [IO.Path]::Combine($RepositoryRoot, "images", $relativeTemplatePath)
# Specific template selection using Packer's "-only" functionality
$buildName = [IO.Path]::GetFileName($imageTemplatePath).Split(".")[1]

if (-not (Test-Path $imageTemplatePath)) {
throw "Template for image '$ImageType' doesn't exist on path '$imageTemplatePath'."
}

return $imageTemplatePath;
return [PSCustomObject] @{
"BuildName" = $buildName
"ImageOS" = $imageOS
"Path" = [IO.Path]::GetDirectoryName($imageTemplatePath)
}
}

Function Show-LatestCommit {
Expand Down Expand Up @@ -81,7 +88,7 @@ Function GenerateResourcesAndImage {
.PARAMETER ResourceGroupName
The name of the resource group to store the resulting artifact. Resource group must already exist.
.PARAMETER ImageType
The type of image to generate. Valid values are: Windows2019, Windows2022, Windows2025, Ubuntu2204, Ubuntu2404, UbuntuMinimal.
The type of image to generate. Valid values are: Windows2019, Windows2022, Windows2025, Ubuntu2204, Ubuntu2404.
.PARAMETER ManagedImageName
The name of the managed image to create. The default is "Runner-Image-{{ImageType}}".
.PARAMETER AzureLocation
Expand Down Expand Up @@ -155,8 +162,8 @@ Function GenerateResourcesAndImage {
}

# Get template path
$TemplatePath = Get-PackerTemplatePath -RepositoryRoot $ImageGenerationRepositoryRoot -ImageType $ImageType
Write-Debug "Template path: $TemplatePath."
$PackerTemplate = Get-PackerTemplate -RepositoryRoot $ImageGenerationRepositoryRoot -ImageType $ImageType
Write-Debug "Template path: $($PackerTemplate.Path)."

# Prepare list of allowed inbound IP addresses
if ($RestrictToAgentIpAddress) {
Expand Down Expand Up @@ -208,17 +215,19 @@ Function GenerateResourcesAndImage {

Write-Host "Validating packer template..."
& $PackerBinary validate `
"-only=$($PackerTemplate.BuildName)*" `
"-var=client_id=fake" `
"-var=client_secret=fake" `
"-var=subscription_id=$($SubscriptionId)" `
"-var=tenant_id=fake" `
"-var=location=$($AzureLocation)" `
"-var=image_os=$($PackerTemplate.ImageOS)" `
"-var=managed_image_name=$($ManagedImageName)" `
"-var=managed_image_resource_group_name=$($ResourceGroupName)" `
"-var=install_password=$($InstallPassword)" `
"-var=allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" `
"-var=azure_tags=$($TagsJson)" `
$TemplatePath
$PackerTemplate.Path

if ($LastExitCode -ne 0) {
throw "Packer template validation failed."
Expand Down Expand Up @@ -276,17 +285,19 @@ Function GenerateResourcesAndImage {
Write-Debug "Tenant id: $TenantId."

& $PackerBinary build -on-error="$($OnError)" `
-only "$($PackerTemplate.BuildName)*" `
-var "client_id=$($ServicePrincipalAppId)" `
-var "client_secret=$($ServicePrincipalPassword)" `
-var "subscription_id=$($SubscriptionId)" `
-var "tenant_id=$($TenantId)" `
-var "location=$($AzureLocation)" `
-var "image_os=$($PackerTemplate.ImageOS)" `
-var "managed_image_name=$($ManagedImageName)" `
-var "managed_image_resource_group_name=$($ResourceGroupName)" `
-var "install_password=$($InstallPassword)" `
-var "allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" `
-var "azure_tags=$($TagsJson)" `
$TemplatePath
$PackerTemplate.Path

if ($LastExitCode -ne 0) {
throw "Failed to build image."
Expand Down
16 changes: 11 additions & 5 deletions images.CI/linux-and-win/build-image.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
param(
[String] [Parameter (Mandatory=$true)] $TemplatePath,
[String] [Parameter (Mandatory=$true)] $BuildTemplateName,
[String] [Parameter (Mandatory=$true)] $ClientId,
[String] [Parameter (Mandatory=$false)] $ClientSecret,
[String] [Parameter (Mandatory=$true)] $Location,
Expand All @@ -8,7 +9,9 @@ param(
[String] [Parameter (Mandatory=$true)] $TempResourceGroupName,
[String] [Parameter (Mandatory=$true)] $SubscriptionId,
[String] [Parameter (Mandatory=$true)] $TenantId,
[String] [Parameter (Mandatory=$false)] $pluginVersion = "2.2.1",
[String] [Parameter (Mandatory=$true)] $ImageOS, # e.g. "ubuntu22", "ubuntu22" or "win19", "win22", "win25"
[String] [Parameter (Mandatory=$false)] $UseAzureCliAuth = "false",
[String] [Parameter (Mandatory=$false)] $PluginVersion = "2.3.3",
[String] [Parameter (Mandatory=$false)] $VirtualNetworkName,
[String] [Parameter (Mandatory=$false)] $VirtualNetworkRG,
[String] [Parameter (Mandatory=$false)] $VirtualNetworkSubnet,
Expand All @@ -22,7 +25,7 @@ if (-not (Test-Path $TemplatePath))
exit 1
}

$ImageTemplateName = [io.path]::GetFileName($TemplatePath).Split(".")[0]
$buildName = $($BuildTemplateName).Split(".")[1]
$InstallPassword = [System.GUID]::NewGuid().ToString().ToUpper()

$SensitiveData = @(
Expand All @@ -44,13 +47,15 @@ Write-Host "Download packer plugins"
packer plugins install github.com/hashicorp/azure $pluginVersion

Write-Host "Validate packer template"
packer validate -syntax-only $TemplatePath
packer validate -syntax-only -only "$buildName*" $TemplatePath

Write-Host "Build $ImageTemplateName VM"
packer build -var "client_id=$ClientId" `
Write-Host "Build $buildName VM"
packer build -only "$buildName*" `
-var "client_id=$ClientId" `
-var "client_secret=$ClientSecret" `
-var "install_password=$InstallPassword" `
-var "location=$Location" `
-var "image_os=$ImageOS" `
-var "managed_image_name=$ImageName" `
-var "managed_image_resource_group_name=$ImageResourceGroupName" `
-var "subscription_id=$SubscriptionId" `
Expand All @@ -60,6 +65,7 @@ packer build -var "client_id=$ClientId" `
-var "virtual_network_resource_group_name=$VirtualNetworkRG" `
-var "virtual_network_subnet_name=$VirtualNetworkSubnet" `
-var "allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" `
-var "use_azure_cli_auth=$UseAzureCliAuth" `
-var "azure_tags=$azure_tags" `
-color=false `
$TemplatePath `
Expand Down
Loading