diff --git a/.github/workflows/ensure-docs-compiled.yaml b/.github/workflows/ensure-docs-compiled.yaml new file mode 100644 index 00000000..74a174d3 --- /dev/null +++ b/.github/workflows/ensure-docs-compiled.yaml @@ -0,0 +1,22 @@ +name: Ensure Docs are Compiled +on: + push: +jobs: + ensure-docs-compiled: + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - shell: bash + run: make build-docs + - shell: bash + run: | + if [[ -z "$(git status -s)" ]]; then + echo "OK" + else + echo "Docs have been updated, but the compiled docs have not been committed." + echo "Run 'make build-docs', and commit the result to resolve this error." + exit 1 + fi + diff --git a/.github/workflows/go-test-darwin.yml b/.github/workflows/go-test-darwin.yml index 30bf6c40..9b9f601c 100644 --- a/.github/workflows/go-test-darwin.yml +++ b/.github/workflows/go-test-darwin.yml @@ -36,7 +36,7 @@ jobs: name: Darwin Go tests steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: | diff --git a/.github/workflows/go-test-linux.yml b/.github/workflows/go-test-linux.yml index 00fb01e0..092890c1 100644 --- a/.github/workflows/go-test-linux.yml +++ b/.github/workflows/go-test-linux.yml @@ -36,7 +36,7 @@ jobs: name: Linux Go tests steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: | diff --git a/.github/workflows/go-test-windows.yml b/.github/workflows/go-test-windows.yml index a0ed1f00..63033e60 100644 --- a/.github/workflows/go-test-windows.yml +++ b/.github/workflows/go-test-windows.yml @@ -36,7 +36,7 @@ jobs: name: Windows Go tests steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: | diff --git a/.github/workflows/go-validate.yml b/.github/workflows/go-validate.yml index 210ff848..7765a187 100644 --- a/.github/workflows/go-validate.yml +++ b/.github/workflows/go-validate.yml @@ -35,7 +35,7 @@ jobs: name: Go Mod Tidy steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go mod tidy @@ -46,7 +46,7 @@ jobs: name: Lint check steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - uses: golangci/golangci-lint-action@639cd343e1d3b897ff35927a75193d57cfcba299 # v3.6.0 @@ -60,7 +60,7 @@ jobs: name: Gofmt check steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: | @@ -78,7 +78,7 @@ jobs: name: Generate check steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: | diff --git a/.github/workflows/notify-integration-release-via-manual.yaml b/.github/workflows/notify-integration-release-via-manual.yaml new file mode 100644 index 00000000..2e658011 --- /dev/null +++ b/.github/workflows/notify-integration-release-via-manual.yaml @@ -0,0 +1,46 @@ +name: Notify Integration Release (Manual) +on: + workflow_dispatch: + inputs: + version: + description: "The release version (semver)" + default: 0.0.1 + required: false + branch: + description: "A branch or SHA" + default: 'main' + required: false +jobs: + notify-release: + runs-on: ubuntu-latest + steps: + - name: Checkout this repo + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + with: + ref: ${{ github.event.inputs.branch }} + # Ensure that Docs are Compiled + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + - shell: bash + run: make build-docs + - shell: bash + run: | + if [[ -z "$(git status -s)" ]]; then + echo "OK" + else + echo "Docs have been updated, but the compiled docs have not been committed." + echo "Run 'make build-docs', and commit the result to resolve this error." + exit 1 + fi + # Perform the Release + - name: Checkout integration-release-action + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + with: + repository: hashicorp/integration-release-action + path: ./integration-release-action + - name: Notify Release + uses: ./integration-release-action + with: + integration_identifier: "packer/hashicorp/azure" + release_version: ${{ github.event.inputs.version }} + release_sha: ${{ github.event.inputs.branch }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/notify-integration-release-via-tag.yaml b/.github/workflows/notify-integration-release-via-tag.yaml new file mode 100644 index 00000000..4fb62bcf --- /dev/null +++ b/.github/workflows/notify-integration-release-via-tag.yaml @@ -0,0 +1,40 @@ +name: Notify Integration Release (Tag) +on: + push: + tags: + - '*.*.*' # Proper releases + - '*.*.*-*' # Pre releases +jobs: + notify-release: + runs-on: ubuntu-latest + steps: + - name: Checkout this repo + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + with: + ref: ${{ github.ref }} + # Ensure that Docs are Compiled + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + - shell: bash + run: make build-docs + - shell: bash + run: | + if [[ -z "$(git status -s)" ]]; then + echo "OK" + else + echo "Docs have been updated, but the compiled docs have not been committed." + echo "Run 'make build-docs', and commit the result to resolve this error." + exit 1 + fi + # Perform the Release + - name: Checkout integration-release-action + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + with: + repository: hashicorp/integration-release-action + path: ./integration-release-action + - name: Notify Release + uses: ./integration-release-action + with: + integration_identifier: 'packer/hashicorp/azure' + release_version: ${{ github.ref_name }} + release_sha: ${{ github.ref }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/oidc-test.yaml b/.github/workflows/oidc-test.yaml index dce53666..22e97489 100644 --- a/.github/workflows/oidc-test.yaml +++ b/.github/workflows/oidc-test.yaml @@ -20,7 +20,7 @@ jobs: secrets-check: runs-on: ubuntu-latest outputs: - available: "${{ steps.check-secrets.outputs.available }}" + available: ${{ steps.check-secrets.outputs.available }} steps: # we check for the ACTIONS_ID_TOKEN_REQUEST_URL variable as a proxy for other secrets # it will be unset when running for a PR from a fork diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c0734f4..0ec531d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: - name: Unshallow run: git fetch --prune --unshallow - name: Set up Go - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: Describe plugin diff --git a/.web-docs/README.md b/.web-docs/README.md new file mode 100644 index 00000000..68676191 --- /dev/null +++ b/.web-docs/README.md @@ -0,0 +1,102 @@ +The Azure plugin can be used with HashiCorp Packer to create custom images on Azure. +To do so, the plugin exposes multiple builders, among which you can choose the one most adapted to your workflow. + +## Installation + +To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init). + +```hcl +packer { + required_plugins { + azure = { + source = "github.com/hashicorp/azure" + version = "~> 2" + } + } +} +``` + +Alternatively, you can use `packer plugins install` to manage installation of this plugin. + +```sh +$ packer plugins install github.com/hashicorp/azure +``` + +## Components + +Packer can create Azure virtual machine images through variety of ways depending on the strategy that you want to use for building the images. + +### Builders + +- [azure-arm](/packer/integrations/hashicorp/azure/latest/components/builder/arm) - The Azure ARM builder supports building Virtual Hard Disks (VHDs) and + Managed Images in Azure Resource Manager. +- [azure-chroot](/packer/integrations/hashicorp/azure/latest/components/builder/chroot) - The Azure chroot builder supports building a managed disk image without + launching a new Azure VM for every build, but instead use an already-running Azure VM. +- [azure-dtl](/packer/integrations/hashicorp/azure/latest/components/builder/dtl) - The Azure DevTest Labs builder builds custom images and uploads them to DevTest Lab image repository automatically. + +### Provisioners + +- [azure-dtlartifact](/packer/integrations/hashicorp/azure/latest/components/provisioner/dtlartifact) - The Azure DevTest Labs provisioner can be used to apply an artifact to a VM - Refer to [Add an artifact to a VM](https://docs.microsoft.com/en-us/azure/devtest-labs/add-artifact-vm) + +## Authentication + + + +Config allows for various ways to authenticate Azure clients. When +`client_id` and `subscription_id` are specified in addition to one and only +one of the following: `client_secret`, `client_jwt`, `client_cert_path` -- +Packer will use the specified Azure Active Directory (AAD) Service Principal +(SP). +If none ofthese options are specified, Packer will attempt to use the Managed Identity +and subscription of the VM that Packer is running on. This will only work if +Packer is running on an Azure VM with either a System Assigned Managed +Identity or User Assigned Managed Identity. + + + + +### Managed Identity + +If you're running Packer on an Azure VM with a [managed +identity](https://packer.io/docs/builders/azure#azure-managed-identity) you +don't need to specify any additional configuration options. As Packer will +attempt to use the Managed Identity and subscription of the VM that Packer is +running on. + +You can use a different subscription if you set `subscription_id`. If your VM +has multiple user assigned managed identities you will need to set `client_id` +too. + +### Interactive User Authentication + +To use interactive user authentication, you should specify +`use_interactive_auth` only. Packer will use cached credentials or redirect you +to a website to log in. + +### Service Principal + +To use a [service principal](https://packer.io/docs/builders/azure#azure-active-directory-service-principal) +you should specify `subscription_id`, `client_id` and one of `client_secret`, +`client_cert_path` or `client_jwt`. + +- `subscription_id` (string) - Subscription under which the build will be + performed. **The service principal specified in `client_id` must have full + access to this subscription, unless build_resource_group_name option is + specified in which case it needs to have owner access to the existing + resource group specified in build_resource_group_name parameter.** + +- `client_id` (string) - The Active Directory service principal associated with + your builder. + +- `client_secret` (string) - The password or secret for your service principal. + +- `client_cert_path` (string) - The location of a PEM file containing a + certificate and private key for service principal. + +- `client_cert_token_timeout` (duration string | ex: "1h30m12s") - How long to set the expire time on the token created when using + `client_cert_path`. + +- `client_jwt` (string) - The bearer JWT assertion signed using a certificate + associated with your service principal principal. See [Azure Active + Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) + for more information. diff --git a/.web-docs/components/builder/arm/README.md b/.web-docs/components/builder/arm/README.md new file mode 100644 index 00000000..1df0cc27 --- /dev/null +++ b/.web-docs/components/builder/arm/README.md @@ -0,0 +1,1161 @@ +Type: `azure-arm` +Artifact BuilderId: `Azure.ResourceManagement.VMImage` + +Packer supports building Virtual Hard Disks (VHDs) and Managed Images in [Azure Resource +Manager](https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/). +Azure provides new users a [`$200` credit for the first 30 +days](https://azure.microsoft.com/en-us/free/); after which you will incur +costs for VMs built and stored using Packer. + +Azure uses a combination of OAuth and Active Directory to authorize requests to +the ARM API. Learn how to [authorize access to +ARM](https://packer.io/docs/builder/azure#authentication-for-azure). + +The documentation below references command output from the [Azure +CLI](https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/). + +## Configuration Reference + +There are many configuration options available for the builder. We'll start +with authentication parameters, then go over the Azure ARM builder specific +options. In addition to the options listed here, a [communicator](https://packer.io/docs/templates/legacy_json_templates/communicator) can be configured for this builder. + +### Azure ARM builder specific options + +The Azure builder can create either a VHD, managed image or create a Shared Image Gallery. +If you are creating a VHD, you **must** start with a VHD. Likewise, if you want to create +a managed image you **must** start with a managed image. +Managed images can also be published to shared image galleries, +but a managed image definition is not required to publish to a gallery. + +### Required: + + + +- `image_publisher` (string) - Name of the publisher to use for your base image (Azure Marketplace Images only). See + [documentation](https://docs.microsoft.com/en-us/cli/azure/vm/image) + for details. + + CLI example `az vm image list-publishers --location westus` + +- `image_offer` (string) - Name of the publisher's offer to use for your base image (Azure Marketplace Images only). See + [documentation](https://docs.microsoft.com/en-us/cli/azure/vm/image) + for details. + + CLI example + `az vm image list-offers --location westus --publisher Canonical` + +- `image_sku` (string) - SKU of the image offer to use for your base image (Azure Marketplace Images only). See + [documentation](https://docs.microsoft.com/en-us/cli/azure/vm/image) + for details. + + CLI example + `az vm image list-skus --location westus --publisher Canonical --offer UbuntuServer` + +- `image_url` (string) - URL to a custom VHD to use for your base image. If this value is set, + image_publisher, image_offer, image_sku, or image_version should not be set. + +- `custom_managed_image_name` (string) - Name of a custom managed image to use for your base image. If this value is set, do + not set image_publisher, image_offer, image_sku, or image_version. + If this value is set, the option + `custom_managed_image_resource_group_name` must also be set. See + [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + to learn more about managed images. + +- `custom_managed_image_resource_group_name` (string) - Name of a custom managed image's resource group to use for your base image. If this + value is set, image_publisher, image_offer, image_sku, or image_version should not be set. + If this value is set, the option + `custom_managed_image_name` must also be set. See + [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + to learn more about managed images. + + + + +When creating a VHD the following additional options are required: + +- `capture_container_name` (string) - Destination container name. Essentially + the "directory" where your VHD will be organized in Azure. The captured + VHD's URL will be + `https://.blob.core.windows.net/system/Microsoft.Compute/Images//.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.vhd`. + +- `capture_name_prefix` (string) - VHD prefix. The final artifacts will be + named `PREFIX-osDisk.UUID` and `PREFIX-vmTemplate.UUID`. + +- `resource_group_name` (string) - Resource group under which the final + artifact will be stored. + +- `storage_account` (string) - Storage account under which the final artifact + will be stored. + +When creating a managed image the following additional options are required: + +- `managed_image_name` (string) - Specify the managed image name where the + result of the Packer build will be saved. The image name must not exist + ahead of time, and will not be overwritten. If this value is set, the value + `managed_image_resource_group_name` must also be set. See + [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + to learn more about managed images. + +- `managed_image_resource_group_name` (string) - Specify the managed image + resource group name where the result of the Packer build will be saved. The + resource group must already exist. If this value is set, the value + `managed_image_name` must also be set. See + [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + to learn more about managed images. + +Creating a managed image using a [Shared Gallery image](https://azure.microsoft.com/en-us/blog/announcing-the-public-preview-of-shared-image-gallery/) as the source can be achieved by specifying the [shared_image_gallery](#shared-image-gallery) configuration option. + +#### Resource Group Usage + +The Azure builder can either provision resources into a new resource group that +it controls (default) or an existing one. The advantage of using a packer +defined resource group is that failed resource cleanup is easier because you +can simply remove the entire resource group, however this means that the +provided credentials must have permission to create and remove resource groups. +By using an existing resource group you can scope the provided credentials to +just this group, however failed builds are more likely to leave unused +artifacts. + +To have Packer create a resource group you **must** provide: + +- `location` (string) Azure datacenter in which your VM will build. + + CLI example `az account list-locations` + +and optionally: + +- `temp_resource_group_name` (string) name assigned to the temporary resource + group created during the build. If this value is not set, a random value + will be assigned. This resource group is deleted at the end of the build. + +To use an existing resource group you **must** provide: + +- `build_resource_group_name` (string) - Specify an existing resource group + to run the build in. + +Providing `temp_resource_group_name` or `location` in combination with +`build_resource_group_name` is not allowed. + +### Optional: + + + +- `user_assigned_managed_identities` ([]string) - A list of one or more fully-qualified resource IDs of user assigned + managed identities to be configured on the VM. + See [documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token) + for how to acquire tokens within the VM. + To assign a user assigned managed identity to a VM, the provided account or service principal must have [Managed Identity Operator](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#managed-identity-operator) + and [Virtual Machine Contributor](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#virtual-machine-contributor) role assignments. + +- `capture_name_prefix` (string) - VHD prefix. + +- `capture_container_name` (string) - Destination container name. + +- `shared_image_gallery` (SharedImageGallery) - Use a [Shared Gallery + image](https://azure.microsoft.com/en-us/blog/announcing-the-public-preview-of-shared-image-gallery/) + as the source for this build. *VHD targets are incompatible with this + build type* - the target must be a *Managed Image*. When using shared_image_gallery as a source, image_publisher, + image_offer, image_sku, image_version, and custom_managed_image_name should not be set. + + In JSON + ```json + "shared_image_gallery": { + "subscription": "00000000-0000-0000-0000-00000000000", + "resource_group": "ResourceGroup", + "gallery_name": "GalleryName", + "image_name": "ImageName", + "image_version": "1.0.0", + } + "managed_image_name": "TargetImageName", + "managed_image_resource_group_name": "TargetResourceGroup" + ``` + In HCL2 + ```hcl + shared_image_gallery { + subscription = "00000000-0000-0000-0000-00000000000" + resource_group = "ResourceGroup" + gallery_name = "GalleryName" + image_name = "ImageName" + image_version = "1.0.0" + } + managed_image_name = "TargetImageName" + managed_image_resource_group_name = "TargetResourceGroup" + ``` + +- `shared_image_gallery_destination` (SharedImageGalleryDestination) - The name of the Shared Image Gallery under which the managed image will be published as Shared Gallery Image version. + + Following is an example. + + In JSON + ```json + "shared_image_gallery_destination": { + "subscription": "00000000-0000-0000-0000-00000000000", + "resource_group": "ResourceGroup", + "gallery_name": "GalleryName", + "image_name": "ImageName", + "image_version": "1.0.0", + "replication_regions": ["regionA", "regionB", "regionC"], + "storage_account_type": "Standard_LRS" + } + "managed_image_name": "TargetImageName", + "managed_image_resource_group_name": "TargetResourceGroup" + ``` + In HCL2 + ```hcl + shared_image_gallery_destination { + subscription = "00000000-0000-0000-0000-00000000000" + resource_group = "ResourceGroup" + gallery_name = "GalleryName" + image_name = "ImageName" + image_version = "1.0.0" + replication_regions = ["regionA", "regionB", "regionC"] + storage_account_type = "Standard_LRS" + } + managed_image_name = "TargetImageName" + managed_image_resource_group_name = "TargetResourceGroup" + ``` + +- `shared_image_gallery_timeout` (duration string | ex: "1h5m2s") - How long to wait for an image to be published to the shared image + gallery before timing out. If your Packer build is failing on the + Publishing to Shared Image Gallery step with the error `Original Error: + context deadline exceeded`, but the image is present when you check your + Azure dashboard, then you probably need to increase this timeout from + its default of "60m" (valid time units include `s` for seconds, `m` for + minutes, and `h` for hours.) + +- `shared_gallery_image_version_end_of_life_date` (string) - The end of life date (2006-01-02T15:04:05.99Z) of the gallery Image Version. This property + can be used for decommissioning purposes. + +- `shared_image_gallery_replica_count` (int32) - The number of replicas of the Image Version to be created per region. This + property would take effect for a region when regionalReplicaCount is not specified. + Replica count must be between 1 and 100, but 50 replicas should be sufficient for most use cases. + +- `shared_gallery_image_version_exclude_from_latest` (bool) - If set to true, Virtual Machines deployed from the latest version of the + Image Definition won't use this Image Version. + +- `image_version` (string) - Specify a specific version of an OS to boot from. + Defaults to `latest`. There may be a difference in versions available + across regions due to image synchronization latency. To ensure a consistent + version across regions set this value to one that is available in all + regions where you are deploying. + + CLI example + `az vm image list --location westus --publisher Canonical --offer UbuntuServer --sku 16.04.0-LTS --all` + +- `location` (string) - Azure datacenter in which your VM will build. + +- `vm_size` (string) - Size of the VM used for building. This can be changed when you deploy a + VM from your VHD. See + [pricing](https://azure.microsoft.com/en-us/pricing/details/virtual-machines/) + information. Defaults to `Standard_A1`. + + CLI example `az vm list-sizes --location westus` + +- `spot` (Spot) - If set use a spot instance during build; spot configuration settings only apply to the virtual machine launched by Packer and will not be persisted on the resulting image artifact. + + Following is an example. + + In JSON + + ```json + "spot": { + "eviction_policy": "Delete", + "max_price": "0.4", + } + ``` + + In HCL2 + + ```hcl + spot { + eviction_policy = "Delete" + max_price = "0.4" + } + ``` + +- `managed_image_resource_group_name` (string) - Specify the managed image resource group name where the result of the + Packer build will be saved. The resource group must already exist. If + this value is set, the value managed_image_name must also be set. See + documentation to learn more about managed images. + +- `managed_image_name` (string) - Specify the managed image name where the result of the Packer build will + be saved. The image name must not exist ahead of time, and will not be + overwritten. If this value is set, the value + managed_image_resource_group_name must also be set. See documentation to + learn more about managed images. + +- `managed_image_storage_account_type` (string) - Specify the storage account + type for a managed image. Valid values are Standard_LRS and Premium_LRS. + The default is Standard_LRS. + +- `managed_image_os_disk_snapshot_name` (string) - If + managed_image_os_disk_snapshot_name is set, a snapshot of the OS disk + is created with the same name as this value before the VM is captured. + +- `managed_image_data_disk_snapshot_prefix` (string) - If + managed_image_data_disk_snapshot_prefix is set, snapshot of the data + disk(s) is created with the same prefix as this value before the VM is + captured. + +- `keep_os_disk` (bool) - If + keep_os_disk is set, the OS disk is not deleted. + The default is false. + +- `managed_image_zone_resilient` (bool) - Store the image in zone-resilient storage. You need to create it in a + region that supports [availability + zones](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview). + +- `azure_tags` (map[string]string) - Name/value pair tags to apply to every resource deployed i.e. Resource + Group, VM, NIC, VNET, Public IP, KeyVault, etc. The user can define up + to 15 tags. Tag names cannot exceed 512 characters, and tag values + cannot exceed 256 characters. + +- `azure_tag` ([]{name string, value string}) - Same as [`azure_tags`](#azure_tags) but defined as a singular repeatable block + containing a `name` and a `value` field. In HCL2 mode the + [`dynamic_block`](/packer/docs/templates/hcl_templates/expressions#dynamic-blocks) + will allow you to create those programatically. + +- `resource_group_name` (string) - Resource group under which the final artifact will be stored. + +- `storage_account` (string) - Storage account under which the final artifact will be stored. + +- `temp_compute_name` (string) - temporary name assigned to the VM. If this + value is not set, a random value will be assigned. Knowing the resource + group and VM name allows one to execute commands to update the VM during a + Packer build, e.g. attach a resource disk to the VM. + +- `temp_nic_name` (string) - temporary name assigned to the Nic. If this + value is not set, a random value will be assigned. Being able to assign a custom + nicname could ease deployment if naming conventions are used. + +- `temp_resource_group_name` (string) - name assigned to the temporary resource group created during the build. + If this value is not set, a random value will be assigned. This resource + group is deleted at the end of the build. + +- `build_resource_group_name` (string) - Specify an existing resource group to run the build in. + +- `build_key_vault_name` (string) - Specify an existing key vault to use for uploading certificates to the + instance to connect. + +- `build_key_vault_sku` (string) - Specify the KeyVault SKU to create during the build. Valid values are + standard or premium. The default value is standard. + +- `disk_encryption_set_id` (string) - Specify the Disk Encryption Set ID to use to encrypt the OS and data disks created with the VM during the build + Only supported when publishing to Shared Image Galleries, without a managed image + The disk encryption set ID can be found in the properties tab of a disk encryption set on the Azure Portal, and is labeled as its resource ID + https://learn.microsoft.com/en-us/azure/virtual-machines/image-version-encryption + +- `private_virtual_network_with_public_ip` (bool) - This value allows you to + set a virtual_network_name and obtain a public IP. If this value is not + set and virtual_network_name is defined Packer is only allowed to be + executed from a host on the same subnet / virtual network. + +- `virtual_network_name` (string) - Use a pre-existing virtual network for the + VM. This option enables private communication with the VM, no public IP + address is used or provisioned (unless you set + private_virtual_network_with_public_ip). + +- `virtual_network_subnet_name` (string) - If virtual_network_name is set, + this value may also be set. If virtual_network_name is set, and this + value is not set the builder attempts to determine the subnet to use with + the virtual network. If the subnet cannot be found, or it cannot be + disambiguated, this value should be set. + +- `virtual_network_resource_group_name` (string) - If virtual_network_name is + set, this value may also be set. If virtual_network_name is set, and + this value is not set the builder attempts to determine the resource group + containing the virtual network. If the resource group cannot be found, or + it cannot be disambiguated, this value should be set. + +- `custom_data_file` (string) - Specify a file containing custom data to inject into the cloud-init + process. The contents of the file are read and injected into the ARM + template. The custom data will be passed to cloud-init for processing at + the time of provisioning. See + [documentation](http://cloudinit.readthedocs.io/en/latest/topics/examples.html) + to learn more about custom data, and how it can be used to influence the + provisioning process. + +- `custom_data` (string) - Specify a Base64-encode custom data to apply when launching the instance. + Note that you need to be careful about escaping characters due to the templates being JSON. + The custom data will be passed to cloud-init for processing at + the time of provisioning. See + [documentation](http://cloudinit.readthedocs.io/en/latest/topics/examples.html) + to learn more about custom data, and how it can be used to influence the + provisioning process. + +- `user_data_file` (string) - Specify a file containing user data to inject into the cloud-init + process. The contents of the file are read and injected into the ARM + template. The user data will be available from the provision until the vm is + deleted. Any application on the virtual machine can access the user data + from the Azure Instance Metadata Service (IMDS) after provision. + See [documentation](https://docs.microsoft.com/en-us/azure/virtual-machines/user-data) + to learn more about user data. + +- `user_data` (string) - Specify a Base64-encode user data to apply + Note that you need to be careful about escaping characters due to the templates being JSON. + The user data will be available from the provision until the vm is + deleted. Any application on the virtual machine can access the user data + from the Azure Instance Metadata Service (IMDS) after provision. + See [documentation](https://docs.microsoft.com/en-us/azure/virtual-machines/user-data) + to learn more about user data. + +- `custom_script` (string) - Used for running a script on VM provision during the image build + The following example executes the contents of the file specified by `user_data_file`: + ```hcl2 + custom_script = "powershell -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -Command \"$userData = (Invoke-RestMethod -Headers @{Metadata=$true} -Method GET -Uri http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01$([char]38)format=text); $contents = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)); set-content -path c:\\Windows\\Temp\\userdata.ps1 -value $contents; . c:\\Windows\\Temp\\userdata.ps1;\"" + user_data_file = "./scripts/userdata.ps1" + ``` + Specify a command to inject into the CustomScriptExtension, to run on startup + on Windows builds, before the communicator attempts to connect + See [documentation](https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-windows) + to learn more. + +- `plan_info` (PlanInformation) - Used for creating images from Marketplace images. Please refer to + [Deploy an image with Marketplace + terms](https://aka.ms/azuremarketplaceapideployment) for more details. + Not all Marketplace images support programmatic deployment, and support + is controlled by the image publisher. + + An example plan\_info object is defined below. + + ```json + { + "plan_info": { + "plan_name": "rabbitmq", + "plan_product": "rabbitmq", + "plan_publisher": "bitnami" + } + } + ``` + + `plan_name` (string) - The plan name, required. `plan_product` (string) - + The plan product, required. `plan_publisher` (string) - The plan publisher, + required. `plan_promotion_code` (string) - Some images accept a promotion + code, optional. + + Images created from the Marketplace with `plan_info` **must** specify + `plan_info` whenever the image is deployed. The builder automatically adds + tags to the image to ensure this information is not lost. The following + tags are added. + + ```text + 1. PlanName + 2. PlanProduct + 3. PlanPublisher + 4. PlanPromotionCode + ``` + +- `polling_duration_timeout` (duration string | ex: "1h5m2s") - The default PollingDuration for azure is 15mins, this property will override + that value. + If your Packer build is failing on the + ARM deployment step with the error `Original Error: + context deadline exceeded`, then you probably need to increase this timeout from + its default of "15m" (valid time units include `s` for seconds, `m` for + minutes, and `h` for hours.) + +- `os_type` (string) - If either Linux or Windows is specified Packer will + automatically configure authentication credentials for the provisioned + machine. For Linux this configures an SSH authorized key. For Windows + this configures a WinRM certificate. + +- `winrm_expiration_time` (duration string | ex: "1h5m2s") - A time duration with which to set the WinRM certificate to expire + This only works for Windows builds (valid time units include `s` for seconds, `m` for + minutes, and `h` for hours.) + +- `temp_os_disk_name` (string) - temporary name assigned to the OSDisk. If this + value is not set, a random value will be assigned. Being able to assign a custom + osDiskName could ease deployment if naming conventions are used. + +- `os_disk_size_gb` (int32) - Specify the size of the OS disk in GB + (gigabytes). Values of zero or less than zero are ignored. + +- `disk_additional_size` ([]int32) - The size(s) of any additional hard disks for the VM in gigabytes. If + this is not specified then the VM will only contain an OS disk. The + number of additional disks and maximum size of a disk depends on the + configuration of your VM. See + [Windows](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/about-disks-and-vhds) + or + [Linux](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/about-disks-and-vhds) + for more information. + + For VHD builds the final artifacts will be named + `PREFIX-dataDisk-.UUID.vhd` and stored in the specified capture + container along side the OS disk. The additional disks are included in + the deployment template `PREFIX-vmTemplate.UUID`. + + For Managed build the final artifacts are included in the managed image. + The additional disk will have the same storage account type as the OS + disk, as specified with the `managed_image_storage_account_type` + setting. + +- `disk_caching_type` (string) - Specify the disk caching type. Valid values + are None, ReadOnly, and ReadWrite. The default value is ReadWrite. + +- `allowed_inbound_ip_addresses` ([]string) - Specify the list of IP addresses and CIDR blocks that should be + allowed access to the VM. If provided, an Azure Network Security + Group will be created with corresponding rules and be bound to + the subnet of the VM. + Providing `allowed_inbound_ip_addresses` in combination with + `virtual_network_name` is not allowed. + +- `boot_diag_storage_account` (string) - Specify storage to store Boot Diagnostics -- Enabling this option + will create 2 Files in the specified storage account. (serial console log & screehshot file) + once the build is completed, it has to be removed manually. + see [here](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/boot-diagnostics) for more info + +- `custom_resource_build_prefix` (string) - specify custom azure resource names during build limited to max 10 characters + this will set the prefix for the resources. The actuall resource names will be + `custom_resource_build_prefix` + resourcetype + 5 character random alphanumeric string + +- `license_type` (string) - Specify a license type for the build VM to enable Azure Hybrid Benefit. If not set, Pay-As-You-Go license + model (default) will be used. Valid values are: + + For Windows: + - `Windows_Client` + - `Windows_Server` + + For Linux: + - `RHEL_BYOS` + - `SLES_BYOS` + + Refer to the following documentation for more information about Hybrid Benefit: + [Windows](https://learn.microsoft.com/en-us/azure/virtual-machines/windows/hybrid-use-benefit-licensing) + or + [Linux](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/azure-hybrid-benefit-linux) + +- `secure_boot_enabled` (bool) - Specifies if Secure Boot and Trusted Launch is enabled for the Virtual Machine. + +- `encryption_at_host` (bool) - Specifies if Encryption at host is enabled for the Virtual Machine. + Requires enabling encryption at host in the Subscription read more [here](https://learn.microsoft.com/en-us/azure/virtual-machines/disks-enable-host-based-encryption-portal?tabs=azure-powershell) + +- `vtpm_enabled` (bool) - Specifies if vTPM (virtual Trusted Platform Module) and Trusted Launch is enabled for the Virtual Machine. + +- `async_resourcegroup_delete` (bool) - If you want packer to delete the + temporary resource group asynchronously set this value. It's a boolean + value and defaults to false. Important Setting this true means that + your builds are faster, however any failed deletes are not reported. + + + + + + +- `cloud_environment_name` (string) - One of Public, China, or + USGovernment. Defaults to Public. Long forms such as + USGovernmentCloud and AzureUSGovernmentCloud are also supported. + +- `metadata_host` (string) - The Hostname of the Azure Metadata Service + (for example management.azure.com), used to obtain the Cloud Environment + when using a Custom Azure Environment. This can also be sourced from the + ARM_METADATA_HOST Environment Variable. + Note: CloudEnvironmentName must be set to the requested environment + name in the list of available environments held in the metadata_host. + +- `client_id` (string) - The application ID of the AAD Service Principal. + Requires either `client_secret`, `client_cert_path` or `client_jwt` to be set as well. + +- `client_secret` (string) - A password/secret registered for the AAD SP. + +- `client_cert_path` (string) - The path to a PKCS#12 bundle (.pfx file) to be used as the client certificate + that will be used to authenticate as the specified AAD SP. + +- `client_cert_password` (string) - The password for decrypting the client certificate bundle. + +- `client_jwt` (string) - A JWT bearer token for client auth (RFC 7523, Sec. 2.2) that will be used + to authenticate the AAD SP. Provides more control over token the expiration + when using certificate authentication than when using `client_cert_path`. + +- `object_id` (string) - The object ID for the AAD SP. Optional, will be derived from the oAuth token if left empty. + +- `tenant_id` (string) - The Active Directory tenant identifier with which your `client_id` and + `subscription_id` are associated. If not specified, `tenant_id` will be + looked up using `subscription_id`. + +- `subscription_id` (string) - The subscription to use. + +- `use_azure_cli_auth` (bool) - Flag to use Azure CLI authentication. Defaults to false. + CLI auth will use the information from an active `az login` session to connect to Azure and set the subscription id and tenant id associated to the signed in account. + If enabled, it will use the authentication provided by the `az` CLI. + Azure CLI authentication will use the credential marked as `isDefault` and can be verified using `az account show`. + Works with normal authentication (`az login`) and service principals (`az login --service-principal --username APP_ID --password PASSWORD --tenant TENANT_ID`). + Ignores all other configurations if enabled. + + + + + + +- `skip_create_image` (bool) - Skip creating the image. + Useful for setting to `true` during a build test stage. + Defaults to `false`. + + + + + +### Shared Image Gallery + +The shared_image_gallery block is available for building a new image from a private or [community shared imaged gallery](https://docs.microsoft.com/en-us/azure/virtual-machines/azure-compute-gallery#community-gallery-preview) owned gallery. + + + +- `subscription` (string) - Subscription + +- `resource_group` (string) - Resource Group + +- `gallery_name` (string) - Gallery Name + +- `image_name` (string) - Image Name + +- `image_version` (string) - Specify a specific version of an OS to boot from. + Defaults to latest. There may be a difference in versions available + across regions due to image synchronization latency. To ensure a consistent + version across regions set this value to one that is available in all + regions where you are deploying. + +- `community_gallery_image_id` (string) - Id of the community gallery image : /CommunityGalleries/{galleryUniqueName}/Images/{img}[/Versions/{}] (Versions part is optional) + +- `direct_shared_gallery_image_id` (string) - Id of the direct shared gallery image : /sharedGalleries/{galleryUniqueName}/Images/{img}[/Versions/{}] (Versions part is optional) + + + + + +### Shared Image Gallery Destination + +The shared_image_gallery_destination block is available for publishing a new image version to an existing shared image gallery. + + + +- `subscription` (string) - Sig Destination Subscription + +- `resource_group` (string) - Sig Destination Resource Group + +- `gallery_name` (string) - Sig Destination Gallery Name + +- `image_name` (string) - Sig Destination Image Name + +- `image_version` (string) - Sig Destination Image Version + +- `replication_regions` ([]string) - Sig Destination Replication Regions + +- `storage_account_type` (string) - Specify a storage account type for the Shared Image Gallery Image Version. + Defaults to `Standard_LRS`. Accepted values are `Standard_LRS`, `Standard_ZRS` and `Premium_LRS` + +- `specialized` (bool) - Set to true if publishing to a Specialized Gallery, this skips a call to set the build VM's OS state as Generalized + + + + + +### Spot + +The `spot` block is available to use a spot instance during build. + + + +- `eviction_policy` (virtualmachines.VirtualMachineEvictionPolicyTypes) - Specify eviction policy for spot instance: "Deallocate" or "Delete". If this is set, a spot instance will be used. + +- `max_price` (float32) - How much should the VM cost maximally per hour. Specify -1 (or do not specify) to not evict based on price. + + + + + +## Build Shared Information Variables + +This builder generates data that are shared with provisioner and post-processor via build function of [template engine](https://packer.io/docs/templates/legacy_json_templates/engine) for JSON and [contextual variables](https://packer.io/docs/templates/hcl_templates/contextual-variables) for HCL2. + +The generated variables available for this builder are: + +- `SourceImageName` - The full name of the source image used in the deployment. When using +shared images the resulting name will point to the actual source used to create the said version. + building the AMI. + +Usage example: + +**HCL2** + +```hcl +// When accessing one of these variables from inside the builder, you need to +// use the golang templating syntax. This is due to an architectural quirk that +// won't be easily resolvable until legacy json templates are deprecated: + +{ +source "azure-arm" "basic-example" { + os_type = "Linux" + image_publisher = "Canonical" + image_offer = "UbuntuServer" + image_sku = "14.04.4-LTS" +} + +// when accessing one of the variables from a provisioner or post-processor, use +// hcl-syntax +post-processor "manifest" { + output = "manifest.json" + strip_path = true + custom_data = { + source_image_name = "${build.SourceImageName}" + } +} +``` +**JSON** + +```json +"post-processors": [ + { + "type": "manifest", + "output": "manifest.json", + "strip_path": true, + "custom_data": { + "source_image_name": "{{ build `SourceImageName` }}" + } + } +] +``` + + +### Communicator Config + +In addition to the builder options, a communicator may also be defined: + + + +- `communicator` (string) - Packer currently supports three kinds of communicators: + + - `none` - No communicator will be used. If this is set, most + provisioners also can't be used. + + - `ssh` - An SSH connection will be established to the machine. This + is usually the default. + + - `winrm` - A WinRM connection will be established. + + In addition to the above, some builders have custom communicators they + can use. For example, the Docker builder has a "docker" communicator + that uses `docker exec` and `docker cp` to execute scripts and copy + files. + +- `pause_before_connecting` (duration string | ex: "1h5m2s") - We recommend that you enable SSH or WinRM as the very last step in your + guest's bootstrap script, but sometimes you may have a race condition + where you need Packer to wait before attempting to connect to your + guest. + + If you end up in this situation, you can use the template option + `pause_before_connecting`. By default, there is no pause. For example if + you set `pause_before_connecting` to `10m` Packer will check whether it + can connect, as normal. But once a connection attempt is successful, it + will disconnect and then wait 10 minutes before connecting to the guest + and beginning provisioning. + + + + + + +- `ssh_host` (string) - The address to SSH to. This usually is automatically configured by the + builder. + +- `ssh_port` (int) - The port to connect to SSH. This defaults to `22`. + +- `ssh_username` (string) - The username to connect to SSH with. Required if using SSH. + +- `ssh_password` (string) - A plaintext password to use to authenticate with SSH. + +- `ssh_ciphers` ([]string) - This overrides the value of ciphers supported by default by Golang. + The default value is [ + "aes128-gcm@openssh.com", + "chacha20-poly1305@openssh.com", + "aes128-ctr", "aes192-ctr", "aes256-ctr", + ] + + Valid options for ciphers include: + "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", + "chacha20-poly1305@openssh.com", + "arcfour256", "arcfour128", "arcfour", "aes128-cbc", "3des-cbc", + +- `ssh_clear_authorized_keys` (bool) - If true, Packer will attempt to remove its temporary key from + `~/.ssh/authorized_keys` and `/root/.ssh/authorized_keys`. This is a + mostly cosmetic option, since Packer will delete the temporary private + key from the host system regardless of whether this is set to true + (unless the user has set the `-debug` flag). Defaults to "false"; + currently only works on guests with `sed` installed. + +- `ssh_key_exchange_algorithms` ([]string) - If set, Packer will override the value of key exchange (kex) algorithms + supported by default by Golang. Acceptable values include: + "curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha1", and "diffie-hellman-group1-sha1". + +- `ssh_certificate_file` (string) - Path to user certificate used to authenticate with SSH. + The `~` can be used in path and will be expanded to the + home directory of current user. + +- `ssh_pty` (bool) - If `true`, a PTY will be requested for the SSH connection. This defaults + to `false`. + +- `ssh_timeout` (duration string | ex: "1h5m2s") - The time to wait for SSH to become available. Packer uses this to + determine when the machine has booted so this is usually quite long. + Example value: `10m`. + This defaults to `5m`, unless `ssh_handshake_attempts` is set. + +- `ssh_disable_agent_forwarding` (bool) - If true, SSH agent forwarding will be disabled. Defaults to `false`. + +- `ssh_handshake_attempts` (int) - The number of handshakes to attempt with SSH once it can connect. + This defaults to `10`, unless a `ssh_timeout` is set. + +- `ssh_bastion_host` (string) - A bastion host to use for the actual SSH connection. + +- `ssh_bastion_port` (int) - The port of the bastion host. Defaults to `22`. + +- `ssh_bastion_agent_auth` (bool) - If `true`, the local SSH agent will be used to authenticate with the + bastion host. Defaults to `false`. + +- `ssh_bastion_username` (string) - The username to connect to the bastion host. + +- `ssh_bastion_password` (string) - The password to use to authenticate with the bastion host. + +- `ssh_bastion_interactive` (bool) - If `true`, the keyboard-interactive used to authenticate with bastion host. + +- `ssh_bastion_private_key_file` (string) - Path to a PEM encoded private key file to use to authenticate with the + bastion host. The `~` can be used in path and will be expanded to the + home directory of current user. + +- `ssh_bastion_certificate_file` (string) - Path to user certificate used to authenticate with bastion host. + The `~` can be used in path and will be expanded to the + home directory of current user. + +- `ssh_file_transfer_method` (string) - `scp` or `sftp` - How to transfer files, Secure copy (default) or SSH + File Transfer Protocol. + + **NOTE**: Guests using Windows with Win32-OpenSSH v9.1.0.0p1-Beta, scp + (the default protocol for copying data) returns a a non-zero error code since the MOTW + cannot be set, which cause any file transfer to fail. As a workaround you can override the transfer protocol + with SFTP instead `ssh_file_transfer_protocol = "sftp"`. + +- `ssh_proxy_host` (string) - A SOCKS proxy host to use for SSH connection + +- `ssh_proxy_port` (int) - A port of the SOCKS proxy. Defaults to `1080`. + +- `ssh_proxy_username` (string) - The optional username to authenticate with the proxy server. + +- `ssh_proxy_password` (string) - The optional password to use to authenticate with the proxy server. + +- `ssh_keep_alive_interval` (duration string | ex: "1h5m2s") - How often to send "keep alive" messages to the server. Set to a negative + value (`-1s`) to disable. Example value: `10s`. Defaults to `5s`. + +- `ssh_read_write_timeout` (duration string | ex: "1h5m2s") - The amount of time to wait for a remote command to end. This might be + useful if, for example, packer hangs on a connection after a reboot. + Example: `5m`. Disabled by default. + +- `ssh_remote_tunnels` ([]string) - + +- `ssh_local_tunnels` ([]string) - + + + + +- `ssh_private_key_file` (string) - Path to a PEM encoded private key file to use to authenticate with SSH. + The `~` can be used in path and will be expanded to the home directory + of current user. + + +## Basic Example + +Here is a basic example for Azure. + +**HCL2** + +```hcl +source "azure-arm" "basic-example" { + client_id = "fe354398-d7sf-4dc9-87fd-c432cd8a7e09" + client_secret = "keepitsecret&#*$" + resource_group_name = "packerdemo" + storage_account = "virtualmachines" + subscription_id = "44cae533-4247-4093-42cf-897ded6e7823" + tenant_id = "de39842a-caba-497e-a798-7896aea43218" + + capture_container_name = "images" + capture_name_prefix = "packer" + + os_type = "Linux" + image_publisher = "Canonical" + image_offer = "UbuntuServer" + image_sku = "14.04.4-LTS" + + azure_tags = { + dept = "engineering" + } + + location = "West US" + vm_size = "Standard_A2" +} + +build { + sources = ["sources.azure-arm.basic-example"] +} +``` + +**JSON** + +```json +{ + "type": "azure-arm", + + "client_id": "fe354398-d7sf-4dc9-87fd-c432cd8a7e09", + "client_secret": "keepitsecret&#*$", + "resource_group_name": "packerdemo", + "storage_account": "virtualmachines", + "subscription_id": "44cae533-4247-4093-42cf-897ded6e7823", + "tenant_id": "de39842a-caba-497e-a798-7896aea43218", + + "capture_container_name": "images", + "capture_name_prefix": "packer", + + "os_type": "Linux", + "image_publisher": "Canonical", + "image_offer": "UbuntuServer", + "image_sku": "14.04.4-LTS", + + "azure_tags": { + "dept": "engineering" + }, + + "location": "West US", + "vm_size": "Standard_A2" +} +``` + + +## Deprovision + +Azure VMs should be deprovisioned at the end of every build. For Windows this +means executing sysprep, and for Linux this means executing the waagent +deprovision process. + +Please refer to the Azure +[example](https://github.com/hashicorp/packer-plugin-azure/tree/main/example) folder for +complete examples showing the deprovision process. + +### Windows + +The following provisioner snippet shows how to sysprep a Windows VM. +Deprovision should be the last operation executed by a build. The code below +will wait for sysprep to write the image status in the registry and will exit +after that. The possible states, in case you want to wait for another state, +[are documented +here](https://technet.microsoft.com/en-us/library/hh824815.aspx) + +**JSON** + +```json +{ + "provisioners": [ + { + "type": "powershell", + "inline": [ + "# If Guest Agent services are installed, make sure that they have started.", + "foreach ($service in Get-Service -Name RdAgent, WindowsAzureTelemetryService, WindowsAzureGuestAgent -ErrorAction SilentlyContinue) { while ((Get-Service $service.Name).Status -ne 'Running') { Start-Sleep -s 5 } }", + + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit /mode:vm", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + ] + } + ] +} +``` + +**HCL2** + +```hcl +provisioner "powershell" { + inline = [ + "# If Guest Agent services are installed, make sure that they have started.", + "foreach ($service in Get-Service -Name RdAgent, WindowsAzureTelemetryService, WindowsAzureGuestAgent -ErrorAction SilentlyContinue) { while ((Get-Service $service.Name).Status -ne 'Running') { Start-Sleep -s 5 } }", + + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit /mode:vm", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + ] +} +``` + + +The Windows Guest Agent participates in the Sysprep process. The agent must be +fully installed before the VM can be sysprep'ed. To ensure this is true all +agent services must be running before executing sysprep.exe. The above JSON +snippet shows one way to do this in the PowerShell provisioner. This snippet is +**only** required if the VM is configured to install the agent, which is the +default. To learn more about disabling the Windows Guest Agent please see +[Install the VM +Agent](https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/agent-windows#install-the-vm-agent). + +Please note that sysprep can get stuck in infinite loops if it is not configured +correctly -- for example, if it is waiting for a reboot that you never perform. + +### Linux + +The following provisioner snippet shows how to deprovision a Linux VM. +Deprovision should be the last operation executed by a build. + +**JSON** + +```json +{ + "provisioners": [ + { + "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", + "inline": [ + "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" + ], + "inline_shebang": "/bin/sh -x", + "type": "shell" + } + ] +} +``` + +**HCL2** + +```hcl +provisioner "shell" { + execute_command = "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'" + inline = [ + "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" + ] + inline_shebang = "/bin/sh -x" +} +``` + + +To learn more about the Linux deprovision process please see WALinuxAgent's +[README](https://github.com/Azure/WALinuxAgent/blob/master/README.md). + +#### skip_clean + +Customers have reported issues with the deprovision process where the builder +hangs. The error message is similar to the following. + + Build 'azure-arm' errored: Retryable error: Error removing temporary script at /tmp/script_9899.sh: ssh: handshake failed: EOF + +One solution is to set skip_clean to true in the provisioner. This prevents +Packer from cleaning up any helper scripts uploaded to the VM during the build. + +## Defaults + +The Azure builder attempts to pick default values that provide for a just works +experience. These values can be changed by the user to more suitable values. + +- The default user name is Packer not root as in other builders. Most distros + on Azure do not allow root to SSH to a VM hence the need for a non-root + default user. Set the ssh_username option to override the default value. +- The default VM size is Standard_A1. Set the vm_size option to override + the default value. +- The default image version is latest. Set the image_version option to + override the default value. +- By default a temporary resource group will be created and destroyed as part + of the build. If you do not have permissions to do so, use + `build_resource_group_name` to specify an existing resource group to run + the build in. + +## Implementation + +~> **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 allow you 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-`. The value `` is a +random value that is generated at every invocation of packer. The `` +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. +2. Validate and deploy a VM template. +3. Execute provision - defined by the user; typically shell commands. +4. Power off and capture the VM. +5. Delete the resource group. +6. 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. +- NIC Name: a random 15-character name prefixed with pkrni. +- Public IP Name: a random 15-character name prefixed with pkrip. +- OS Disk Name: a random 15-character name prefixed with pkros. +- Data Disk Name: a random 15-character name prefixed with pkrdd. +- Resource Group Name: a random 33-character name prefixed with + packer-Resource-Group-. +- Subnet Name: a random 15-character name prefixed with pkrsn. +- SSH Key Pair: a 2,048-bit asymmetric key pair; can be overridden by the + user. +- Virtual Network Name: a random 15-character name prefixed with pkrvn. + +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. +2. Validate and deploy a KeyVault template. +3. Validate and deploy a VM template. +4. Execute provision - defined by the user; typically shell commands. +5. Power off and capture the VM. +6. Delete the resource group. +7. 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. + +See the +[example](https://github.com/hashicorp/packer-plugin-azure/tree/main/example) +folder in the Packer project for more examples. diff --git a/.web-docs/components/builder/chroot/README.md b/.web-docs/components/builder/chroot/README.md new file mode 100644 index 00000000..719f2c78 --- /dev/null +++ b/.web-docs/components/builder/chroot/README.md @@ -0,0 +1,481 @@ +Type: `azure-chroot` +Artifact BuilderId: `azure.chroot` + +The `azure-chroot` builder is able to build Azure managed disk (MD) images. For +more information on managed disks, see [Azure Managed Disks Overview](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/managed-disks-overview). + +The difference between this builder and the `azure-arm` builder is that this +builder is able to build a managed disk image without launching a new Azure VM +for every build, but instead use an already-running Azure VM. This can +dramatically speed up image builds. It also allows for more deterministic image +content and enables some capabilities that are not possible with the +`azure-arm` builder. + +> **This is an advanced builder** If you're just getting started with Packer, +> it is recommend to start with the [azure-arm builder](https://packer.io/docs/builder/azure-arm), +> which is much easier to use. + +## How Does it Work? + +This builder works by creating a new MD from either an existing source or from +scratch and attaching it to the (already existing) Azure VM where Packer is +running. Once attached, a [chroot](https://en.wikipedia.org/wiki/Chroot) is set +up and made available to the [provisioners](https://packer.io/docs/provisioners). +After provisioning, the MD is detached, snapshotted and a MD image is created. + +Using this process, minutes can be shaved off the image creation process +because Packer does not need to launch a VM instance. + +There are some restrictions however: + +- The host system must be a similar system (generally the same OS version, + kernel versions, etc.) as the image being built. +- If the source is a managed disk, it must be made available in the same + region as the host system. +- The host system SKU has to allow for all of the specified disks to be + attached. + +## Configuration Reference + +There are many configuration options available for the builder. We'll start +with authentication parameters, then go over the Azure chroot builder specific +options. + +### Authentication options + +None of the authentication options are required, but depending on which +ones are specified a different authentication method may be used. See the +[shared Azure builders documentation](https://packer.io/docs/builder/azure) for more +information. + + + +- `cloud_environment_name` (string) - One of Public, China, or + USGovernment. Defaults to Public. Long forms such as + USGovernmentCloud and AzureUSGovernmentCloud are also supported. + +- `metadata_host` (string) - The Hostname of the Azure Metadata Service + (for example management.azure.com), used to obtain the Cloud Environment + when using a Custom Azure Environment. This can also be sourced from the + ARM_METADATA_HOST Environment Variable. + Note: CloudEnvironmentName must be set to the requested environment + name in the list of available environments held in the metadata_host. + +- `client_id` (string) - The application ID of the AAD Service Principal. + Requires either `client_secret`, `client_cert_path` or `client_jwt` to be set as well. + +- `client_secret` (string) - A password/secret registered for the AAD SP. + +- `client_cert_path` (string) - The path to a PKCS#12 bundle (.pfx file) to be used as the client certificate + that will be used to authenticate as the specified AAD SP. + +- `client_cert_password` (string) - The password for decrypting the client certificate bundle. + +- `client_jwt` (string) - A JWT bearer token for client auth (RFC 7523, Sec. 2.2) that will be used + to authenticate the AAD SP. Provides more control over token the expiration + when using certificate authentication than when using `client_cert_path`. + +- `object_id` (string) - The object ID for the AAD SP. Optional, will be derived from the oAuth token if left empty. + +- `tenant_id` (string) - The Active Directory tenant identifier with which your `client_id` and + `subscription_id` are associated. If not specified, `tenant_id` will be + looked up using `subscription_id`. + +- `subscription_id` (string) - The subscription to use. + +- `use_azure_cli_auth` (bool) - Flag to use Azure CLI authentication. Defaults to false. + CLI auth will use the information from an active `az login` session to connect to Azure and set the subscription id and tenant id associated to the signed in account. + If enabled, it will use the authentication provided by the `az` CLI. + Azure CLI authentication will use the credential marked as `isDefault` and can be verified using `az account show`. + Works with normal authentication (`az login`) and service principals (`az login --service-principal --username APP_ID --password PASSWORD --tenant TENANT_ID`). + Ignores all other configurations if enabled. + + + + +### Azure chroot builder specific options + +#### Required: + + + +- `source` (string) - One of the following can be used as a source for an image: + - a shared image version resource ID + - a managed disk resource ID + - a publisher:offer:sku:version specifier for plaform image sources. + + + + +#### Optional: + + + +- `from_scratch` (bool) - When set to `true`, starts with an empty, unpartitioned disk. Defaults to `false`. + +- `command_wrapper` (string) - How to run shell commands. This may be useful to set environment variables or perhaps run + a command with sudo or so on. This is a configuration template where the `.Command` variable + is replaced with the command to be run. Defaults to `{{.Command}}`. + +- `pre_mount_commands` ([]string) - A series of commands to execute after attaching the root volume and before mounting the chroot. + This is not required unless using `from_scratch`. If so, this should include any partitioning + and filesystem creation commands. The path to the device is provided by `{{.Device}}`. + +- `mount_options` ([]string) - Options to supply the `mount` command when mounting devices. Each option will be prefixed with + `-o` and supplied to the `mount` command ran by Packer. Because this command is ran in a shell, + user discretion is advised. See this manual page for the `mount` command for valid file system specific options. + +- `mount_partition` (string) - The partition number containing the / partition. By default this is the first partition of the volume. + +- `mount_path` (string) - The path where the volume will be mounted. This is where the chroot environment will be. This defaults + to `/mnt/packer-amazon-chroot-volumes/{{.Device}}`. This is a configuration template where the `.Device` + variable is replaced with the name of the device where the volume is attached. + +- `post_mount_commands` ([]string) - As `pre_mount_commands`, but the commands are executed after mounting the root device and before the + extra mount and copy steps. The device and mount path are provided by `{{.Device}}` and `{{.MountPath}}`. + +- `chroot_mounts` ([][]string) - This is a list of devices to mount into the chroot environment. This configuration parameter requires + some additional documentation which is in the "Chroot Mounts" section below. Please read that section + for more information on how to use this. + +- `copy_files` ([]string) - Paths to files on the running Azure instance that will be copied into the chroot environment prior to + provisioning. Defaults to `/etc/resolv.conf` so that DNS lookups work. Pass an empty list to skip copying + `/etc/resolv.conf`. You may need to do this if you're building an image that uses systemd. + +- `os_disk_size_gb` (int64) - Try to resize the OS disk to this size on the first copy. Disks can only be englarged. If not specified, + the disk will keep its original size. Required when using `from_scratch` + +- `os_disk_storage_account_type` (string) - The [storage SKU](https://docs.microsoft.com/en-us/rest/api/compute/disks/createorupdate#diskstorageaccounttypes) + to use for the OS Disk. Defaults to `Standard_LRS`. + +- `os_disk_cache_type` (string) - The [cache type](https://docs.microsoft.com/en-us/rest/api/compute/images/createorupdate#cachingtypes) + specified in the resulting image and for attaching it to the Packer VM. Defaults to `ReadOnly` + +- `data_disk_storage_account_type` (string) - The [storage SKU](https://docs.microsoft.com/en-us/rest/api/compute/disks/createorupdate#diskstorageaccounttypes) + to use for datadisks. Defaults to `Standard_LRS`. + +- `data_disk_cache_type` (string) - The [cache type](https://docs.microsoft.com/en-us/rest/api/compute/images/createorupdate#cachingtypes) + specified in the resulting image and for attaching it to the Packer VM. Defaults to `ReadOnly` + +- `image_hyperv_generation` (string) - The [Hyper-V generation type](https://docs.microsoft.com/en-us/rest/api/compute/images/createorupdate#hypervgenerationtypes) for Managed Image output. + Defaults to `V1`. + +- `temporary_os_disk_id` (string) - The id of the temporary OS disk that will be created. Will be generated if not set. + +- `temporary_os_disk_snapshot_id` (string) - The id of the temporary OS disk snapshot that will be created. Will be generated if not set. + +- `temporary_data_disk_id_prefix` (string) - The prefix for the resource ids of the temporary data disks that will be created. The disks will be suffixed with a number. Will be generated if not set. + +- `temporary_data_disk_snapshot_id` (string) - The prefix for the resource ids of the temporary data disk snapshots that will be created. The snapshots will be suffixed with a number. Will be generated if not set. + +- `skip_cleanup` (bool) - If set to `true`, leaves the temporary disks and snapshots behind in the Packer VM resource group. Defaults to `false` + +- `image_resource_id` (string) - The managed image to create using this build. + +- `shared_image_destination` (SharedImageGalleryDestination) - The shared image to create using this build. + + + + + + +- `skip_create_image` (bool) - Skip creating the image. + Useful for setting to `true` during a build test stage. + Defaults to `false`. + + + + +#### Output options: + +At least one of these options needs to be specified: + +- `image_resource_id` (string) - The managed image to create using this build. + +- `shared_image_destination` (object) - The shared image to create using this build. + +Where `shared_image_destination` is an object with the following properties: + + + +- `resource_group` (string) - Resource Group + +- `gallery_name` (string) - Gallery Name + +- `image_name` (string) - Image Name + +- `image_version` (string) - Image Version + + + + + + +- `target_regions` ([]TargetRegion) - Target Regions + +- `exclude_from_latest` (bool) - Exclude From Latest + + + + +And `target_regions` is an array of objects with the following properties: + + + +- `name` (string) - Name of the Azure region + + + + + + +- `replicas` (int64) - Number of replicas in this region. Default: 1 + +- `storage_account_type` (string) - Storage account type: Standard_LRS or Standard_ZRS. Default: Standard_ZRS + + + + +## Chroot Mounts + +The `chroot_mounts` configuration can be used to mount specific devices within +the chroot. By default, the following additional mounts are added into the +chroot by Packer: + +- `/proc` (proc) +- `/sys` (sysfs) +- `/dev` (bind to real `/dev`) +- `/dev/pts` (devpts) +- `/proc/sys/fs/binfmt_misc` (binfmt_misc) + +These default mounts are usually good enough for anyone and are sane defaults. +However, if you want to change or add the mount points, you may using the +`chroot_mounts` configuration. Here is an example configuration which only +mounts `/prod` and `/dev`: + +```json +{ + "chroot_mounts": [ + ["proc", "proc", "/proc"], + ["bind", "/dev", "/dev"] + ] +} +``` + +`chroot_mounts` is a list of a 3-tuples of strings. The three components of the +3-tuple, in order, are: + +- The filesystem type. If this is "bind", then Packer will properly bind the + filesystem to another mount point. + +- The source device. + +- The mount directory. + +## Additional template function + +Because this builder runs on an Azure VM, there is an additional template function +available called `vm`, which returns the following VM metadata: + +- name +- subscription_id +- resource_group +- location +- resource_id + +This function can be used in the configuration templates, for example, use + +```text +"{{ vm `subscription_id` }}" +``` + +to fill in the subscription ID of the VM in any of the configuration options. + +## Build Shared Information Variables + +This builder generates data that are shared with provisioner and post-processor via build function of [template engine](https://packer.io/docs/templates/legacy_json_templates/engine) for JSON and [contextual variables](https://packer.io/docs/templates/hcl_templates/contextual-variables) for HCL2. + +The generated variables available for this builder are: + +- `SourceImageName` - The full name of the source image used in the deployment. When using +shared images the resulting name will point to the actual source used to create the said version. + building the AMI. + +Usage example: + +**HCL2** + +```hcl +// When accessing one of these variables from inside the builder, you need to +// use the golang templating syntax. This is due to an architectural quirk that +// won't be easily resolvable until legacy json templates are deprecated: + +{ +source "amazon-arm" "basic-example" { + source = "credativ:Debian:9:latest" +} + +// when accessing one of the variables from a provisioner or post-processor, use +// hcl-syntax +post-processor "manifest" { + output = "manifest.json" + strip_path = true + custom_data = { + source_image_name = "${build.SourceImageName}" + } +} +``` +**JSON** + +```json +"post-processors": [ + { + "type": "manifest", + "output": "manifest.json", + "strip_path": true, + "custom_data": { + "source_image_name": "{{ build `SourceImageName` }}" + } + } +] +``` + + + +## Examples + +Here are some examples using this builder. +This builder requires privileged actions, such as mounting disks, running +`chroot` and other admin commands. Usually it needs to be run with root +permissions, for example: + +```shell-session +$ sudo -E packer build example.pkr.json +``` + +### Using a VM with a Managed Identity + +On a VM with a system-assigned managed identity that has the contributor role +on its own resource group, the following config can be used to create an +updated Debian image: + + +**HCL2** + +```hcl +source "azure-chroot" "example" { + image_resource_id = "/subscriptions/{{vm `subscription_id`}}/resourceGroups/{{vm `resource_group`}}/providers/Microsoft.Compute/images/MyDebianOSImage-{{timestamp}}" + source = "credativ:Debian:9:latest" +} + +build { + sources = ["source.azure-chroot.example"] + + provisioner "shell" { + inline = ["apt-get update", "apt-get upgrade -y"] + inline_shebang = "/bin/sh -x" + } +} +``` + + +**JSON** + +```json +{ + "builders": [ + { + "type": "azure-chroot", + + "image_resource_id": "/subscriptions/{{vm `subscription_id`}}/resourceGroups/{{vm `resource_group`}}/providers/Microsoft.Compute/images/MyDebianOSImage-{{timestamp}}", + "source": "credativ:Debian:9:latest" + } + ], + "provisioners": [ + { + "inline": ["apt-get update", "apt-get upgrade -y"], + "inline_shebang": "/bin/sh -x", + "type": "shell" + } + ] +} +``` + + +### Using a Service Principal + +Here is an example that creates a Debian image with updated packages. Specify +all environment variables (`ARM_CLIENT_ID`, `ARM_CLIENT_SECRET`, +`ARM_SUBSCRIPTION_ID`) to use a service principal. +The identity you choose should have permission to create disks and images and also +to update your VM. +Set the `ARM_IMAGE_RESOURCEGROUP_ID` variable to an existing resource group in the +subscription where the resulting image will be created. + +**HCL2** + +```hcl +variable "client_id" { + type = string +} +variable "client_secret" { + type = string +} +variable "subscription_id" { + type = string +} variable "resource_group" { + type = string +} + +source "azure-chroot" "basic-example" { + client_id = var.client_id + client_secret = var.client_secret + subscription_id = var.subscription_id + + image_resource_id = "/subscriptions/${var.subscription_id}/resourceGroups/${var.resource_group}/providers/Microsoft.Compute/images/MyDebianOSImage-{{timestamp}}" + + source = "credativ:Debian:9:latest" +} + +build { + sources = ["sources.azure-chroot.basic-example"] + + provisioner "shell" { + inline = ["apt-get update", "apt-get upgrade -y"] + inline_shebang = "/bin/sh -x" + } +} +``` + +**JSON** + +```json +{ + "variables": { + "client_id": "{{env `ARM_CLIENT_ID`}}", + "client_secret": "{{env `ARM_CLIENT_SECRET`}}", + "subscription_id": "{{env `ARM_SUBSCRIPTION_ID`}}", + "resource_group": "{{env `ARM_IMAGE_RESOURCEGROUP_ID`}}" + }, + "builders": [ + { + "type": "azure-chroot", + + "client_id": "{{user `client_id`}}", + "client_secret": "{{user `client_secret`}}", + "subscription_id": "{{user `subscription_id`}}", + + "image_resource_id": "/subscriptions/{{user `subscription_id`}}/resourceGroups/{{user `resource_group`}}/providers/Microsoft.Compute/images/MyDebianOSImage-{{timestamp}}", + + "source": "credativ:Debian:9:latest" + } + ], + "provisioners": [ + { + "inline": ["apt-get update", "apt-get upgrade -y"], + "inline_shebang": "/bin/sh -x", + "type": "shell" + } + ] +} +``` diff --git a/.web-docs/components/builder/dtl/README.md b/.web-docs/components/builder/dtl/README.md new file mode 100644 index 00000000..f6d08261 --- /dev/null +++ b/.web-docs/components/builder/dtl/README.md @@ -0,0 +1,274 @@ +Type: `azure-dtl` +Artifact BuilderId: `Azure.ResourceManagement.VMImage` + +The Azure DevTest Labs builder builds custom images and uploads them to an existing DevTest Lab image repository automatically. +For more information on crating an Azure DevTest Lab see the [Configuring a Lab How-to guide](https://docs.microsoft.com/en-us/azure/devtest-labs/devtest-lab-create-lab). + +## Configuration Reference + +There are many configuration options available for the builder. We'll start +with authentication parameters, then go over the Azure ARM builder specific +options. In addition to the options listed here, a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can be configured for this builder. + +## Azure DevTest Labs builder specific options + +### Required: + + + +- `managed_image_resource_group_name` (string) - Specify the managed image resource group name where the result of the + Packer build will be saved. The resource group must already exist. If + this value is set, the value managed_image_name must also be set. See + documentation to learn more about managed images. + +- `managed_image_name` (string) - Specify the managed image name where the result of the Packer build will + be saved. The image name must not exist ahead of time, and will not be + overwritten. If this value is set, the value + managed_image_resource_group_name must also be set. See documentation to + learn more about managed images. + +- `lab_name` (string) - Name of the existing lab where the virtual machine will be created. + +- `lab_subnet_name` (string) - Name of the subnet being used in the lab, if not the default. + +- `lab_resource_group_name` (string) - Name of the resource group where the lab exist. + + + + +### Optional: + + + +- `capture_name_prefix` (string) - Capture + +- `capture_container_name` (string) - Capture Container Name + +- `shared_image_gallery` (SharedImageGallery) - Use a [Shared Gallery + image](https://azure.microsoft.com/en-us/blog/announcing-the-public-preview-of-shared-image-gallery/) + as the source for this build. *VHD targets are incompatible with this + build type* - the target must be a *Managed Image*. + +- `shared_image_gallery_destination` (SharedImageGalleryDestination) - The name of the Shared Image Gallery under which the managed image will be published as Shared Gallery Image version. + + Following is an example. + +- `shared_image_gallery_timeout` (duration string | ex: "1h5m2s") - How long to wait for an image to be published to the shared image + gallery before timing out. If your Packer build is failing on the + Publishing to Shared Image Gallery step with the error `Original Error: + context deadline exceeded`, but the image is present when you check your + Azure dashboard, then you probably need to increase this timeout from + its default of "60m" (valid time units include `s` for seconds, `m` for + minutes, and `h` for hours.) + +- `custom_image_capture_timeout` (duration string | ex: "1h5m2s") - How long to wait for an image to be captured before timing out + If your Packer build is failing on the Capture Image step with the + error `Original Error: context deadline exceeded`, but the image is + present when you check your custom image repository, then you probably + need to increase this timeout from its default of "30m" (valid time units + include `s` for seconds, `m` for minutes, and `h` for hours.) + +- `image_publisher` (string) - PublisherName for your base image. See + [documentation](https://docs.microsoft.com/en-us/cli/azure/vm/image) + for details. + + CLI example `az vm image list-publishers --location westus` + +- `image_offer` (string) - Offer for your base image. See + [documentation](https://docs.microsoft.com/en-us/cli/azure/vm/image) + for details. + + CLI example + `az vm image list-offers --location westus --publisher Canonical` + +- `image_sku` (string) - SKU for your base image. See + [documentation](https://docs.microsoft.com/en-us/cli/azure/vm/image) + for details. + + CLI example + `az vm image list-skus --location westus --publisher Canonical --offer UbuntuServer` + +- `image_version` (string) - Specify a specific version of an OS to boot from. + Defaults to `latest`. There may be a difference in versions available + across regions due to image synchronization latency. To ensure a consistent + version across regions set this value to one that is available in all + regions where you are deploying. + + CLI example + `az vm image list --location westus --publisher Canonical --offer UbuntuServer --sku 16.04.0-LTS --all` + +- `image_url` (string) - Specify a custom VHD to use. If this value is set, do + not set image_publisher, image_offer, image_sku, or image_version. + +- `custom_managed_image_resource_group_name` (string) - Specify the source managed image's resource group used to use. If this + value is set, do not set image\_publisher, image\_offer, image\_sku, or + image\_version. If this value is set, the value + `custom_managed_image_name` must also be set. See + [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + to learn more about managed images. + +- `custom_managed_image_name` (string) - Specify the source managed image's name to use. If this value is set, do + not set image\_publisher, image\_offer, image\_sku, or image\_version. + If this value is set, the value + `custom_managed_image_resource_group_name` must also be set. See + [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + to learn more about managed images. + +- `location` (string) - Location + +- `vm_size` (string) - Size of the VM used for building. This can be changed when you deploy a + VM from your VHD. See + [pricing](https://azure.microsoft.com/en-us/pricing/details/virtual-machines/) + information. Defaults to `Standard_A1`. + + CLI example `az vm list-sizes --location westus` + +- `managed_image_storage_account_type` (string) - Specify the storage account + type for a managed image. Valid values are Standard_LRS and Premium_LRS. + The default is Standard_LRS. + +- `azure_tags` (map[string]string) - the user can define up to 15 + tags. Tag names cannot exceed 512 characters, and tag values cannot exceed + 256 characters. Tags are applied to every resource deployed by a Packer + build, i.e. Resource Group, VM, NIC, VNET, Public IP, KeyVault, etc. + +- `plan_id` (string) - Used for creating images from Marketplace images. Please refer to + [Deploy an image with Marketplace + terms](https://aka.ms/azuremarketplaceapideployment) for more details. + Not all Marketplace images support programmatic deployment, and support + is controlled by the image publisher. + Plan_id is a string with unique identifier for the plan associated with images. + Ex plan_id="1-12ab" + +- `polling_duration_timeout` (duration string | ex: "1h5m2s") - The default PollingDuration for azure is 15mins, this property will override + that value. + If your Packer build is failing on the + ARM deployment step with the error `Original Error: + context deadline exceeded`, then you probably need to increase this timeout from + its default of "15m" (valid time units include `s` for seconds, `m` for + minutes, and `h` for hours.) + +- `os_type` (string) - If either Linux or Windows is specified Packer will + automatically configure authentication credentials for the provisioned + machine. For Linux this configures an SSH authorized key. For Windows + this configures a WinRM certificate. + +- `os_disk_size_gb` (int32) - Specify the size of the OS disk in GB + (gigabytes). Values of zero or less than zero are ignored. + +- `disk_additional_size` ([]int32) - For Managed build the final artifacts are included in the managed image. + The additional disk will have the same storage account type as the OS + disk, as specified with the `managed_image_storage_account_type` + setting. + +- `disk_caching_type` (string) - Specify the disk caching type. Valid values + are None, ReadOnly, and ReadWrite. The default value is ReadWrite. + +- `storage_type` (string) - DTL values + +- `lab_virtual_network_name` (string) - Name of the virtual network used for communicating with the lab vms. + +- `dtl_artifacts` ([]DtlArtifact) - One or more Artifacts that should be added to the VM at start. + +- `vm_name` (string) - Name for the virtual machine within the DevTest lab. + +- `disallow_public_ip` (bool) - DisallowPublicIPAddress - Indicates whether the virtual machine is to be created without a public IP address. + +- `skip_sysprep` (bool) - SkipSysprep - Indicates whether SysPrep is to be requested to the DTL or if it should be skipped because it has already been applied. Defaults to false. + + + + + + +- `skip_create_image` (bool) - Skip creating the image. + Useful for setting to `true` during a build test stage. + Defaults to `false`. + + + + +#### DtlArtifact + + +- `artifact_name` (string) - Artifact Name + +- `artifact_id` (string) - Artifact Id + +- `parameters` ([]ArtifactParameter) - Parameters + + + + +#### ArtifactParmater + + +- `name` (string) - Name + +- `value` (string) - Value + +- `type` (string) - Type + + + + + +## Basic Example + +```hcl + +variable "client_id" { + type = string + default = "${env("ARM_CLIENT_ID")}" +} + +variable "client_secret" { + type = string + default = "${env("ARM_CLIENT_SECRET")}" +} + +variable "subscription_id" { + type = string + default = "${env("ARM_SUBSCRIPTION_ID")}" +} + +locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } + +source "azure-dtl" "example" { + subscription_id = "${var.subscription_id}" + client_id = "${var.client_id}" + client_secret = "${var.client_secret}" + disallow_public_ip = true + dtl_artifacts { + artifact_name = "linux-apt-package" + parameters { + name = "packages" + value = "vim" + } + parameters { + name = "update" + value = "true" + } + parameters { + name = "options" + value = "--fix-broken" + } + } + image_offer = "UbuntuServer" + image_publisher = "Canonical" + image_sku = "16.04-LTS" + lab_name = "packer-test" + lab_resource_group_name = "packer-test" + lab_virtual_network_name = "dtlpacker-test" + location = "South Central US" + managed_image_name = "ManagedDiskLinux-${local.timestamp}" + managed_image_resource_group_name = "packer-test" + os_type = "Linux" + vm_size = "Standard_DS2_v2" +} + +build { + sources = ["source.azure-dtl.example"] + +} +``` diff --git a/.web-docs/components/provisioner/dtlartifact/README.md b/.web-docs/components/provisioner/dtlartifact/README.md new file mode 100644 index 00000000..661b3d92 --- /dev/null +++ b/.web-docs/components/provisioner/dtlartifact/README.md @@ -0,0 +1,94 @@ +Type: `azure-dtlartifact` + +The Azure DevTest Labs provisioner can be used to apply an artifact to a VM - See [Add an artifact to a VM](https://docs.microsoft.com/en-us/azure/devtest-labs/add-artifact-vm) + +## Azure DevTest Labs provisioner specific options + +### Required: + + + +- `dtl_artifacts` ([]DtlArtifact) - Dtl Artifacts + +- `lab_name` (string) - Name of the existing lab where the virtual machine exist. + +- `lab_resource_group_name` (string) - Name of the resource group where the lab exist. + +- `vm_name` (string) - Name of the virtual machine within the DevTest lab. + + + + +### Optional: + + + +- `polling_duration_timeout` (duration string | ex: "1h5m2s") - The default PollingDuration for azure is 15mins, this property will override + that value. + If your Packer build is failing on the + ARM deployment step with the error `Original Error: + context deadline exceeded`, then you probably need to increase this timeout from + its default of "15m" (valid time units include `s` for seconds, `m` for + minutes, and `h` for hours.) + +- `azure_tags` (map[string]\*string) - Azure Tags + + + + +#### DtlArtifact + + +- `artifact_name` (string) - Artifact Name + +- `artifact_id` (string) - Artifact Id + +- `parameters` ([]ArtifactParameter) - Parameters + + + + +#### ArtifactParmater + + +- `name` (string) - Name + +- `value` (string) - Value + +- `type` (string) - Type + + + + +## Basic Example + +```hcl +source "null" "example" { + communicator = "none" +} + +build { + sources = ["source.null.example"] + + provisioner "azure-dtlartifact" { + lab_name = "packer-test" + lab_resource_group_name = "packer-test" + vm_name = "packer-test-vm" + dtl_artifacts { + artifact_name = "linux-apt-package" + parameters { + name = "packages" + value = "vim" + } + parameters { + name = "update" + value = "true" + } + parameters { + name = "options" + value = "--fix-broken" + } + } + } +} +``` diff --git a/.web-docs/metadata.hcl b/.web-docs/metadata.hcl new file mode 100644 index 00000000..7ba6db59 --- /dev/null +++ b/.web-docs/metadata.hcl @@ -0,0 +1,31 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# For full specification on the configuration of this file visit: +# https://github.com/hashicorp/integration-template#metadata-configuration +integration { + name = "Azure" + description = "Packer can create Azure virtual machine images through variety of ways depending on the strategy that you want to use for building the images." + identifier = "packer/hashicorp/azure" + flags = ["hcp-ready"] + component { + type = "builder" + name = "ARM" + slug = "arm" + } + component { + type = "builder" + name = "chroot" + slug = "chroot" + } + component { + type = "builder" + name = "DTL" + slug = "dtl" + } + component { + type = "provisioner" + name = "DTL Artifact" + slug = "dtlartifact" + } +} diff --git a/.web-docs/scripts/compile-to-webdocs.sh b/.web-docs/scripts/compile-to-webdocs.sh new file mode 100755 index 00000000..2fc710b8 --- /dev/null +++ b/.web-docs/scripts/compile-to-webdocs.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + + +# Converts the folder name that the component documentation file +# is stored in into the integration slug of the component. +componentTypeFromFolderName() { + if [[ "$1" = "builders" ]]; then + echo "builder" + elif [[ "$1" = "provisioners" ]]; then + echo "provisioner" + elif [[ "$1" = "post-processors" ]]; then + echo "post-processor" + elif [[ "$1" = "datasources" ]]; then + echo "data-source" + else + echo "" + fi +} + +# $1: The content to adjust links +# $2: The organization of the integration +rewriteLinks() { + local result="$1" + local organization="$2" + + urlSegment="([^/]+)" + urlAnchor="(#[^/]+)" + + # Rewrite Component Index Page links to the Integration root page. + # + # (\1) (\2) (\3) + # /packer/plugins/datasources/amazon#anchor-tag--> + # /packer/integrations/hashicorp/amazon#anchor-tag + local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment$urlAnchor?\)" + local replace="\(\/packer\/integrations\/$organization\/\2\3\)" + result="$(echo "$result" | sed -E "s/$find/$replace/g")" + + + # Rewrite Component links to the Integration component page + # + # (\1) (\2) (\3) (\4) + # /packer/plugins/datasources/amazon/parameterstore#anchor-tag --> + # /packer/integrations/{organization}/amazon/latest/components/datasources/parameterstore + local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment\/$urlSegment$urlAnchor?\)" + local replace="\(\/packer\/integrations\/$organization\/\2\/latest\/components\/\1\/\3\4\)" + result="$(echo "$result" | sed -E "s/$find/$replace/g")" + + # Rewrite the Component URL segment from the Packer Plugin format + # to the Integrations format + result="$(echo "$result" \ + | sed "s/\/datasources\//\/data-source\//g" \ + | sed "s/\/builders\//\/builder\//g" \ + | sed "s/\/post-processors\//\/post-processor\//g" \ + | sed "s/\/provisioners\//\/provisioner\//g" \ + )" + + echo "$result" +} + +# $1: Docs Dir +# $2: Web Docs Dir +# $3: Component File +# $4: The org of the integration +processComponentFile() { + local docsDir="$1" + local webDocsDir="$2" + local componentFile="$3" + + local escapedDocsDir="$(echo "$docsDir" | sed 's/\//\\\//g' | sed 's/\./\\\./g')" + local componentTypeAndSlug="$(echo "$componentFile" | sed "s/$escapedDocsDir\///g" | sed 's/\.mdx//g')" + + # Parse out the Component Slug & Component Type + local componentSlug="$(echo "$componentTypeAndSlug" | cut -d'/' -f 2)" + local componentType="$(componentTypeFromFolderName "$(echo "$componentTypeAndSlug" | cut -d'/' -f 1)")" + if [[ "$componentType" = "" ]]; then + echo "Failed to process '$componentFile', unexpected folder name." + echo "Documentation for components must be stored in one of:" + echo "builders, provisioners, post-processors, datasources" + exit 1 + fi + + + # Calculate the location of where this file will ultimately go + local webDocsFolder="$webDocsDir/components/$componentType/$componentSlug" + mkdir -p "$webDocsFolder" + local webDocsFile="$webDocsFolder/README.md" + local webDocsFileTmp="$webDocsFolder/README.md.tmp" + + # Copy over the file to its webDocsFile location + cp "$componentFile" "$webDocsFile" + + # Remove the Header + local lastMetadataLine="$(grep -n -m 2 '^\-\-\-' "$componentFile" | tail -n1 | cut -d':' -f1)" + cat "$webDocsFile" | tail -n +"$(($lastMetadataLine+2))" > "$webDocsFileTmp" + mv "$webDocsFileTmp" "$webDocsFile" + + # Remove the top H1, as this will be added automatically on the web + cat "$webDocsFile" | tail -n +3 > "$webDocsFileTmp" + mv "$webDocsFileTmp" "$webDocsFile" + + # Rewrite Links + rewriteLinks "$(cat "$webDocsFile")" "$4" > "$webDocsFileTmp" + mv "$webDocsFileTmp" "$webDocsFile" +} + +# Compiles the Packer SDC compiled docs folder down +# to a integrations-compliant folder (web docs) +# +# $1: The directory of the plugin +# $2: The directory of the SDC compiled docs files +# $3: The output directory to place the web-docs files +# $4: The org of the integration +compileWebDocs() { + local docsDir="$1/$2" + local webDocsDir="$1/$3" + + echo "Compiling MDX docs in '$2' to Markdown in '$3'..." + # Create the web-docs directory if it hasn't already been created + mkdir -p "$webDocsDir" + + # Copy the README over + cp "$docsDir/README.md" "$webDocsDir/README.md" + + # Process all MDX component files (exclude index files, which are unsupported) + for file in $(find "$docsDir" | grep "$docsDir/.*/.*\.mdx" | grep --invert-match "index.mdx"); do + processComponentFile "$docsDir" "$webDocsDir" "$file" "$4" + done +} + +compileWebDocs "$1" "$2" "$3" "$4" diff --git a/GNUmakefile b/GNUmakefile index f3aaa0ca..f56a8c4b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -35,3 +35,8 @@ generate: install-packer-sdc packer-sdc renderdocs -src ./docs -dst ./.docs -partials ./docs-partials # checkout the .docs folder for a preview of the docs +build-docs: install-packer-sdc + @if [ -d ".docs" ]; then rm -r ".docs"; fi + @packer-sdc renderdocs -src "docs" -partials docs-partials/ -dst ".docs/" + @./.web-docs/scripts/compile-to-webdocs.sh "." ".docs" ".web-docs" "hashicorp" + @rm -r ".docs" diff --git a/docs/README.md b/docs/README.md index f721b9a0..62efdfd9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,69 +1,89 @@ -# Azure Plugins - +The Azure plugin can be used with HashiCorp Packer to create custom images on Azure. +To do so, the plugin exposes multiple builders, among which you can choose the one most adapted to your workflow. ## Installation -### Using pre-built releases - -#### Using the `packer init` command - -Starting from version 1.7, Packer supports a new `packer init` command allowing -automatic installation of Packer plugins. Read the -[Packer documentation](https://www.packer.io/docs/commands/init) for more information. - -To install this plugin, copy and paste this code into your Packer configuration . -Then, run [`packer init`](https://www.packer.io/docs/commands/init). +To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init). ```hcl packer { required_plugins { azure = { - version = ">= 1.4.2" source = "github.com/hashicorp/azure" + version = "~> 2" } } } ``` -#### Manual installation - -You can find pre-built binary releases of the plugin [here](https://github.com/hashicorp/packer-plugin-azure/releases). -Once you have downloaded the latest archive corresponding to your target OS, -uncompress it to retrieve the plugin binary file corresponding to your platform. -To install the plugin, please follow the Packer documentation on -[installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins). - - -#### From Source - -If you prefer to build the plugin from its source code, clone the GitHub -repository locally and run the command `go build` from the root -directory. Upon successful compilation, a `packer-plugin-azure` plugin -binary file can be found in the root directory. -To install the compiled plugin, please follow the official Packer documentation -on [installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins). +Alternatively, you can use `packer plugins install` to manage installation of this plugin. +```sh +$ packer plugins install github.com/hashicorp/azure +``` -## Plugin Contents +## Components Packer can create Azure virtual machine images through variety of ways depending on the strategy that you want to use for building the images. ### Builders -- [azure-arm](builders/arm.mdx) - The Azure ARM builder supports building Virtual Hard Disks (VHDs) and +- [azure-arm](/packer/integrations/hashicorp/azure/latest/components/builder/arm) - The Azure ARM builder supports building Virtual Hard Disks (VHDs) and Managed Images in Azure Resource Manager. -- [azure-chroot](builders/chroot.mdx) - The Azure chroot builder supports building a managed disk image without +- [azure-chroot](/packer/integrations/hashicorp/azure/latest/components/builder/chroot) - The Azure chroot builder supports building a managed disk image without launching a new Azure VM for every build, but instead use an already-running Azure VM. -- [azure-dtl](builders/dtl.mdx) - The Azure DevTest Labs builder builds custom images and uploads them to DevTest Lab image repository automatically. +- [azure-dtl](/packer/integrations/hashicorp/azure/latest/components/builder/dtl) - The Azure DevTest Labs builder builds custom images and uploads them to DevTest Lab image repository automatically. ### Provisioners -- [azure-dtlartifact](provisioners/dtlartifact.mdx) - The Azure DevTest Labs provisioner can be used to apply an artifact to a VM - See [Add an artifact to a VM](https://docs.microsoft.com/en-us/azure/devtest-labs/add-artifact-vm) +- [azure-dtlartifact](/packer/integrations/hashicorp/azure/latest/components/provisioner/dtlartifact) - The Azure DevTest Labs provisioner can be used to apply an artifact to a VM - Refer to [Add an artifact to a VM](https://docs.microsoft.com/en-us/azure/devtest-labs/add-artifact-vm) + +## Authentication + +@include 'builder/azure/common/client/Config.mdx' + +### Managed Identity + +If you're running Packer on an Azure VM with a [managed +identity](https://packer.io/docs/builders/azure#azure-managed-identity) you +don't need to specify any additional configuration options. As Packer will +attempt to use the Managed Identity and subscription of the VM that Packer is +running on. + +You can use a different subscription if you set `subscription_id`. If your VM +has multiple user assigned managed identities you will need to set `client_id` +too. + +### Interactive User Authentication + +To use interactive user authentication, you should specify +`use_interactive_auth` only. Packer will use cached credentials or redirect you +to a website to log in. + +### Service Principal + +To use a [service principal](https://packer.io/docs/builders/azure#azure-active-directory-service-principal) +you should specify `subscription_id`, `client_id` and one of `client_secret`, +`client_cert_path` or `client_jwt`. + +- `subscription_id` (string) - Subscription under which the build will be + performed. **The service principal specified in `client_id` must have full + access to this subscription, unless build_resource_group_name option is + specified in which case it needs to have owner access to the existing + resource group specified in build_resource_group_name parameter.** + +- `client_id` (string) - The Active Directory service principal associated with + your builder. + +- `client_secret` (string) - The password or secret for your service principal. + +- `client_cert_path` (string) - The location of a PEM file containing a + certificate and private key for service principal. + +- `client_cert_token_timeout` (duration string | ex: "1h30m12s") - How long to set the expire time on the token created when using + `client_cert_path`. +- `client_jwt` (string) - The bearer JWT assertion signed using a certificate + associated with your service principal principal. See [Azure Active + Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) + for more information. diff --git a/docs/builders/arm.mdx b/docs/builders/arm.mdx index 9437dddc..5ded7a1d 100644 --- a/docs/builders/arm.mdx +++ b/docs/builders/arm.mdx @@ -28,50 +28,6 @@ There are many configuration options available for the builder. We'll start with authentication parameters, then go over the Azure ARM builder specific options. In addition to the options listed here, a [communicator](https://packer.io/docs/templates/legacy_json_templates/communicator) can be configured for this builder. -### Authentication options - -@include 'builder/azure/common/client/Config.mdx' - -#### Managed Identity - -If you're running Packer on an Azure VM with a [managed -identity](https://packer.io/docs/builders/azure#azure-managed-identity) you -don't need to specify any additional configuration options. As Packer will -attempt to use the Managed Identity and subscription of the VM that Packer is -running on. - -You can use a different subscription if you set `subscription_id`. If your VM -has multiple user assigned managed identities you will need to set `client_id` -too. - -#### Service Principal - -To use a [service principal](https://packer.io/docs/builders/azure#azure-active-directory-service-principal) -you should specify `subscription_id`, `client_id` and one of `client_secret`, -`client_cert_path` or `client_jwt`. - -- `subscription_id` (string) - Subscription under which the build will be - performed. **The service principal specified in `client_id` must have full - access to this subscription, unless build_resource_group_name option is - specified in which case it needs to have owner access to the existing - resource group specified in build_resource_group_name parameter.** - -- `client_id` (string) - The Active Directory service principal associated with - your builder. - -- `client_secret` (string) - The password or secret for your service principal. - -- `client_cert_path` (string) - The location of a PEM file containing a - certificate and private key for service principal. - -- `client_cert_token_timeout` (duration string | ex: "1h30m12s") - How long to set the expire time on the token created when using - `client_cert_path`. - -- `client_jwt` (string) - The bearer JWT assertion signed using a certificate - associated with your service principal principal. See [Azure Active - Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) - for more information. - ### Azure ARM builder specific options The Azure builder can create either a VHD, managed image or create a Shared Image Gallery. @@ -191,8 +147,7 @@ shared images the resulting name will point to the actual source used to create Usage example: - - +**HCL2** ```hcl // When accessing one of these variables from inside the builder, you need to @@ -217,8 +172,7 @@ post-processor "manifest" { } } ``` - - +**JSON** ```json "post-processors": [ @@ -233,8 +187,6 @@ post-processor "manifest" { ] ``` - - ### Communicator Config @@ -250,8 +202,7 @@ In addition to the builder options, a communicator may also be defined: Here is a basic example for Azure. - - +**HCL2** ```hcl source "azure-arm" "basic-example" { @@ -283,8 +234,7 @@ build { } ``` - - +**JSON** ```json { @@ -314,8 +264,6 @@ build { } ``` - - ## Deprovision @@ -336,8 +284,7 @@ after that. The possible states, in case you want to wait for another state, [are documented here](https://technet.microsoft.com/en-us/library/hh824815.aspx) - - +**JSON** ```json { @@ -356,8 +303,7 @@ here](https://technet.microsoft.com/en-us/library/hh824815.aspx) } ``` - - +**HCL2** ```hcl provisioner "powershell" { @@ -371,8 +317,6 @@ provisioner "powershell" { } ``` - - The Windows Guest Agent participates in the Sysprep process. The agent must be fully installed before the VM can be sysprep'ed. To ensure this is true all @@ -391,8 +335,7 @@ correctly -- for example, if it is waiting for a reboot that you never perform. The following provisioner snippet shows how to deprovision a Linux VM. Deprovision should be the last operation executed by a build. - - +**JSON** ```json { @@ -409,8 +352,7 @@ Deprovision should be the last operation executed by a build. } ``` - - +**HCL2** ```hcl provisioner "shell" { @@ -422,8 +364,6 @@ provisioner "shell" { } ``` - - To learn more about the Linux deprovision process please see WALinuxAgent's [README](https://github.com/Azure/WALinuxAgent/blob/master/README.md). diff --git a/docs/builders/chroot.mdx b/docs/builders/chroot.mdx index b08c3aaa..4af6bde7 100644 --- a/docs/builders/chroot.mdx +++ b/docs/builders/chroot.mdx @@ -159,8 +159,7 @@ shared images the resulting name will point to the actual source used to create Usage example: - - +**HCL2** ```hcl // When accessing one of these variables from inside the builder, you need to @@ -182,8 +181,7 @@ post-processor "manifest" { } } ``` - - +**JSON** ```json "post-processors": [ @@ -198,8 +196,6 @@ post-processor "manifest" { ] ``` - - ## Examples @@ -219,9 +215,8 @@ On a VM with a system-assigned managed identity that has the contributor role on its own resource group, the following config can be used to create an updated Debian image: - - +**HCL2** ```hcl source "azure-chroot" "example" { @@ -239,9 +234,8 @@ build { } ``` - - +**JSON** ```json { @@ -263,8 +257,6 @@ build { } ``` - - ### Using a Service Principal @@ -276,8 +268,7 @@ to update your VM. Set the `ARM_IMAGE_RESOURCEGROUP_ID` variable to an existing resource group in the subscription where the resulting image will be created. - - +**HCL2** ```hcl variable "client_id" { @@ -312,8 +303,7 @@ build { } ``` - - +**JSON** ```json { @@ -346,6 +336,4 @@ build { } ``` - - diff --git a/docs/builders/dtl.mdx b/docs/builders/dtl.mdx index 1ae1791a..39e90e62 100644 --- a/docs/builders/dtl.mdx +++ b/docs/builders/dtl.mdx @@ -18,47 +18,6 @@ There are many configuration options available for the builder. We'll start with authentication parameters, then go over the Azure ARM builder specific options. In addition to the options listed here, a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can be configured for this builder. -### Authentication options - -@include 'builder/azure/common/client/Config.mdx' - -#### Managed Identity - -If you're running Packer on an Azure VM with a [managed identity](/packer/plugins/builders/azure#azure-managed-identity) you don't need to specify any additional configuration options. As Packer will attempt to use the Managed Identity and subscription of the VM that Packer is running on. - -#### Interactive User Authentication - -To use interactive user authentication, you should specify `subscription_id` only. -Packer will use cached credentials or redirect you to a website to log in. - -#### Service Principal - -To use a [service principal](/packer/plugins/builders/azure#azure-active-directory-service-principal) -you should specify `subscription_id`, `client_id` and one of `client_secret`, -`client_cert_path` or `client_jwt`. - -- `subscription_id` (string) - Subscription under which the build will be - performed. **The service principal specified in `client_id` must have full - access to this subscription, unless build_resource_group_name option is - specified in which case it needs to have owner access to the existing - resource group specified in build_resource_group_name parameter.** - -- `client_id` (string) - The Active Directory service principal associated with - your builder. - -- `client_secret` (string) - The password or secret for your service principal. - -- `client_cert_path` (string) - The location of a PEM file containing a - certificate and private key for service principal. - -- `client_cert_token_timeout` (duration string | ex: "1h30m12s") - How long to set the expire time on the token created when using - `client_cert_path`. - -- `client_jwt` (string) - The bearer JWT assertion signed using a certificate - associated with your service principal principal. See [Azure Active - Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) - for more information. - ## Azure DevTest Labs builder specific options ### Required: diff --git a/docs/provisioners/dtlartifact.mdx b/docs/provisioners/dtlartifact.mdx index 61509961..96144904 100644 --- a/docs/provisioners/dtlartifact.mdx +++ b/docs/provisioners/dtlartifact.mdx @@ -10,57 +10,8 @@ Type: `azure-dtlartifact` The Azure DevTest Labs provisioner can be used to apply an artifact to a VM - See [Add an artifact to a VM](https://docs.microsoft.com/en-us/azure/devtest-labs/add-artifact-vm) - -## Configuration Reference - -There are many configuration options available for the builder. We'll start -with authentication parameters, then go over the Azure ARM builder specific -options. In addition to the options listed here, a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can be configured for this builder. - -### Authentication options - -@include 'builder/azure/common/client/Config.mdx' - -#### Managed Identity - -If you're running Packer on an Azure VM with a [managed identity](/packer/plugins/builders/azure#azure-managed-identity) you don't need to specify any additional configuration options. As Packer will attempt to use the Managed Identity and subscription of the VM that Packer is running on. - -#### Interactive User Authentication - -To use interactive user authentication, you should specify `subscription_id` only. -Packer will use cached credentials or redirect you to a website to log in. - -#### Service Principal - -To use a [service principal](/packer/plugins/builders/azure#azure-active-directory-service-principal) -you should specify `subscription_id`, `client_id` and one of `client_secret`, -`client_cert_path` or `client_jwt`. - -- `subscription_id` (string) - Subscription under which the build will be - performed. **The service principal specified in `client_id` must have full - access to this subscription, unless build_resource_group_name option is - specified in which case it needs to have owner access to the existing - resource group specified in build_resource_group_name parameter.** - -- `client_id` (string) - The Active Directory service principal associated with - your builder. - -- `client_secret` (string) - The password or secret for your service principal. - -- `client_cert_path` (string) - The location of a PEM file containing a - certificate and private key for service principal. - -- `client_cert_token_timeout` (duration string | ex: "1h30m12s") - How long to set the expire time on the token created when using - `client_cert_path`. - -- `client_jwt` (string) - The bearer JWT assertion signed using a certificate - associated with your service principal principal. See [Azure Active - Directory docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials) - for more information. - ## Azure DevTest Labs provisioner specific options - ### Required: @include 'provisioner/azure-dtlartifact/Config-required.mdx'