Documentation for the Azure builder. (#3518)

This commit is contained in:
Christopher Boumenot 2016-05-17 14:15:24 -07:00 committed by Chris Bednarski
parent 5484b9c7d0
commit 83e6044595
3 changed files with 115 additions and 12 deletions

View File

@ -152,7 +152,7 @@ func (c *Config) createCertificate() (string, error) {
host := fmt.Sprintf("%s.cloudapp.net", c.tmpComputeName)
notBefore := time.Now()
notAfter := notBefore.Add(365 * 24 * time.Hour)
notAfter := notBefore.Add(24 * time.Hour)
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
if err != nil {

View File

@ -7,22 +7,44 @@ page_title: Authorizing Packer Builds in Azure
# Authorizing Packer Builds in Azure
In order to build VMs in Azure packer needs 6 configuration options to be specified:
In order to build VMs in Azure Packer needs 6 configuration options to be specified:
- `tenant_id` - UUID identifying your Azure account (where you login)
- `subscription_id` - UUID identifying your Azure subscription (where billing is handled)
- `client_id` - UUID identifying the Active Directory service principal that will run your packer builds
- `client_id` - UUID identifying the Active Directory service principal that will run your Packer builds
- `client_secret` - service principal secret / password
- `resource_group_name` - name of the resource group where your VHD(s) will be stored
- `storage_account` - name of the storage account where your VHD(s) will be stored
-> 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 unncessarily 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.
-> 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.
In order to get all of the items above, you will need a username and password for your Azure account.
## Device Login
Device login is an alternative way to authorize in Azure Packer. Device login only requires you to know your
Subscription ID. (Device login is only supported for Linux based VMs.) Device login is intended for those who are first
time users, and just want to ''kick the tires.'' We recommend the SPN approach if you intend to automate Packer, or for
deploying Windows VMs.
> Device login is for **interactive** builds, and SPN is **automated** builds.
There are three pieces of information you must provide to enable device login mode.
1. SubscriptionID
1. Resource Group - parent resource group that Packer uses to build an image.
1. Storage Account - storage account where the image will be placed.
> Device login mode is enabled by not setting client_id, client_secret, and tenant_id.
The device login flow asks that you open a web browser, navigate to http://aka.ms/devicelogin, and input the supplied
code. This authorizes the Packer for Azure application to act on your behalf. An OAuth token will be created, and stored
in the user's home directory (~/.azure/packer/oauth-TenantID.json). This token is used if the token file exists, and it
is refreshed as necessary. The token file prevents the need to continually execute the device login flow.
## Install the Azure CLI
To get the credentials above, we will need to install the Azure CLI. Please refer to Microsoft's official [intallation guide](https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/).
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`.
@ -32,7 +54,7 @@ If you already have node.js installed you can use `npm` to install `azure-cli`:
## Guided Setup
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.
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.
## Manual Setup
@ -72,7 +94,7 @@ Your storage account (below) will need to use the same `GROUPNAME` and `LOCATION
### Create a Storage Account
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.
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.
azure storage account create -g GROUPNAME \
-l LOCATION --type LRS STORAGENAME
@ -101,7 +123,7 @@ First, get the `APPID` for the application we just created.
### Grant Permissions to Your Application
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. This allows Packer to create temporary resource groups for each build.
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
@ -111,6 +133,7 @@ There are a lot of pre-defined roles and you can define your own with more granu
azure role list --json | \
jq ".[] | {name:.Name, description:.Description}"
### Configuring Packer
Now (finally) everything has been setup in Azure. Let's get our configuration keys together:

View File

@ -66,8 +66,10 @@ builder.
- `image_version` (string) Specify a specific version of an OS to boot from.
Defaults to `latest`.
- `object_id` (string) Specify an OAuth Object ID to automatically
authenticate with the VM. See `Windows` behavior for `os_type`, below.
- `object_id` (string) Specify an OAuth Object ID to protect WinRM certificates
created at runtime. This variable is required when creating images based on
Windows; this variable is not used by non-Windows builds. See `Windows`
behavior for `os_type`, below.
- `os_type` (string) If either `Linux` or `Windows` is specified Packer will
automatically configure authentication credentials for your machine. For
@ -100,13 +102,91 @@ Here is a basic example for Azure.
"capture_container_name": "images",
"capture_name_prefix": "packer",
"os_type": "Linux",
"image_publisher": "Canonical",
"image_offer": "UbuntuServer",
"image_sku": "14.04.3-LTS",
"image_sku": "14.04.4-LTS",
"location": "West US",
"vm_size": "Standard_A2"
}
```
See the [examples/azure](https://github.com/mitchellh/packer/tree/master/examples/azure) folder in the packer project for more examples.
## Implementation
\~&gt; **Warning!** This is an advanced topic. You do not need to understand the implementation to use the Azure
builder.
The Azure builder uses ARM
[templates](https://azure.microsoft.com/en-us/documentation/articles/resource-group-authoring-templates/) to deploy
resources. ARM templates make it easy to express the what without having to express the how.
The Azure builder works under the assumption that it creates everything it needs to execute a build. When the build has
completed it simply deletes the resource group to cleanup any runtime resources. Resource groups are named using the
form `packer-Resource-Group-<random>`. The value `<random>` is a random value that is generated at every invocation of
packer. The `<random>` value is re-used as much as possible when naming resources, so users can better identify and
group these transient resources when seen in their subscription.
> The VHD is created on a user specified storage account, not a random one created at runtime. When a virtual machine
is captured the resulting VHD is stored on the same storage account as the source VHD. The VHD created by Packer must
persist after a build is complete, which is why the storage account is set by the user.
The basic steps for a build are:
1. Create a resource group.
1. Validate and deploy a VM template.
1. Execute provision - defined by the user; typically shell commands.
1. Power off and capture the VM.
1. Delete the resource group.
1. Delete the temporary VM's OS disk.
The templates used for a build are currently fixed in the code. There is a template for Linux, Windows, and KeyVault.
The templates are themselves templated with place holders for names, passwords, SSH keys, certificates, etc.
### What's Randomized?
The Azure builder creates the following random values at runtime.
* Administrator Password: a random 32-character value using the *password alphabet*.
* Certificate: a 2,048-bit certificate used to secure WinRM communication. The certificate is valid for 24-hours, which starts roughly at invocation time.
* Certificate Password: a random 32-character value using the *password alphabet* used to protect the private key of the certificate.
* Compute Name: a random 15-character name prefixed with pkrvm; the name of the VM.
* Deployment Name: a random 15-character name prefixed with pkfdp; the name of the deployment.
* KeyVault Name: a random 15-character name prefixed with pkrkv.
* OS Disk Name: a random 15-character name prefixed with pkros.
* Resource Group Name: a random 33-character name prefixed with packer-Resource-Group-.
* SSH Key Pair: a 2,048-bit asymmetric key pair; can be overriden by the user.
The default alphabet used for random values is **0123456789bcdfghjklmnpqrstvwxyz**. The alphabet was reduced (no
vowels) to prevent running afoul of Azure decency controls.
The password alphabet used for random values is **0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ**.
### Windows
The Windows implementation is very similar to the Linux build, with the exception that it deploys a template to
configure KeyVault. Packer communicates with a Windows VM using the WinRM protocol. Windows VMs on Azure default to
using both password and certificate based authentication for WinRM. The password is easily set via the VM ARM template,
but the certificate requires an intermediary. The intermediary for Azure is KeyVault. The certificate is uploaded to a
new KeyVault provisioned in the same resource group as the VM. When the Windows VM is deployed, it links to the
certificate in KeyVault, and Azure will ensure the certificate is injected as part of deployment.
The basic steps for a Windows build are:
1. Create a resource group.
1. Validate and deploy a KeyVault template.
1. Validate and deploy a VM template.
1. Execute provision - defined by the user; typically shell commands.
1. Power off and capture the VM.
1. Delete the resource group.
1. Delete the temporary VM's OS disk.
A Windows build requires two templates and two deployments. Unfortunately, the KeyVault and VM cannot be deployed at
the same time hence the need for two templates and deployments. The time required to deploy a KeyVault template is
minimal, so overall impact is small.
> The KeyVault certificate is protected using the object_id of the SPN. This is why Windows builds require object_id,
and an SPN. The KeyVault is deleted when the resource group is deleted.
See the [examples/azure](https://github.com/mitchellh/packer/tree/master/examples/azure) folder in the packer project
for more examples.