-> Behind the scenes Packer uses the OAuth protocol to authenticate against Azure Active Directory and authorize requests to the Azure Service Management API. These topics are unnecessarily complicated so we will try to ignore them for the rest of this document.<br/><br/>You do not need to understand how OAuth works in order to use Packer with Azure, though the Active Directory terms "service principal" and "role" will be useful for understanding Azure's access policies.
To get the credentials above, we will need to install the Azure CLI. Please refer to Microsoft's official [installation guide](https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/).
-> The guides below also use a tool called [`jq`](https://stedolan.github.io/jq/) to simplify the output from the Azure CLI, though this is optional. If you use homebrew you can simply `brew install node jq`.
If you already have node.js installed you can use `npm` to install `azure-cli`:
The Packer project includes a [setup script](https://github.com/mitchellh/packer/blob/master/contrib/azure-setup.sh) that can help you setup your account. It uses an interactive bash script to log you into Azure, name your resources, and export your Packer configuration.
If you want more control or the script does not work for you, you can also use the manual instructions below to setup your Azure account. You will need to manually keep track of the various account identifiers, resource names, and your service principal password.
### Identify Your Tenant and Subscription IDs
Login using the Azure CLI
azure config mode arm
azure login -u USERNAME
Get your account information
azure account list --json | jq .[].name
azure account set ACCOUNTNAME
azure account show --json | jq ".[] | .tenantId, .id"
-> Throughout this document when you see a command pipe to `jq` you may instead omit `--json` and everything after it, but the output will be more verbose. For example you can simply run `azure account list` instead._
This will print out two lines that look like this:
"4f562e88-8caf-421a-b4da-e3f6786c52ec"
"b68319b-2180-4c3e-ac1f-d44f5af2c6907"
The first one is your `tenant_id`. The second is your `subscription_id`. Note these for later.
### Create a Resource Group
A [resource group](https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/#resource-groups) is used to organize related resources. Resource groups and storage accounts are tied to a location. To see available locations, run:
azure location list
...
azure group create -n GROUPNAME -l LOCATION
Your storage account (below) will need to use the same `GROUPNAME` and `LOCATION`.
We will need to create a storage account where your Packer artifacts will be stored. We will create a `LRS` storage account which is the least expensive price/GB at the time of writing.
-> `LRS` is meant as a literal "LRS" and not as a variable.
Make sure that `GROUPNAME` and `LOCATION` are the same as above.
### Create an Application
An application represents a way to authorize access to the Azure API. Note that you will need to specify a URL for your application (this is intended to be used for OAuth callbacks) but these do not actually need to be valid URLs.
Password is your `client_secret` and can be anything you like. I recommend using `openssl rand -base64 24`.
### Create a Service Principal
You cannot directly grant permissions to an application. Instead, you create a service principal associated with the application and assign permissions to the service principal.
First, get the `APPID` for the application we just created.
Finally, we will associate the proper permissions with our application's service principal. We're going to assign the `Owner` role to our Packer application and change the scope to manage our whole subscription. (The `Owner` role can be scoped to a specific resource group to further reduce the scope of the account.) This allows Packer to create temporary resource groups for each build.
azure role assignment create --spn APPURL -o "Owner" \
-c /subscriptions/SUBSCRIPTIONID
There are a lot of pre-defined roles and you can define your own with more granular permissions, though this is out of scope. You can see a list of pre-configured roles via: