azure-image-builder
hashicorp/agent-skills
Build custom Azure managed images and Compute Gallery images with Packer
What is azure-image-builder?
This skill uses Packer's azure-arm builder to create custom images for Azure VMs. Use it when you need to build managed images or publish images to Azure Compute Gallery with custom configurations and provisioning steps.
- Build Azure managed images with custom OS and provisioning
- Publish images to Azure Compute Gallery with replication across regions
- Support both service principal and managed identity authentication
- Apply custom provisioning via shell, scripts, or other Packer provisioners
- Tag images with metadata for organization and tracking
- Validate and initialize Packer templates before building
How to install azure-image-builder
npx skills add https://github.com/hashicorp/agent-skills --skill azure-image-builder- Azure subscription with Contributor role on target resource group
- Service principal credentials (client ID, client secret, subscription ID, tenant ID) or Azure CLI authentication configured
- Packer installed locally or in CI/CD environment
- Azure CLI installed for creating service principals
How to use azure-image-builder
- 1.Set up Azure authentication by creating a service principal or configuring managed identity
- 2.Define variables for subscription_id, tenant_id, client_id, and client_secret in your Packer template
- 3.Configure the azure-arm source block with desired OS image, location, and VM size
- 4.Add provisioners (shell, scripts, etc.) to customize the image during build
- 5.Run `packer init` to download required Azure plugin
- 6.Run `packer validate` to check template syntax
- 7.Run `packer build` to create the image (15-45 minutes typical)
- 8.Verify the image in Azure Portal under Managed Images or Compute Gallery
Use cases
- Create a custom Ubuntu image with pre-installed application dependencies for VM deployments
- Build and publish a hardened Windows image to a shared gallery for enterprise use
- Generate timestamped managed images for CI/CD pipelines that deploy to Azure VMs
- Replicate a custom image across multiple Azure regions for disaster recovery
- Build images with specific software versions locked in for compliance requirements
- Infrastructure engineers building custom Azure VM images
- DevOps teams automating image creation in CI/CD pipelines
- Cloud architects managing shared image galleries across teams
- System administrators creating standardized OS images for enterprise deployments
azure-image-builder FAQ
Use either a service principal (set ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_SUBSCRIPTION_ID, ARM_TENANT_ID environment variables) or managed identity (set use_azure_cli_auth = true in the source block).
Yes, use the shared_image_gallery_destination block with replication_regions to publish to Azure Compute Gallery and replicate across regions automatically.
Builds incur costs for compute (VM running during build), storage, and data transfer. Typical builds take 15-45 minutes depending on provisioning complexity.
Image versions in Compute Gallery are immutable. Use unique version numbers with dates or build numbers (e.g., 1.0.20240115) to avoid conflicts.
Check network connectivity from the build VM, verify NSG rules allow required traffic, and increase the timeout value if needed.
Full instructions (SKILL.md)
Source of truth, from hashicorp/agent-skills.
name: azure-image-builder description: Build Azure managed images and Azure Compute Gallery images with Packer. Use when creating custom images for Azure VMs.
Azure Image Builder
Build Azure managed images and Azure Compute Gallery images using Packer's azure-arm builder.
Reference: Azure ARM Builder
Note: Building Azure images incurs costs (compute, storage, data transfer). Builds typically take 15-45 minutes depending on provisioning and OS.
Basic Managed Image
packer {
required_plugins {
azure = {
source = "github.com/hashicorp/azure"
version = "~> 2.0"
}
}
}
variable "client_id" {
type = string
sensitive = true
}
variable "client_secret" {
type = string
sensitive = true
}
variable "subscription_id" {
type = string
}
variable "tenant_id" {
type = string
}
variable "resource_group" {
type = string
default = "packer-images-rg"
}
locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}
source "azure-arm" "ubuntu" {
client_id = var.client_id
client_secret = var.client_secret
subscription_id = var.subscription_id
tenant_id = var.tenant_id
managed_image_resource_group_name = var.resource_group
managed_image_name = "my-app-${local.timestamp}"
os_type = "Linux"
image_publisher = "Canonical"
image_offer = "0001-com-ubuntu-server-jammy"
image_sku = "22_04-lts-gen2"
location = "East US"
vm_size = "Standard_B2s"
azure_tags = {
Name = "my-app"
BuildDate = local.timestamp
}
}
build {
sources = ["source.azure-arm.ubuntu"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get upgrade -y",
]
}
}
Azure Compute Gallery
source "azure-arm" "ubuntu" {
client_id = var.client_id
client_secret = var.client_secret
subscription_id = var.subscription_id
tenant_id = var.tenant_id
os_type = "Linux"
image_publisher = "Canonical"
image_offer = "0001-com-ubuntu-server-jammy"
image_sku = "22_04-lts-gen2"
location = "East US"
vm_size = "Standard_B2s"
shared_image_gallery_destination {
resource_group = "gallery-rg"
gallery_name = "myImageGallery"
image_name = "ubuntu-webapp"
image_version = "1.0.${formatdate("YYYYMMDD", timestamp())}"
replication_regions = ["East US", "West US 2"]
storage_account_type = "Standard_LRS"
}
}
Authentication
Service Principal
# Create service principal
az ad sp create-for-rbac \
--name "packer-sp" \
--role Contributor \
--scopes /subscriptions/<subscription-id>
# Set environment variables
export ARM_CLIENT_ID="<client-id>"
export ARM_CLIENT_SECRET="<client-secret>"
export ARM_SUBSCRIPTION_ID="<subscription-id>"
export ARM_TENANT_ID="<tenant-id>"
Managed Identity
source "azure-arm" "ubuntu" {
use_azure_cli_auth = true
subscription_id = var.subscription_id
# ... rest of configuration
}
Build Commands
# Set authentication
export ARM_CLIENT_ID="your-client-id"
export ARM_CLIENT_SECRET="your-client-secret"
export ARM_SUBSCRIPTION_ID="your-subscription-id"
export ARM_TENANT_ID="your-tenant-id"
# Initialize plugins
packer init .
# Validate template
packer validate .
# Build image
packer build .
Common Issues
Authentication Failed
- Verify service principal credentials
- Ensure Contributor role on resource group
- Check subscription and tenant IDs
Compute Gallery Version Exists
- Image versions are immutable
- Use unique version numbers with date/build number
- Cannot overwrite existing versions
Timeout During Provisioning
- Check network connectivity from build VM
- Verify NSG rules allow required traffic
- Increase timeout if needed
References
Related skills
More from hashicorp/agent-skills and the wider catalog.

azure-verified-modules
Azure Verified Modules (AVM) requirements and best practices for certified Terraform modules on Azure.

new-terraform-provider
Scaffold a new Terraform provider using the Plugin Framework.

provider-actions
Implement Terraform Provider actions for imperative operations at lifecycle events.

provider-docs
Create and validate Terraform provider documentation for Registry using tfplugindocs and HashiCorp patterns.

provider-resources
Implement Terraform Provider resources and data sources using the Plugin Framework.

provider-test-patterns
Terraform provider acceptance test patterns with terraform-plugin-testing and Plugin Framework.