Alliances
1762924 Members
2845 Online
108909 Solutions
New Article
Patrick_Lownds

Building Custom Azure Images with Packer by HashiCorp

HashiCorp Packer offers a powerful tool for automating the creation of custom virtual machine images for various cloud platforms, including Microsoft Azure. This HPE_ELEMENT_Blog.jpgblog post guides you through the initial steps of using Packer to build your own Azure images.

Why Use Packer for Azure Images?

Packer offers a powerful solution for streamlining the development and deployment of custom Azure virtual machine images. It allows you to automate the entire build process, including setting configurations, installing necessary software, and customising settings, all within a single, reusable template. This not only saves you significant time compared to manual image creation but also ensures consistency and repeatability across your Azure deployments.

  • Infrastructure as Code (IaC): Packer templates define the image build process, making it repeatable, version-controlled, and manageable.
  • Customisation: Build images with specific configurations, pre-installed software, and personalised settings.
  • Flexibility: Packer supports different builders (azure-arm, azure-chroot, azure-dtl) for various workflows.

Alternatives to Consider:

While Packer provides a powerful, flexible tool for building Azure images, Microsoft's Azure VM Image Builder offers a managed service alternative. This simplifies the process by providing a user-friendly interface for defining image builds and leverages Packer templates under the hood for customisation, making it a good option for those seeking a more streamlined approach within the Azure ecosystem.

How do you install Packer?

For a smoother workflow, consider installing Packer using the pre-compiled binaries from the official website. This method offers a quick and convenient way to get started, allowing you to download the appropriate binary for your specific operating system (Windows, macOS, or Linux) and build Azure images in no time.

Pre-compiled Binaries:

  1. Visit the Packer downloads page: https://developer.hashicorp.com/packer/tutorials/docker-get-started/get-started-install-cli
  2. Download the appropriate binary for your operating system (Windows, macOS or Linux).
  3. In the case of Windows, unzip the downloaded file. You'll find a binary named packer.exe

Verifying a successful Packer installation

In Windows, verifying a successful Packer installation is a simple process:

  1. Open your command prompt or terminal. You can use the Start menu search or press the Windows key + R, type "cmd", and press Enter.
  2. Run the packer --version command. This command instructs Packer to display its installed version information.
  3. Observe the output. If Packer is installed correctly, you should see the installed Packer version number displayed in the terminal window.

Verifying Packer installationVerifying Packer installation

The alternative option is to use Azure Cloud Shell

Azure Cloud Shell comes pre-equipped with Packer (today) version 1.10.1 but the current version is 1.10.3. This eliminates the need for software installation. With Packer readily available, Azure Cloud Shell transforms into a one-stop location for managing your entire Azure virtual machine image creation workflow and is convenient if working with Azure only.

Packer in Azure Cloud ShellPacker in Azure Cloud Shell

Even though Packer is available in Azure Cloud Shell, Packer itself isn't integrated by default with Azure, so you still need to install the Azure plugin and you can do this within the Azure Cloud Shell by running the following command packer plugins install github.com/hashicorp/azure

Azure Prerequisites

Building Azure images with Packer requires a well-provisioned Azure environment. This includes having an active Azure subscription to cover resource usage e.g. Azure Resource Group, the Azure CLI installed and configured to interact with your Azure resources through commands, and a service principal with the necessary permissions to allow Packer to interact with Azure on your behalf.

  • An Azure subscription
  • An Azure Resource Group
  • Azure CLI is installed and configured to interact with your Azure environment.
  • Create an Azure service principal with "Contributor" RBAC on the Subscription or on the specific Resource Group where Packer will create an Image.

Troubleshooting

If you don't see any version information after running the command, it might indicate that Packer is not installed or not accessible from your current location. Here are some troubleshooting steps:

  • Double-check the installation: Ensure you downloaded the correct Packer binary for your Windows version (32-bit or 64-bit) from the official website: https://developer.hashicorp.com/packer/install.
  • Verify path addition (if applicable): If you downloaded the standalone binary, you might need to add the directory containing the packer.exe file to your system's PATH environment variable. This allows you to run Packer commands from any location in your terminal. Refer to Microsoft documentation for detailed instructions on managing environment variables in Windows.

Integrating Packer with Azure

Packer integrates with Azure through a plugin system, offering an automated and flexible approach to building custom VM images. These plugins act as bridges between Packer and Azure's APIs, allowing Packer templates to define the build process.

The Packer Workflow:

  1. Packer Template: You define a configuration file (JSON or HCL) specifying the build process. This includes:
    • Builders: Plugins like azure-arm, azure-chroot, or azure-dtl define how to interact with Azure for building the image.
    • Provisioners: These are scripts (Bash, PowerShell etc.) that run on the VM during the build process to install software, configure settings, etc.
  2. Packer Execution: You run Packer with the template file. Packer interacts with Azure based on the chosen builder:
    • azure-arm: Creates a new Azure VM, provisions it using scripts, and then captures the VM as a managed image or VHD.
    • azure-chroot: Uses an existing Azure VM, creates a chroot environment, installs software, and captures the resulting filesystem as a managed disk image.
    • azure-dtl: Provisions a VM in Azure DevTest Labs, configures it, and automatically uploads the captured image to the DevTest Lab image repository.
  3. Output Image: The final image is a managed disk image or VHD that you can use to deploy new VMs in Azure.

How do you install Plugins?

To capture the source VM built by Packer and use it as an image, you need to define an Azure resource group. This resource group temporarily stores the resources Packer uses during the build process, including the final image itself. From the Azure Cloud Shell, run the following command:

packer plugins install github.com/hashicorp/azure

Installing the Azure pluginInstalling the Azure plugin

Azure Cloud Shell empowers you to manage your Azure resources directly from your web browser. This browser-based shell environment eliminates the need to set up a local development machine or install any additional software and because this blog post is limited to Azure, I'm going to use Azure Cloud Shell going forward, rather than run Packer locally on my development machine.

Configuring the Azure environment

To capture the source VM built by Packer and use it as an image, you need to define an Azure resource group. This group temporarily stores the resources Packer uses during the build process, including the final image itself. From the Azure Cloud Shell, run the following command:

$rgName = "myPackerRG"

$location = "North Europe"

New-AzResourceGroup -Name $rgName -Location $location

Packer authenticates with Azure through a service principal. Think of this as a secure identity you create that grants Packer access to Azure. You have full control over the permissions assigned to this identity, allowing you to customise it to your specific needs when building images. Run the following command:

$sp = New-AzADServicePrincipal -DisplayName "PackerServicePrincipal" -role Contributor -scope /subscriptions/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
$plainPassword = (New-AzADSpCredential -ObjectId $sp.Id).SecretText

To view the output of your password and application ID, run the following:

$plainPassword
$sp.AppId

Finally, To authenticate to Azure, you also need to obtain your Azure tenant and subscription IDs with Get-AzSubscription:

$subName = "mySubscriptionName"
$sub = Get-AzSubscription -SubscriptionName $subName

Defining your first template

Packer templates define the entire image creation process in a human-readable format using HCL (HashiCorp Configuration Language). This structure utilises variables for reusable configuration values, builders to specify the image creation method e.g. Azure, and optional provisioners to execute scripts for software installation or configuration during the build.

In my opinion, HCL's clear syntax with blocks improves code organisation and readability compared to JSON. By leveraging variables and separate blocks, you can easily manage and customise your image creation workflows within a single Packer template. This approach promotes consistency and repeatability in building virtual machine images across various cloud platforms and not just Azure. Here's an explanation of how to define a Packer template in HCL:

  •   Variables: These represent configuration values that can be reused throughout the template. You define them with a variable block, specifying the type (e.g., string, number, list, etc.) and optionally marking sensitive information with sensitive = true.
  •   Builders: This block defines the method used to create the virtual machine image. Packer offers various builders depending on your workflow e.g., azure-arm. Each builder block contains specific configuration options for the chosen builder.
  •   Provisioners (Optional): These blocks define scripts or commands that are executed on the VM during the build process. They are typically used for installing software, configuring settings, or customizing the image. You can use various provisioner types like shell, PowerShell, file, etc., based on your needs.

Sample Packer template for Windows Server 2022Sample Packer template for Windows Server 2022

Alternatively, you can use the Packer init command to help you get started with a basic Packer template. This command serves as the starting point, creating a basic Packer configuration file (usually named template.pkr.hcl) in the current directory. This file defines the blueprint for your image build. The final step in creating your template is to run Packer fmt. This command acts as a code formatter for your Packer template file. It takes your template and rewrites it in a consistent and readable format.

Building your image

With your Packer template meticulously crafted you've laid the groundwork for a robust image build process. The next step is to validate your template with the Packer validate command. This command acts as a quality check for your Packer template. It specifically focuses on the syntax and configuration of your template, ensuring it's free of errors and ready for the build process.

The final step is to leverage this template with the Packer build command. This will instruct Packer to spring into action, utilising the builders and provisioners you have defined to construct your image. Get ready to see your configuration transform into a functional machine image, ready to be deployed to your Azure environment.

Packer build commandPacker build command

Integrating Packer with Azure DevOps

While not strictly part of this blog post, now that you've successfully built your image using Packer, it's time to start considering unleashing its potential! Azure DevOps provides a powerful platform to integrate Packer into your DevOps pipeline. This allows for a streamlined and automated image creation process.

By incorporating Packer tasks within your Azure DevOps pipeline, you can trigger image builds alongside your code deployments. This means whenever you commit changes to your codebase, the pipeline can automatically execute Packer build. This not only automates image creation but also ensures consistency and reduces the risk of errors from manual builds. Imagine deploying your application updates alongside freshly built, up-to-date images! Additionally, Azure DevOps integrates with various cloud providers, allowing you to seamlessly publish your Packer-built images to other platforms or a private container registry.

Conclusion

Packer simplifies the process of building machine images, offering significant advantages for developers and operations teams. It automates the build process, eliminating manual steps and errors. Packer ensures consistent images across different environments, promoting predictable deployments. Furthermore, it supports a variety of cloud providers and virtualization platforms, providing flexibility in where you deploy your images. By streamlining image creation and integrating with DevOps pipelines, Packer frees up valuable IT resources and accelerates the software development lifecycle.

For more information on the many ways we can help you, https://www.hpe.com/uk/en/services/pointnext.html 

Patrick Lownds
Hewlett Packard Enterprise

twitter.com/HPE_TechSvcs 

linkedin.com/showcase/hpe-technology-services/ 

hpe.com/hpe-services 

About the Author

Patrick_Lownds