Skip to content

Packer templates for Azure infrastructure configured with Terraform

Notifications You must be signed in to change notification settings

deck15/packer-azure-terraform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Creating Packer Images in Azure with Terraform

The repository demonstrates simple usage of Terraform to configure an Azure infrastructure to store and use Packer images, and Packer templates to generate images to store in the Storage Account created in Azure.

Getting Started

You will need an Azure Service Principal Account. See Authorizing Packer Builds in Azure.

Variables used by Terraform

Variable Required Default Description
azure_client_id Yes Azure Client ID, Azure portal shows this as the Application ID.
azure_client_secret Yes Service principal secret / password. Found in Keys from the Settings menu.
azure_subscription_id Yes UUID identifying your Azure subscription.
azure_tenant_id Yes Tenant ID found in the application configure parameters, authorization endpoint ID
azure_object_id Yes Specify an OAuth Object ID to protect WinRM certificates created at runtime.
resourceGroupName Yes name of the resource group where your VHD(s) will be stored.
location No southcentralus Primary location for the resource group and storage account.
storageAccountPrefix No packerimages Prefix used for the storage account name where your VHDs will be stored.
storageAccountType No Standard_GRS Standard_LRS``Standard_GRS``Standard_RAGRS``Standard_ZRS``Premium_LRS

These variables are expected to be defined as environment variables, which are prefixed with TF_VAR_. If using with Jenkins, these can be defined as parameters and the azure connection information (first 4 variables above) defined as password parameters to mask them. See Notes (below) for obtaining the subscription and tenant IDs through the Azure CLI

Variables used by Packer

Variable Required Default / Source
azure_subscription_id Yes env var: TF_VAR_azure_subscription_id
azure_client_id Yes env var: TF_VAR_azure_client_id
azure_client_secret Yes env var: TF_VAR_azure_client_secret
azure_object_id Yes env var: azure_object_id
resource_group_name Yes env var: TF_VAR_resourceGroupName
location Yes env var: TF_VAR_location
storage_account Yes env var: storageAccountName
container_name No packer-images
capture_name_prefix No packer
vm_size No Standard_DS1_V2
image_publisher No MicrosoftWindowsServer
image_offer No WindowsServer
image_sku No 2016-Datacenter
winrm_username No Administrator

Step 1: Set Parameters for Terraform and Packer

# Mask these first 5 parameters...
export TF_VAR_azure_client_id=.....
export TF_VAR_azure_client_secret=.....
export TF_VAR_azure_subscription_id=.....
export TF_VAR_azure_tenant_id=.....
export azure_object_id=.....

export TF_VAR_resourceGroupName="packerimages"
export TF_VAR_location="westus"
export TF_VAR_storageAccountPrefix="images"
export captureContainerName="custom-images"

Step 2: Run Terraform

Validate and apply terraform plan.

terraform plan

terraform apply

Step 3: Run Packer

Validate packer template and apply using storage account name from Terraform tfstate:

Option 1: Packer Variables from Environment

Packer will take variables assigned previously as environment variables.

# Inspect
packer inspect packer_windows.json

# Set storage account name as environment variable
export storageAccountName=$(terraform output storage_account_name)

# Validate
packer validate packer_windows.json

# Build
packer build packer_windows.json

Variables can be overwritten with -var 'key=value' arguments.

Option 2: Variable File

Variables for Packer can also be set from an external JSON file. The -var-file flag reads a file containing a basic key/value mapping of variables to values and sets those variables. The JSON file is simple:

{
  "azure_subscription_id":  "xxxxx-xxxxx-xxxxxx-xxxxxx",
  "azure_client_id":        "xxxxx-xxxxx-xxxxxx-xxxxxx",
  "azure_client_secret":    "xxxxx-xxxxx-xxxxxx-xxxxxx",
  "azure_object_id":        "xxxxx-xxxxx-xxxxxx-xxxxxx",
  "azure_tenant_id":        "xxxxx-xxxxx-xxxxxx-xxxxxx",

  "resource_group_name":    "MyResourceGroup",
  "location":               "westus",
  "container_name":         "packer-images",
  "capture_name_prefix":    "packer",

  "vm_size":                "Standard_DS1_V2",
  "image_publisher":        "MicrosoftWindowsServer",
  "image_offer":            "WindowsServer",
  "image_sku":              "2016-Datacenter",

  "winrm_username":         "Administrator"
}

It is a single JSON object where the keys are variables and the values are the variable values. Assuming this file is in variables.json, we can build our template using the following command:

# Set storage account name as variable
storageAccountName=$(terraform output storage_account_name)

packer validate \
  -var-file=variables.json \
  -var storage_account=$storageAccountName \
  packer_windows.json

packer build \
  -var-file=variables.json \
  -var storage_account=$storageAccountName \
  packer_windows.json

Notes:

The Subscription ID, Object ID, and Tenant ID can be obtained by using the azure cli. Ensure you're logged in by using azure login and following instructions.

$ azure account show
info:    Executing command account show
data:    Name                        : <Your Subscription Name>
data:    ID                          : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
data:    State                       : Enabled
data:    Tenant ID                   : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
data:    Is Default                  : true
data:    Environment                 : AzureCloud
data:    Has Certificate             : Yes
data:    Has Access Token            : Yes
data:    User name                   : [email protected]
data:
info:    account show command OK

To obtain the object_id required by Packer:

$ azure ad sp show -n CLIENT_ID

About

Packer templates for Azure infrastructure configured with Terraform

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages