From 7c4645539217ed81f3cef9164083746af2593ccf Mon Sep 17 00:00:00 2001 From: BrandonRomano Date: Wed, 14 Jun 2023 16:07:19 -0700 Subject: [PATCH] docs: Upgrade plugin to integrations framework --- .github/workflows/ensure-docs-compiled.yaml | 22 + ...notify-integration-release-via-manual.yaml | 46 + .../notify-integration-release-via-tag.yaml | 40 + .web-docs/README.md | 38 + .web-docs/components/builder/iso/README.md | 1655 +++++++++++++++++ .web-docs/components/builder/vmcx/README.md | 1537 +++++++++++++++ .web-docs/metadata.hcl | 17 + .web-docs/scripts/compile-to-webdocs.sh | 129 ++ GNUmakefile | 6 + docs/README.md | 57 +- docs/builders/index.mdx | 23 - 11 files changed, 3509 insertions(+), 61 deletions(-) create mode 100644 .github/workflows/ensure-docs-compiled.yaml create mode 100644 .github/workflows/notify-integration-release-via-manual.yaml create mode 100644 .github/workflows/notify-integration-release-via-tag.yaml create mode 100644 .web-docs/README.md create mode 100644 .web-docs/components/builder/iso/README.md create mode 100644 .web-docs/components/builder/vmcx/README.md create mode 100644 .web-docs/metadata.hcl create mode 100755 .web-docs/scripts/compile-to-webdocs.sh delete mode 100644 docs/builders/index.mdx 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/notify-integration-release-via-manual.yaml b/.github/workflows/notify-integration-release-via-manual.yaml new file mode 100644 index 00000000..19d3916e --- /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@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ github.event.inputs.branch }} + # Ensure that Docs are Compiled + - uses: actions/setup-go@v4 + - 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@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + repository: hashicorp/integration-release-action + path: ./integration-release-action + - name: Notify Release + uses: ./integration-release-action + with: + integration_identifier: 'packer/hashicorp/hyperv' + 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..85f6f356 --- /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@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ github.ref }} + # Ensure that Docs are Compiled + - uses: actions/setup-go@v4 + - 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@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + repository: hashicorp/integration-release-action + path: ./integration-release-action + - name: Notify Release + uses: ./integration-release-action + with: + integration_identifier: 'packer/hashicorp/hyperv' + release_version: ${{ github.ref_name }} + release_sha: ${{ github.ref }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.web-docs/README.md b/.web-docs/README.md new file mode 100644 index 00000000..18f1b900 --- /dev/null +++ b/.web-docs/README.md @@ -0,0 +1,38 @@ +The HyperV Packer Plugin is able to create +[Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) +virtual machines and export them. + +## 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 { + hyperv = { + source = "github.com/hashicorp/hyperv" + version = "~> 1" + } + } +} +``` + +Alternatively, you can use `packer plugins install` to manage installation of this plugin. + +```sh +$ packer plugins install github.com/hashicorp/hyperv +``` + +### Components + +#### Builders + +- [hyperv-iso](packer/integrations/hashicorp/hyperv/latest/components/builder/hyperv-iso.mdx) - Starts from an ISO file, + creates a brand new Hyper-V VM, installs an OS, provisions software within + the OS, then exports that machine to create an image. This is best for + people who want to start from scratch. + +- [hyperv-vmcx](packer/integrations/hashicorp/hyperv/latest/components/builder/hyperv-vmcx.mdx) - Clones an an existing + virtual machine, provisions software within the OS, then exports that + machine to create an image. This is best for people who have existing base + images and want to customize them. diff --git a/.web-docs/components/builder/iso/README.md b/.web-docs/components/builder/iso/README.md new file mode 100644 index 00000000..cfa49a23 --- /dev/null +++ b/.web-docs/components/builder/iso/README.md @@ -0,0 +1,1655 @@ +Type: `hyperv-iso` +Artifact BuilderId: `MSOpenTech.hyperv` + +The Hyper-V Packer builder is able to create +[Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) +virtual machines and export them, starting from an ISO image. + +The builder builds a virtual machine by creating a new virtual machine from +scratch. Typically, the VM is booted, an OS is installed, and software is +provisioned within the OS. Finally the VM is shut down. The result of the +Hyper-V builder is a directory containing all the files necessary to run +the virtual machine portably. + +## Basic Example + +Here is a basic example. This example is not functional. It will start the OS +installer but then fail because we don't provide the preseed file for Ubuntu +to self-install. Still, the example serves to show the basic configuration: + +```json +{ + "type": "hyperv-iso", + "iso_url": "http://releases.ubuntu.com/12.04/ubuntu-12.04.5-server-amd64.iso", + "iso_checksum": "md5:769474248a3897f4865817446f9a4a53", + "ssh_username": "packer", + "ssh_password": "packer", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" +} +``` + +By default Packer will perform a hard power off of a virtual machine. +However, when a machine is powered off this way, it is possible that +changes made to the VMs file system may not be fully synced, possibly +leading to corruption of files or lost changes. As such, it is important to +add a `shutdown_command`. This tells Packer how to safely shutdown and +power off the VM. + +## ISO Configuration Reference + + + +By default, Packer will symlink, download or copy image files to the Packer +cache into a "`hash($iso_url+$iso_checksum).$iso_target_extension`" file. +Packer uses [hashicorp/go-getter](https://github.com/hashicorp/go-getter) in +file mode in order to perform a download. + +go-getter supports the following protocols: + +* Local files +* Git +* Mercurial +* HTTP +* Amazon S3 + +Examples: +go-getter can guess the checksum type based on `iso_checksum` length, and it is +also possible to specify the checksum type. + +In JSON: + +```json + + "iso_checksum": "946a6077af6f5f95a51f82fdc44051c7aa19f9cfc5f737954845a6050543d7c2", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```json + + "iso_checksum": "file:ubuntu.org/..../ubuntu-14.04.1-server-amd64.iso.sum", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```json + + "iso_checksum": "file://./shasums.txt", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```json + + "iso_checksum": "file:./shasums.txt", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +In HCL2: + +```hcl + + iso_checksum = "946a6077af6f5f95a51f82fdc44051c7aa19f9cfc5f737954845a6050543d7c2" + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```hcl + + iso_checksum = "file:ubuntu.org/..../ubuntu-14.04.1-server-amd64.iso.sum" + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```hcl + + iso_checksum = "file://./shasums.txt" + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```hcl + + iso_checksum = "file:./shasums.txt", + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + + + + +### Required: + + + +- `iso_checksum` (string) - The checksum for the ISO file or virtual hard drive file. The type of + the checksum is specified within the checksum field as a prefix, ex: + "md5:{$checksum}". The type of the checksum can also be omitted and + Packer will try to infer it based on string length. Valid values are + "none", "{$checksum}", "md5:{$checksum}", "sha1:{$checksum}", + "sha256:{$checksum}", "sha512:{$checksum}" or "file:{$path}". Here is a + list of valid checksum values: + * md5:090992ba9fd140077b0661cb75f7ce13 + * 090992ba9fd140077b0661cb75f7ce13 + * sha1:ebfb681885ddf1234c18094a45bbeafd91467911 + * ebfb681885ddf1234c18094a45bbeafd91467911 + * sha256:ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * file:http://releases.ubuntu.com/20.04/SHA256SUMS + * file:file://./local/path/file.sum + * file:./local/path/file.sum + * none + Although the checksum will not be verified when it is set to "none", + this is not recommended since these files can be very large and + corruption does happen from time to time. + +- `iso_url` (string) - A URL to the ISO containing the installation image or virtual hard drive + (VHD or VHDX) file to clone. + + + + +### Optional: + + + +- `iso_urls` ([]string) - Multiple URLs for the ISO to download. Packer will try these in order. + If anything goes wrong attempting to download or while downloading a + single URL, it will move on to the next. All URLs must point to the same + file (same checksum). By default this is empty and `iso_url` is used. + Only one of `iso_url` or `iso_urls` can be specified. + +- `iso_target_path` (string) - The path where the iso should be saved after download. By default will + go in the packer cache, with a hash of the original filename and + checksum as its name. + +- `iso_target_extension` (string) - The extension of the iso file after download. This defaults to `iso`. + + + + +## Configuration Reference + +There are many configuration options available for the Hyper-V builder. They +are organized below into two categories: required and optional. Within each +category, the available options are alphabetized and described. + +In addition to the options listed here, a +[communicator](/packer/docs/templates/legacy_json_templates/communicator) can be configured for this +builder. + +### Optional: + +- `output_directory` (string) - This setting specifies the directory that +artifacts from the build, such as the virtual machine files and disks, +will be output to. The path to the directory may be relative or +absolute. If relative, the path is relative to the working directory +`packer` is executed from. This directory must not exist or, if +created, must be empty prior to running the builder. By default this is +"output-BUILDNAME" where "BUILDNAME" is the name of the build. + + + +- `disable_shutdown` (bool) - Packer normally halts the virtual machine after all provisioners have + run when no `shutdown_command` is defined. If this is set to `true`, Packer + *will not* halt the virtual machine but will assume that the VM will shut itself down + when it's done, via the preseed.cfg or your final provisioner. + Packer will wait for a default of 5 minutes until the virtual machine is shutdown. + The timeout can be changed using the `shutdown_timeout` option. + +- `disk_size` (uint) - The size, in megabytes, of the hard disk to create + for the VM. By default, this is 40 GB. + +- `use_legacy_network_adapter` (bool) - If true use a legacy network adapter as the NIC. + This defaults to false. A legacy network adapter is fully emulated NIC, and is thus + supported by various exotic operating systems, but this emulation requires + additional overhead and should only be used if absolutely necessary. + +- `differencing_disk` (bool) - If true enables differencing disks. Only + the changes will be written to the new disk. This is especially useful if + your source is a VHD/VHDX. This defaults to false. + +- `use_fixed_vhd_format` (bool) - If true, creates the boot disk on the + virtual machine as a fixed VHD format disk. The default is false, which + creates a dynamic VHDX format disk. This option requires setting + generation to 1, skip_compaction to true, and + differencing_disk to false. Additionally, any value entered for + disk_block_size will be ignored. The most likely use case for this + option is outputing a disk that is in the format required for upload to + Azure. + + + + + + +- `disk_block_size` (uint) - The block size of the VHD to be created. + Recommended disk block size for Linux hyper-v guests is 1 MiB. This + defaults to "32" MiB. + +- `memory` (uint) - The amount, in megabytes, of RAM to assign to the + VM. By default, this is 1 GB. + +- `secondary_iso_images` ([]string) - A list of ISO paths to + attach to a VM when it is booted. This is most useful for unattended + Windows installs, which look for an Autounattend.xml file on removable + media. By default, no secondary ISO will be attached. + +- `disk_additional_size` ([]uint) - The size or sizes of any + additional hard disks for the VM in megabytes. If this is not specified + then the VM will only contain a primary hard disk. Additional drives + will be attached to the SCSI interface only. The builder uses + expandable rather than fixed-size virtual hard disks, so the actual + file representing the disk will not use the full size unless it is + full. + +- `guest_additions_mode` (string) - If set to attach then attach and + mount the ISO image specified in guest_additions_path. If set to + none then guest additions are not attached and mounted; This is the + default. + +- `guest_additions_path` (string) - The path to the ISO image for guest + additions. + +- `vm_name` (string) - This is the name of the new virtual machine, + without the file extension. By default this is "packer-BUILDNAME", + where "BUILDNAME" is the name of the build. + +- `switch_name` (string) - The name of the switch to connect the virtual + machine to. By default, leaving this value unset will cause Packer to + try and determine the switch to use by looking for an external switch + that is up and running. + +- `switch_vlan_id` (string) - This is the VLAN of the virtual switch's + network card. By default none is set. If none is set then a VLAN is not + set on the switch's network card. If this value is set it should match + the VLAN specified in by vlan_id. + +- `mac_address` (string) - This allows a specific MAC address to be used on + the default virtual network card. The MAC address must be a string with + no delimiters, for example "0000deadbeef". + +- `vlan_id` (string) - This is the VLAN of the virtual machine's network + card for the new virtual machine. By default none is set. If none is set + then VLANs are not set on the virtual machine's network card. + +- `cpus` (uint) - The number of CPUs the virtual machine should use. If + this isn't specified, the default is 1 CPU. + +- `generation` (uint) - The Hyper-V generation for the virtual machine. By + default, this is 1. Generation 2 Hyper-V virtual machines do not support + floppy drives. In this scenario use secondary_iso_images instead. Hard + drives and DVD drives will also be SCSI and not IDE. + +- `enable_mac_spoofing` (bool) - If true enable MAC address spoofing + for the virtual machine. This defaults to false. + +- `enable_dynamic_memory` (bool) - If true enable dynamic memory for + the virtual machine. This defaults to false. + +- `enable_secure_boot` (bool) - If true enable secure boot for the + virtual machine. This defaults to false. See secure_boot_template + below for additional settings. + +- `secure_boot_template` (string) - The secure boot template to be + configured. Valid values are "MicrosoftWindows" (Windows) or + "MicrosoftUEFICertificateAuthority" (Linux). This only takes effect if + enable_secure_boot is set to "true". This defaults to "MicrosoftWindows". + +- `enable_virtualization_extensions` (bool) - If true enable + virtualization extensions for the virtual machine. This defaults to + false. For nested virtualization you need to enable MAC spoofing, + disable dynamic memory and have at least 4GB of RAM assigned to the + virtual machine. + +- `enable_tpm` (bool) - If true enable a virtual TPM for the + virtual machine. This defaults to false. + +- `temp_path` (string) - The location under which Packer will create a directory to house all the + VM files and folders during the build. By default `%TEMP%` is used + which, for most systems, will evaluate to + `%USERPROFILE%/AppData/Local/Temp`. + + The build directory housed under `temp_path` will have a name similar to + `packerhv1234567`. The seven digit number at the end of the name is + automatically generated by Packer to ensure the directory name is + unique. + +- `configuration_version` (string) - This allows you to set the vm version when calling New-VM to generate + the vm. + +- `keep_registered` (bool) - If "true", Packer will not delete the VM from + The Hyper-V manager. + +- `skip_compaction` (bool) - If true skip compacting the hard disk for + the virtual machine when exporting. This defaults to false. + +- `skip_export` (bool) - If true Packer will skip the export of the VM. + If you are interested only in the VHD/VHDX files, you can enable this + option. The resulting VHD/VHDX file will be output to + /Virtual Hard Disks. By default this option is false + and Packer will export the VM to output_directory. + +- `headless` (bool) - Packer defaults to building Hyper-V virtual + machines by launching a GUI that shows the console of the machine being + built. When this value is set to true, the machine will start without a + console. + +- `first_boot_device` (string) - When configured, determines the device or device type that is given preferential + treatment when choosing a boot device. + + For Generation 1: + - `IDE` + - `CD` *or* `DVD` + - `Floppy` + - `NET` + + For Generation 2: + - `IDE:x:y` + - `SCSI:x:y` + - `CD` *or* `DVD` + - `NET` + +- `boot_order` ([]string) - When configured, the boot order determines the order of the devices + from which to boot. + + The device name must be in the form of `SCSI:x:y`, for example, + to boot from the first scsi device use `SCSI:0:0`. + + **NB** You should also set `first_boot_device` (e.g. `DVD`). + + **NB** Although the VM will have this initial boot order, the OS can + change it, for example, Ubuntu 18.04 will modify the boot order to + include itself as the first boot option. + + **NB** This only works for Generation 2 machines. + + + + +## Http directory configuration reference + + + +Packer will create an http server serving `http_directory` when it is set, a +random free port will be selected and the architecture of the directory +referenced will be available in your builder. + +Example usage from a builder: + +``` +wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/foo/bar/preseed.cfg +``` + + + + +### Optional: + + + +- `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this + directory will be available over HTTP that will be requestable from the + virtual machine. This is useful for hosting kickstart files and so on. + By default this is an empty string, which means no HTTP server will be + started. The address and port of the HTTP server will be available as + variables in `boot_command`. This is covered in more detail below. + +- `http_content` (map[string]string) - Key/Values to serve using an HTTP server. `http_content` works like and + conflicts with `http_directory`. The keys represent the paths and the + values contents, the keys must start with a slash, ex: `/path/to/file`. + `http_content` is useful for hosting kickstart files and so on. By + default this is empty, which means no HTTP server will be started. The + address and port of the HTTP server will be available as variables in + `boot_command`. This is covered in more detail below. + Example: + ```hcl + http_content = { + "/a/b" = file("http/b") + "/foo/bar" = templatefile("${path.root}/preseed.cfg", { packages = ["nginx"] }) + } + ``` + +- `http_port_min` (int) - These are the minimum and maximum port to use for the HTTP server + started to serve the `http_directory`. Because Packer often runs in + parallel, Packer will choose a randomly available port in this range to + run the HTTP server. If you want to force the HTTP server to be on one + port, make this minimum and maximum port the same. By default the values + are `8000` and `9000`, respectively. + +- `http_port_max` (int) - HTTP Port Max + +- `http_bind_address` (string) - This is the bind address for the HTTP server. Defaults to 0.0.0.0 so that + it will work with any network interface. + + + + +## Shutdown configuration reference + +### Optional: + + + +- `shutdown_command` (string) - The command to use to gracefully shut down the machine once all + provisioning is complete. By default this is an empty string, which + tells Packer to just forcefully shut down the machine. This setting can + be safely omitted if for example, a shutdown command to gracefully halt + the machine is configured inside a provisioning script. If one or more + scripts require a reboot it is suggested to leave this blank (since + reboots may fail) and instead specify the final shutdown command in your + last script. + +- `shutdown_timeout` (duration string | ex: "1h5m2s") - The amount of time to wait after executing the shutdown_command for the + virtual machine to actually shut down. If the machine doesn't shut down + in this time it is considered an error. By default, the time out is "5m" + (five minutes). + + + + +## Floppy configuration reference + + + +A floppy can be made available for your build. This is most useful for +unattended Windows installs, which look for an Autounattend.xml file on +removable media. By default, no floppy will be attached. All files listed in +this setting get placed into the root directory of the floppy and the floppy +is attached as the first floppy device. The summary size of the listed files +must not exceed 1.44 MB. The supported ways to move large files into the OS +are using `http_directory` or [the file +provisioner](/packer/docs/provisioner/file). + + + + +### Optional: + + + +- `floppy_files` ([]string) - A list of files to place onto a floppy disk that is attached when the VM + is booted. Currently, no support exists for creating sub-directories on + the floppy. Wildcard characters (\\*, ?, and \[\]) are allowed. Directory + names are also allowed, which will add all the files found in the + directory to the floppy. + +- `floppy_dirs` ([]string) - A list of directories to place onto the floppy disk recursively. This is + similar to the `floppy_files` option except that the directory structure + is preserved. This is useful for when your floppy disk includes drivers + or if you just want to organize it's contents as a hierarchy. Wildcard + characters (\\*, ?, and \[\]) are allowed. The maximum summary size of + all files in the listed directories are the same as in `floppy_files`. + +- `floppy_content` (map[string]string) - Key/Values to add to the floppy disk. The keys represent the paths, and + the values contents. It can be used alongside `floppy_files` or + `floppy_dirs`, which is useful to add large files without loading them + into memory. If any paths are specified by both, the contents in + `floppy_content` will take precedence. + + Usage example (HCL): + + ```hcl + floppy_files = ["vendor-data"] + floppy_content = { + "meta-data" = jsonencode(local.instance_data) + "user-data" = templatefile("user-data", { packages = ["nginx"] }) + } + floppy_label = "cidata" + ``` + +- `floppy_label` (string) - Floppy Label + + + + +### CD configuration reference + + + +- `cd_files` ([]string) - A list of files to place onto a CD that is attached when the VM is + booted. This can include either files or directories; any directories + will be copied onto the CD recursively, preserving directory structure + hierarchy. Symlinks will have the link's target copied into the directory + tree on the CD where the symlink was. File globbing is allowed. + + Usage example (JSON): + + ```json + "cd_files": ["./somedirectory/meta-data", "./somedirectory/user-data"], + "cd_label": "cidata", + ``` + + Usage example (HCL): + + ```hcl + cd_files = ["./somedirectory/meta-data", "./somedirectory/user-data"] + cd_label = "cidata" + ``` + + The above will create a CD with two files, user-data and meta-data in the + CD root. This specific example is how you would create a CD that can be + used for an Ubuntu 20.04 autoinstall. + + Since globbing is also supported, + + ```hcl + cd_files = ["./somedirectory/*"] + cd_label = "cidata" + ``` + + Would also be an acceptable way to define the above cd. The difference + between providing the directory with or without the glob is whether the + directory itself or its contents will be at the CD root. + + Use of this option assumes that you have a command line tool installed + that can handle the iso creation. Packer will use one of the following + tools: + + * xorriso + * mkisofs + * hdiutil (normally found in macOS) + * oscdimg (normally found in Windows as part of the Windows ADK) + +- `cd_content` (map[string]string) - Key/Values to add to the CD. The keys represent the paths, and the values + contents. It can be used alongside `cd_files`, which is useful to add large + files without loading them into memory. If any paths are specified by both, + the contents in `cd_content` will take precedence. + + Usage example (HCL): + + ```hcl + cd_files = ["vendor-data"] + cd_content = { + "meta-data" = jsonencode(local.instance_data) + "user-data" = templatefile("user-data", { packages = ["nginx"] }) + } + cd_label = "cidata" + ``` + +- `cd_label` (string) - CD Label + + + + +## Communicator configuration reference + +### Optional common fields: + + + +- `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. + + + + +### Optional SSH fields: + + + +- `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. + + +### Optional WinRM fields: + + + +- `winrm_username` (string) - The username to use to connect to WinRM. + +- `winrm_password` (string) - The password to use to connect to WinRM. + +- `winrm_host` (string) - The address for WinRM to connect to. + + NOTE: If using an Amazon EBS builder, you can specify the interface + WinRM connects to via + [`ssh_interface`](/packer/integrations/hashicorp/amazon/latest/components/builder/ebs#ssh_interface) + +- `winrm_no_proxy` (bool) - Setting this to `true` adds the remote + `host:port` to the `NO_PROXY` environment variable. This has the effect of + bypassing any configured proxies when connecting to the remote host. + Default to `false`. + +- `winrm_port` (int) - The WinRM port to connect to. This defaults to `5985` for plain + unencrypted connection and `5986` for SSL when `winrm_use_ssl` is set to + true. + +- `winrm_timeout` (duration string | ex: "1h5m2s") - The amount of time to wait for WinRM to become available. This defaults + to `30m` since setting up a Windows machine generally takes a long time. + +- `winrm_use_ssl` (bool) - If `true`, use HTTPS for WinRM. + +- `winrm_insecure` (bool) - If `true`, do not check server certificate chain and host name. + +- `winrm_use_ntlm` (bool) - If `true`, NTLMv2 authentication (with session security) will be used + for WinRM, rather than default (basic authentication), removing the + requirement for basic authentication to be enabled within the target + guest. Further reading for remote connection authentication can be found + [here](https://msdn.microsoft.com/en-us/library/aa384295(v=vs.85).aspx). + + + + +## Boot Configuration Reference + + + +The boot configuration is very important: `boot_command` specifies the keys +to type when the virtual machine is first booted in order to start the OS +installer. This command is typed after boot_wait, which gives the virtual +machine some time to actually load. + +The boot_command is an array of strings. The strings are all typed in +sequence. It is an array only to improve readability within the template. + +There are a set of special keys available. If these are in your boot +command, they will be replaced by the proper key: + +- `` - Backspace + +- `` - Delete + +- ` ` - Simulates an actual "enter" or "return" keypress. + +- `` - Simulates pressing the escape key. + +- `` - Simulates pressing the tab key. + +- ` - ` - Simulates pressing a function key. + +- ` ` - Simulates pressing an arrow key. + +- `` - Simulates pressing the spacebar. + +- `` - Simulates pressing the insert key. + +- ` ` - Simulates pressing the home and end keys. + + - ` ` - Simulates pressing the page up and page down + keys. + +- `` - Simulates pressing the Menu key. + +- ` ` - Simulates pressing the alt key. + +- ` ` - Simulates pressing the ctrl key. + +- ` ` - Simulates pressing the shift key. + +- ` ` - Simulates pressing the ⌘ or Windows key. + + - ` ` - Adds a 1, 5 or 10 second pause before + sending any additional keys. This is useful if you have to generally + wait for the UI to update before typing more. + + - `` - Add an arbitrary pause before sending any additional keys. + The format of `XX` is a sequence of positive decimal numbers, each with + optional fraction and a unit suffix, such as `300ms`, `1.5h` or `2h45m`. + Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. For + example `` or ``. + + - ` ` - Any printable keyboard character, and of these + "special" expressions, with the exception of the `` types, can + also be toggled on or off. For example, to simulate ctrl+c, use + `c`. Be sure to release them, otherwise they + will be held down until the machine reboots. To hold the `c` key down, + you would use ``. Likewise, `` to release. + + - `{{ .HTTPIP }} {{ .HTTPPort }}` - The IP and port, respectively of an + HTTP server that is started serving the directory specified by the + `http_directory` configuration parameter. If `http_directory` isn't + specified, these will be blank! + +- `{{ .Name }}` - The name of the VM. + +Example boot command. This is actually a working boot command used to start an +CentOS 6.4 installer: + +In JSON: + +```json +"boot_command": [ + + "", + " ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos6-ks.cfg" + ] + +``` + +In HCL2: + +```hcl +boot_command = [ + + "", + " ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos6-ks.cfg" + ] + +``` + +The example shown below is a working boot command used to start an Ubuntu +12.04 installer: + +In JSON: + +```json +"boot_command": [ + + "", + "/install/vmlinuz noapic ", + "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{ .Name }} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false ", + "initrd=/install/initrd.gz -- " + +] +``` + +In HCL2: + +```hcl +boot_command = [ + + "", + "/install/vmlinuz noapic ", + "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{ .Name }} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false ", + "initrd=/install/initrd.gz -- " + +] +``` + +For more examples of various boot commands, see the sample projects from our +[community templates page](https://packer.io/community-tools#templates). + + + + +### Optional: + + + +- `boot_keygroup_interval` (duration string | ex: "1h5m2s") - Time to wait after sending a group of key pressses. The value of this + should be a duration. Examples are `5s` and `1m30s` which will cause + Packer to wait five seconds and one minute 30 seconds, respectively. If + this isn't specified, a sensible default value is picked depending on + the builder type. + +- `boot_wait` (duration string | ex: "1h5m2s") - The time to wait after booting the initial virtual machine before typing + the `boot_command`. The value of this should be a duration. Examples are + `5s` and `1m30s` which will cause Packer to wait five seconds and one + minute 30 seconds, respectively. If this isn't specified, the default is + `10s` or 10 seconds. To set boot_wait to 0s, use a negative number, such + as "-1s" + +- `boot_command` ([]string) - This is an array of commands to type when the virtual machine is first + booted. The goal of these commands should be to type just enough to + initialize the operating system installer. Special keys can be typed as + well, and are covered in the section below on the boot command. If this + is not specified, it is assumed the installer will start itself. + + + + +## Integration Services + +Packer will automatically attach the integration services ISO as a DVD drive +for the version of Hyper-V that is running. + +## Generation 1 vs Generation 2 + +Floppy drives are no longer supported by generation 2 machines. This requires +you to take another approach when dealing with preseed or answer files. Two +possible options are using your own virtual DVD drives, the cd_files option, +or using Packer's built in web server. + +When dealing with Windows you need to enable UEFI drives for generation 2 +virtual machines. + +## Creating an ISO From a Directory + +Programs like mkisofs can be used to create an ISO from a directory. There is +a [windows version of +mkisofs](http://opensourcepack.blogspot.co.uk/p/cdrtools.html) available. + +Below is a working PowerShell script that can be used to create a Windows +answer ISO: + +```powershell +$isoFolder = "answer-iso" +if (test-path $isoFolder){ + remove-item $isoFolder -Force -Recurse +} + +if (test-path windows\windows-2012R2-serverdatacenter-amd64\answer.iso){ + remove-item windows\windows-2012R2-serverdatacenter-amd64\answer.iso -Force +} + +mkdir $isoFolder + +copy windows\windows-2012R2-serverdatacenter-amd64\Autounattend.xml $isoFolder\ +copy windows\windows-2012R2-serverdatacenter-amd64\sysprep-unattend.xml $isoFolder\ +copy windows\common\set-power-config.ps1 $isoFolder\ +copy windows\common\microsoft-updates.ps1 $isoFolder\ +copy windows\common\win-updates.ps1 $isoFolder\ +copy windows\common\run-sysprep.ps1 $isoFolder\ +copy windows\common\run-sysprep.cmd $isoFolder\ + +$textFile = "$isoFolder\Autounattend.xml" + +$c = Get-Content -Encoding UTF8 $textFile + +# Enable UEFI and disable Non EUFI +$c | % { $_ -replace '','','Finish Non UEFI -->' } | % { $_ -replace '' } | % { $_ -replace 'Finish UEFI compatible -->','' } | sc -Path $textFile + +& .\mkisofs.exe -r -iso-level 4 -UDF -o windows\windows-2012R2-serverdatacenter-amd64\answer.iso $isoFolder + +if (test-path $isoFolder){ + remove-item $isoFolder -Force -Recurse +} +``` + +## Example For Windows Server 2012 R2 Generation 2 + +Packer config: + +```json +{ + "builders": [ + { + "vm_name": "windows2012r2", + "type": "hyperv-iso", + "disk_size": 61440, + "floppy_files": [], + "secondary_iso_images": [ + "./windows/windows-2012R2-serverdatacenter-amd64/answer.iso" + ], + "http_directory": "./windows/common/http/", + "boot_wait": "0s", + "boot_command": ["aaa"], + "iso_url": "http://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_EVAL_EN-US-IRM_SSS_X64FREE_EN-US_DV5.ISO", + "iso_checksum": "md5:458ff91f8abc21b75cb544744bf92e6a", + "communicator": "winrm", + "winrm_username": "vagrant", + "winrm_password": "vagrant", + "winrm_timeout": "4h", + "shutdown_command": "f:\\run-sysprep.cmd", + "memory": 4096, + "cpus": 4, + "generation": 2, + "switch_name": "LAN", + "enable_secure_boot": true + } + ], + "provisioners": [ + { + "type": "powershell", + "elevated_user": "vagrant", + "elevated_password": "vagrant", + "scripts": [ + "./windows/common/install-7zip.ps1", + "./windows/common/install-chef.ps1", + "./windows/common/compile-dotnet-assemblies.ps1", + "./windows/common/cleanup.ps1", + "./windows/common/ultradefrag.ps1", + "./windows/common/sdelete.ps1" + ] + } + ], + "post-processors": [ + { + "type": "vagrant", + "keep_input_artifact": false, + "output": "{{.Provider}}_windows-2012r2_chef.box" + } + ] +} +``` + +autounattend.xml: + +```xml + + + + + + en-US + + en-US + en-US + en-US + en-US + en-US + + + + + + + + Primary + 1 + 350 + + + 2 + Primary + true + + + + + true + NTFS + + 1 + 1 + + + NTFS + + C + 2 + 2 + + + 0 + true + + + + + + + /IMAGE/NAME + Windows Server 2012 R2 SERVERSTANDARD + + + + 0 + 2 + + + + + + + + + + + + OnError + + true + Vagrant + Vagrant + + + + + + + false + + vagrant-2012r2 + Coordinated Universal Time + + + + true + + + false + false + + + true + + + true + + + + + + + + vagrant + true</PlainText> + </Password> + <Enabled>true</Enabled> + <Username>vagrant</Username> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> + <Description>Set Execution Policy 64 Bit</Description> + <Order>1</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> + <Description>Set Execution Policy 32 Bit</Description> + <Order>2</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm quickconfig -q</CommandLine> + <Description>winrm quickconfig -q</Description> + <Order>3</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm quickconfig -transport:http</CommandLine> + <Description>winrm quickconfig -transport:http</Description> + <Order>4</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}</CommandLine> + <Description>Win RM MaxTimeoutms</Description> + <Order>5</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="300"}</CommandLine> + <Description>Win RM MaxMemoryPerShellMB</Description> + <Order>6</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}</CommandLine> + <Description>Win RM AllowUnencrypted</Description> + <Order>7</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}</CommandLine> + <Description>Win RM auth Basic</Description> + <Order>8</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}</CommandLine> + <Description>Win RM client auth Basic</Description> + <Order>9</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"} </CommandLine> + <Description>Win RM listener Address/Port</Description> + <Order>10</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes </CommandLine> + <Description>Win RM adv firewall enable</Description> + <Order>11</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow</CommandLine> + <Description>Win RM port open</Description> + <Order>12</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow</CommandLine> + <Description>Win RM port open</Description> + <Order>13</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c net stop winrm </CommandLine> + <Description>Stop Win RM Service </Description> + <Order>14</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c sc config winrm start= disabled</CommandLine> + <Description>Win RM Autostart</Description> + <Order>15</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f</CommandLine> + <Order>16</Order> + <Description>Show file extensions in Explorer</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f</CommandLine> + <Order>17</Order> + <Description>Enable QuickEdit mode</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f</CommandLine> + <Order>18</Order> + <Description>Show Run command in Start Menu</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f</CommandLine> + <Order>19</Order> + <Description>Show Administrative Tools in Start Menu</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f</CommandLine> + <Order>20</Order> + <Description>Zero Hibernation File</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f</CommandLine> + <Order>21</Order> + <Description>Disable Hibernation Mode</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c wmic useraccount where "name='vagrant'" set PasswordExpires=FALSE</CommandLine> + <Order>22</Order> + <Description>Disable password expiration for vagrant user</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxShellsPerUser="30"}</CommandLine> + <Description>Win RM MaxShellsPerUser</Description> + <Order>23</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxProcessesPerShell="25"}</CommandLine> + <Description>Win RM MaxProcessesPerShell</Description> + <Order>24</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v DisablePasswordChange /t REG_DWORD /d 1 /f</CommandLine> + <Description>Turn off computer password</Description> + <Order>25</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow</CommandLine> + <Description>ICMP open for ping</Description> + <Order>26</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <!-- WITH WINDOWS UPDATES --> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\set-power-config.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\set-power-config.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\set-power-config.ps1)</CommandLine> + <Order>97</Order> + <Description>Turn off all power saving and timeouts</Description> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\microsoft-updates.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\microsoft-updates.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\microsoft-updates.ps1)</CommandLine> + <Order>98</Order> + <Description>Enable Microsoft Updates</Description> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\win-updates.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\win-updates.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\win-updates.ps1)</CommandLine> + <Description>Install Windows Updates</Description> + <Order>100</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <!-- END WITH WINDOWS UPDATES --> + </FirstLogonCommands> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideLocalAccountScreen>true</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Group>administrators</Group> + <DisplayName>Vagrant</DisplayName> + <Name>vagrant</Name> + <Description>Vagrant User</Description> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <RegisteredOwner /> + <TimeZone>Coordinated Universal Time</TimeZone> + </component> + </settings> + <settings pass="offlineServicing"> + <component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <EnableLUA>false</EnableLUA> + </component> + </settings> + <cpi:offlineImage cpi:source="wim:c:/projects/baseboxes/9600.16384.winblue_rtm.130821-1623_x64fre_server_eval_en-us-irm_sss_x64free_en-us_dv5_slipstream/sources/install.wim#Windows Server 2012 R2 SERVERDATACENTER" xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> +``` + +sysprep-unattend.xml: + +```xml +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="generalize"> + <component language="neutral" name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SkipRearm>1</SkipRearm> + </component> + </settings> + <settings pass="oobeSystem"> +<!-- Setup proxy after sysprep + <component name="Microsoft-Windows-IE-ClientNetworkProtocolImplementation" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <POLICYProxySettingsPerUser>1</POLICYProxySettingsPerUser> + <HKLMProxyEnable>false</HKLMProxyEnable> + <HKLMProxyServer>cache-proxy:3142</HKLMProxyServer> + </component> +Finish proxy after sysprep --> + <component language="neutral" name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>0809:00000809</InputLocale> + <SystemLocale>en-GB</SystemLocale> + <UILanguage>en-US</UILanguage> + <UILanguageFallback>en-US</UILanguageFallback> + <UserLocale>en-GB</UserLocale> + </component> + <component language="neutral" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Group>administrators</Group> + <DisplayName>Vagrant</DisplayName> + <Name>vagrant</Name> + <Description>Vagrant User</Description> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <DisableAutoDaylightTimeSet>true</DisableAutoDaylightTimeSet> + <TimeZone>Coordinated Universal Time</TimeZone> + <VisualEffects> + <SystemDefaultBackgroundColor>2</SystemDefaultBackgroundColor> + </VisualEffects> + </component> + </settings> +</unattend> +``` + +-> **Warning:** Please note that if you're setting up WinRM for provisioning, you'll probably want to turn it off or restrict its permissions as part of a shutdown script at the end of Packer's provisioning process. For more details on the why/how, check out this useful blog post and the associated code: +https://cloudywindows.io/post/winrm-for-provisioning-close-the-door-on-the-way-out-eh/ + +## Example For Ubuntu Vivid Generation 2 + +If you are running Windows under virtualization, you may need to create a +virtual switch with an `External` connection type. + +### Packer config: + +```json +{ + "variables": { + "vm_name": "ubuntu-xenial", + "cpus": "2", + "memory": "1024", + "disk_size": "21440", + "iso_url": "http://releases.ubuntu.com/16.04/ubuntu-16.04.6-server-amd64.iso", + "iso_checksum": "sha1:056b7c15efc15bbbf40bf1a9ff1a3531fcbf70a2" + }, + "builders": [ + { + "vm_name": "{{user `vm_name`}}", + "type": "hyperv-iso", + "disk_size": "{{user `disk_size`}}", + "guest_additions_mode": "disable", + "iso_url": "{{user `iso_url`}}", + "iso_checksum": "{{user `iso_checksum`}}", + "communicator": "ssh", + "ssh_username": "packer", + "ssh_password": "packer", + "ssh_timeout": "4h", + "http_directory": "./", + "boot_wait": "5s", + "boot_command": [ + "<esc><wait10><esc><esc><enter><wait>", + "set gfxpayload=1024x768<enter>", + "linux /install/vmlinuz ", + "preseed/url=http://{{.HTTPIP}}:{{.HTTPPort}}/hyperv-taliesins.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{.Name}} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false <enter>", + "initrd /install/initrd.gz<enter>", + "boot<enter>" + ], + "shutdown_command": "echo 'packer' | sudo -S -E shutdown -P now", + "memory": "{{user `memory`}}", + "cpus": "{{user `cpus`}}", + "generation": 2, + "enable_secure_boot": false + } + ] +} +``` + +### preseed.cfg: + +```text +## Options to set on the command line +d-i debian-installer/locale string en_US.utf8 +d-i console-setup/ask_detect boolean false +d-i console-setup/layout string us + +d-i netcfg/get_hostname string nl-ams-basebox3 +d-i netcfg/get_domain string unassigned-domain + +d-i time/zone string UTC +d-i clock-setup/utc-auto boolean true +d-i clock-setup/utc boolean true + +d-i kbd-chooser/method select American English + +d-i netcfg/wireless_wep string + +d-i base-installer/kernel/override-image string linux-server + +d-i debconf debconf/frontend select Noninteractive + +d-i pkgsel/install-language-support boolean false +tasksel tasksel/first multiselect standard, ubuntu-server + +## Partitioning +d-i partman-auto/method string lvm + +d-i partman-lvm/confirm boolean true +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true + +d-i partman-auto-lvm/guided_size string max +d-i partman-auto/choose_recipe select atomic + +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Write the changes to disks and configure LVM? +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true + +d-i partman-partitioning/no_bootable_gpt_biosgrub boolean false +d-i partman-partitioning/no_bootable_gpt_efi boolean false +d-i partman-efi/non_efi_system boolean true + +# Default user +d-i passwd/user-fullname string packer +d-i passwd/username string packer +d-i passwd/user-password password packer +d-i passwd/user-password-again password packer +d-i user-setup/encrypt-home boolean false +d-i user-setup/allow-password-weak boolean true + +# Minimum packages +d-i pkgsel/include string openssh-server ntp linux-tools-$(uname -r) linux-cloud-tools-$(uname -r) linux-cloud-tools-common + +# Upgrade packages after debootstrap? (none, safe-upgrade, full-upgrade) +# (note: set to none for speed) +d-i pkgsel/upgrade select none + +d-i grub-installer/only_debian boolean true +d-i grub-installer/with_other_os boolean true +d-i finish-install/reboot_in_progress note + +d-i pkgsel/update-policy select none + +choose-mirror-bin mirror/http/proxy string +``` + +-> **Note for \*nix guests:** Please note that Packer requires the VM to be +running a hyper-v KVP daemon in order to detect the IP address of the guest VM. +On RHEL based machines this may require installing the package `hyperv-daemons` +and ensuring the `hypervkvpd` service is started at boot. On Debian based +machines, you may need `linux-cloud-tools-common` for `hv_kvp_daemon`. Failure +to do this may cause packer to wait at `Waiting for SSH to become available...` +before eventually timing out. + +Also note that while the operating system is still being installed by a preseed +file, it is normal to see `Waiting for SSH/WinRM to be available` and +`Error getting SSH/WinRM host: No ip address` error messages until the system +is actually installed and ready to be connected to. + +For more information about the hyper-v daemons and supported distributions, see +the Microsoft docs at +https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/supported-linux-and-freebsd-virtual-machines-for-hyper-v-on-windows diff --git a/.web-docs/components/builder/vmcx/README.md b/.web-docs/components/builder/vmcx/README.md new file mode 100644 index 00000000..9893f867 --- /dev/null +++ b/.web-docs/components/builder/vmcx/README.md @@ -0,0 +1,1537 @@ +Type: `hyperv-vmcx` +Artifact BuilderId: `MSOpenTech.hyperv` + +The Hyper-V Packer builder is able to use exported virtual machines or clone +existing +[Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) +virtual machines. + +Typically, the builder imports or clones an existing virtual machine, +boots it, provisions software within the OS, and then shuts it down. The +result of the Hyper-V builder is a directory containing all the files +necessary to run the virtual machine portably. + +## Basic Examples + +Here are some basic examples. Neither example would really do anything more +than producing a copy of the source virtual machine. However, the examples +could be used as a starting point for more advanced templates. + +Import from folder: + +```json +{ + "type": "hyperv-vmcx", + "clone_from_vmcx_path": "c:/path/to/ubuntu-12.04.5-server-amd64", + "ssh_username": "packer", + "ssh_password": "packer", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" +} +``` + +Clone from existing virtual machine: + +```json +{ + "clone_from_vm_name": "ubuntu-12.04.5-server-amd64", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now", + "ssh_password": "packer", + "ssh_username": "packer", + "type": "hyperv-vmcx" +} +``` + +By default Packer will perform a hard power off of a virtual machine. +However, when a machine is powered off this way, it is possible that +changes made to the VMs file system may not be fully synced, possibly +leading to corruption of files or lost changes. As such, it is important to +add a `shutdown_command`. This tells Packer how to safely shutdown and +power off the VM. + +## Configuration Reference + +There are many configuration options available for the Hyper-V builder. They +are organized below into two categories: required and optional. Within each +category, the available options are alphabetized and described. + +In addition to the options listed here, a +[communicator](/packer/docs/templates/legacy_json_templates/communicator) can be configured for this +builder. + +## ISO Configuration Reference + +<!-- Code generated from the comments of the ISOConfig struct in multistep/commonsteps/iso_config.go; DO NOT EDIT MANUALLY --> + +By default, Packer will symlink, download or copy image files to the Packer +cache into a "`hash($iso_url+$iso_checksum).$iso_target_extension`" file. +Packer uses [hashicorp/go-getter](https://github.com/hashicorp/go-getter) in +file mode in order to perform a download. + +go-getter supports the following protocols: + +* Local files +* Git +* Mercurial +* HTTP +* Amazon S3 + +Examples: +go-getter can guess the checksum type based on `iso_checksum` length, and it is +also possible to specify the checksum type. + +In JSON: + +```json + + "iso_checksum": "946a6077af6f5f95a51f82fdc44051c7aa19f9cfc5f737954845a6050543d7c2", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```json + + "iso_checksum": "file:ubuntu.org/..../ubuntu-14.04.1-server-amd64.iso.sum", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```json + + "iso_checksum": "file://./shasums.txt", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```json + + "iso_checksum": "file:./shasums.txt", + "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +In HCL2: + +```hcl + + iso_checksum = "946a6077af6f5f95a51f82fdc44051c7aa19f9cfc5f737954845a6050543d7c2" + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```hcl + + iso_checksum = "file:ubuntu.org/..../ubuntu-14.04.1-server-amd64.iso.sum" + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```hcl + + iso_checksum = "file://./shasums.txt" + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +```hcl + + iso_checksum = "file:./shasums.txt", + iso_url = "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso" + +``` + +<!-- End of code generated from the comments of the ISOConfig struct in multistep/commonsteps/iso_config.go; --> + + +### Required: + +<!-- Code generated from the comments of the ISOConfig struct in multistep/commonsteps/iso_config.go; DO NOT EDIT MANUALLY --> + +- `iso_checksum` (string) - The checksum for the ISO file or virtual hard drive file. The type of + the checksum is specified within the checksum field as a prefix, ex: + "md5:{$checksum}". The type of the checksum can also be omitted and + Packer will try to infer it based on string length. Valid values are + "none", "{$checksum}", "md5:{$checksum}", "sha1:{$checksum}", + "sha256:{$checksum}", "sha512:{$checksum}" or "file:{$path}". Here is a + list of valid checksum values: + * md5:090992ba9fd140077b0661cb75f7ce13 + * 090992ba9fd140077b0661cb75f7ce13 + * sha1:ebfb681885ddf1234c18094a45bbeafd91467911 + * ebfb681885ddf1234c18094a45bbeafd91467911 + * sha256:ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * file:http://releases.ubuntu.com/20.04/SHA256SUMS + * file:file://./local/path/file.sum + * file:./local/path/file.sum + * none + Although the checksum will not be verified when it is set to "none", + this is not recommended since these files can be very large and + corruption does happen from time to time. + +- `iso_url` (string) - A URL to the ISO containing the installation image or virtual hard drive + (VHD or VHDX) file to clone. + +<!-- End of code generated from the comments of the ISOConfig struct in multistep/commonsteps/iso_config.go; --> + + +### Optional: + +<!-- Code generated from the comments of the ISOConfig struct in multistep/commonsteps/iso_config.go; DO NOT EDIT MANUALLY --> + +- `iso_urls` ([]string) - Multiple URLs for the ISO to download. Packer will try these in order. + If anything goes wrong attempting to download or while downloading a + single URL, it will move on to the next. All URLs must point to the same + file (same checksum). By default this is empty and `iso_url` is used. + Only one of `iso_url` or `iso_urls` can be specified. + +- `iso_target_path` (string) - The path where the iso should be saved after download. By default will + go in the packer cache, with a hash of the original filename and + checksum as its name. + +- `iso_target_extension` (string) - The extension of the iso file after download. This defaults to `iso`. + +<!-- End of code generated from the comments of the ISOConfig struct in multistep/commonsteps/iso_config.go; --> + + +### Required for virtual machine import: + +- `clone_from_vmcx_path` (string) - The path to a directory containing a + previously exported virtual machine. The exported machine will be used + as the source for new VM. + + note: You should provide the named directory that contains the + "Virtual Machines", "Snapshots", and/or "Virtual Hard Disks" subdirectories, + not the .vmcx file itself. + +### Required for virtual machine clone: + +- `clone_from_vm_name` (string) - The name of the VM to clone from. Ideally + the machine to clone from should be shutdown. + +### Optional: + +<!-- Code generated from the comments of the Config struct in builder/hyperv/vmcx/builder.go; DO NOT EDIT MANUALLY --> + +- `disable_shutdown` (bool) - Packer normally halts the virtual machine after all provisioners have + run when no `shutdown_command` is defined. If this is set to `true`, Packer + *will not* halt the virtual machine but will assume that the VM will shut itself down + when it's done, via the preseed.cfg or your final provisioner. + Packer will wait for a default of 5 minutes until the virtual machine is shutdown. + The timeout can be changed using the `shutdown_timeout` option. + +- `disk_size` (\*uint) - The size, in megabytes, of the primary hard disk + for the VM. By default, this is the same as the cloned VM. + +- `clone_from_vmcx_path` (string) - This is the path to a directory containing an exported virtual machine. + +- `clone_from_vm_name` (string) - This is the name of the virtual machine to clone from. + +- `clone_from_snapshot_name` (string) - The name of a snapshot in the + source machine to use as a starting point for the clone. If the value + given is an empty string, the last snapshot present in the source will + be chosen as the starting point for the new VM. + +- `clone_all_snapshots` (bool) - If set to true all snapshots + present in the source machine will be copied when the machine is + cloned. The final result of the build will be an exported virtual + machine that contains all the snapshots of the parent. + +- `differencing_disk` (bool) - If true enables differencing disks. Only + the changes will be written to the new disk. This is especially useful if + your source is a VHD/VHDX. This defaults to false. + +- `copy_in_compare` (bool) - When cloning a vm to build from, we run a powershell + Compare-VM command, which, depending on your version of Windows, may need + the "Copy" flag to be set to true or false. Defaults to "false". Command: + +<!-- End of code generated from the comments of the Config struct in builder/hyperv/vmcx/builder.go; --> + + +<!-- Code generated from the comments of the CommonConfig struct in builder/hyperv/common/config.go; DO NOT EDIT MANUALLY --> + +- `disk_block_size` (uint) - The block size of the VHD to be created. + Recommended disk block size for Linux hyper-v guests is 1 MiB. This + defaults to "32" MiB. + +- `memory` (uint) - The amount, in megabytes, of RAM to assign to the + VM. By default, this is 1 GB. + +- `secondary_iso_images` ([]string) - A list of ISO paths to + attach to a VM when it is booted. This is most useful for unattended + Windows installs, which look for an Autounattend.xml file on removable + media. By default, no secondary ISO will be attached. + +- `disk_additional_size` ([]uint) - The size or sizes of any + additional hard disks for the VM in megabytes. If this is not specified + then the VM will only contain a primary hard disk. Additional drives + will be attached to the SCSI interface only. The builder uses + expandable rather than fixed-size virtual hard disks, so the actual + file representing the disk will not use the full size unless it is + full. + +- `guest_additions_mode` (string) - If set to attach then attach and + mount the ISO image specified in guest_additions_path. If set to + none then guest additions are not attached and mounted; This is the + default. + +- `guest_additions_path` (string) - The path to the ISO image for guest + additions. + +- `vm_name` (string) - This is the name of the new virtual machine, + without the file extension. By default this is "packer-BUILDNAME", + where "BUILDNAME" is the name of the build. + +- `switch_name` (string) - The name of the switch to connect the virtual + machine to. By default, leaving this value unset will cause Packer to + try and determine the switch to use by looking for an external switch + that is up and running. + +- `switch_vlan_id` (string) - This is the VLAN of the virtual switch's + network card. By default none is set. If none is set then a VLAN is not + set on the switch's network card. If this value is set it should match + the VLAN specified in by vlan_id. + +- `mac_address` (string) - This allows a specific MAC address to be used on + the default virtual network card. The MAC address must be a string with + no delimiters, for example "0000deadbeef". + +- `vlan_id` (string) - This is the VLAN of the virtual machine's network + card for the new virtual machine. By default none is set. If none is set + then VLANs are not set on the virtual machine's network card. + +- `cpus` (uint) - The number of CPUs the virtual machine should use. If + this isn't specified, the default is 1 CPU. + +- `generation` (uint) - The Hyper-V generation for the virtual machine. By + default, this is 1. Generation 2 Hyper-V virtual machines do not support + floppy drives. In this scenario use secondary_iso_images instead. Hard + drives and DVD drives will also be SCSI and not IDE. + +- `enable_mac_spoofing` (bool) - If true enable MAC address spoofing + for the virtual machine. This defaults to false. + +- `enable_dynamic_memory` (bool) - If true enable dynamic memory for + the virtual machine. This defaults to false. + +- `enable_secure_boot` (bool) - If true enable secure boot for the + virtual machine. This defaults to false. See secure_boot_template + below for additional settings. + +- `secure_boot_template` (string) - The secure boot template to be + configured. Valid values are "MicrosoftWindows" (Windows) or + "MicrosoftUEFICertificateAuthority" (Linux). This only takes effect if + enable_secure_boot is set to "true". This defaults to "MicrosoftWindows". + +- `enable_virtualization_extensions` (bool) - If true enable + virtualization extensions for the virtual machine. This defaults to + false. For nested virtualization you need to enable MAC spoofing, + disable dynamic memory and have at least 4GB of RAM assigned to the + virtual machine. + +- `enable_tpm` (bool) - If true enable a virtual TPM for the + virtual machine. This defaults to false. + +- `temp_path` (string) - The location under which Packer will create a directory to house all the + VM files and folders during the build. By default `%TEMP%` is used + which, for most systems, will evaluate to + `%USERPROFILE%/AppData/Local/Temp`. + + The build directory housed under `temp_path` will have a name similar to + `packerhv1234567`. The seven digit number at the end of the name is + automatically generated by Packer to ensure the directory name is + unique. + +- `configuration_version` (string) - This allows you to set the vm version when calling New-VM to generate + the vm. + +- `keep_registered` (bool) - If "true", Packer will not delete the VM from + The Hyper-V manager. + +- `skip_compaction` (bool) - If true skip compacting the hard disk for + the virtual machine when exporting. This defaults to false. + +- `skip_export` (bool) - If true Packer will skip the export of the VM. + If you are interested only in the VHD/VHDX files, you can enable this + option. The resulting VHD/VHDX file will be output to + <output_directory>/Virtual Hard Disks. By default this option is false + and Packer will export the VM to output_directory. + +- `headless` (bool) - Packer defaults to building Hyper-V virtual + machines by launching a GUI that shows the console of the machine being + built. When this value is set to true, the machine will start without a + console. + +- `first_boot_device` (string) - When configured, determines the device or device type that is given preferential + treatment when choosing a boot device. + + For Generation 1: + - `IDE` + - `CD` *or* `DVD` + - `Floppy` + - `NET` + + For Generation 2: + - `IDE:x:y` + - `SCSI:x:y` + - `CD` *or* `DVD` + - `NET` + +- `boot_order` ([]string) - When configured, the boot order determines the order of the devices + from which to boot. + + The device name must be in the form of `SCSI:x:y`, for example, + to boot from the first scsi device use `SCSI:0:0`. + + **NB** You should also set `first_boot_device` (e.g. `DVD`). + + **NB** Although the VM will have this initial boot order, the OS can + change it, for example, Ubuntu 18.04 will modify the boot order to + include itself as the first boot option. + + **NB** This only works for Generation 2 machines. + +<!-- End of code generated from the comments of the CommonConfig struct in builder/hyperv/common/config.go; --> + + +## Communicator configuration reference + +### Optional common fields: + +<!-- Code generated from the comments of the Config struct in communicator/config.go; DO NOT EDIT MANUALLY --> + +- `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. + +<!-- End of code generated from the comments of the Config struct in communicator/config.go; --> + + +### Optional SSH fields: + +<!-- Code generated from the comments of the SSH struct in communicator/config.go; DO NOT EDIT MANUALLY --> + +- `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) - + +<!-- End of code generated from the comments of the SSH struct in communicator/config.go; --> + + +- `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. + + +### Optional WinRM fields: + +<!-- Code generated from the comments of the WinRM struct in communicator/config.go; DO NOT EDIT MANUALLY --> + +- `winrm_username` (string) - The username to use to connect to WinRM. + +- `winrm_password` (string) - The password to use to connect to WinRM. + +- `winrm_host` (string) - The address for WinRM to connect to. + + NOTE: If using an Amazon EBS builder, you can specify the interface + WinRM connects to via + [`ssh_interface`](/packer/integrations/hashicorp/amazon/latest/components/builder/ebs#ssh_interface) + +- `winrm_no_proxy` (bool) - Setting this to `true` adds the remote + `host:port` to the `NO_PROXY` environment variable. This has the effect of + bypassing any configured proxies when connecting to the remote host. + Default to `false`. + +- `winrm_port` (int) - The WinRM port to connect to. This defaults to `5985` for plain + unencrypted connection and `5986` for SSL when `winrm_use_ssl` is set to + true. + +- `winrm_timeout` (duration string | ex: "1h5m2s") - The amount of time to wait for WinRM to become available. This defaults + to `30m` since setting up a Windows machine generally takes a long time. + +- `winrm_use_ssl` (bool) - If `true`, use HTTPS for WinRM. + +- `winrm_insecure` (bool) - If `true`, do not check server certificate chain and host name. + +- `winrm_use_ntlm` (bool) - If `true`, NTLMv2 authentication (with session security) will be used + for WinRM, rather than default (basic authentication), removing the + requirement for basic authentication to be enabled within the target + guest. Further reading for remote connection authentication can be found + [here](https://msdn.microsoft.com/en-us/library/aa384295(v=vs.85).aspx). + +<!-- End of code generated from the comments of the WinRM struct in communicator/config.go; --> + + +### CD configuration + +<!-- Code generated from the comments of the CDConfig struct in multistep/commonsteps/extra_iso_config.go; DO NOT EDIT MANUALLY --> + +An iso (CD) containing custom files can be made available for your build. + +By default, no extra CD will be attached. All files listed in this setting +get placed into the root directory of the CD and the CD is attached as the +second CD device. + +This config exists to work around modern operating systems that have no +way to mount floppy disks, which was our previous go-to for adding files at +boot time. + +<!-- End of code generated from the comments of the CDConfig struct in multistep/commonsteps/extra_iso_config.go; --> + + +#### Optional: + +<!-- Code generated from the comments of the CDConfig struct in multistep/commonsteps/extra_iso_config.go; DO NOT EDIT MANUALLY --> + +- `cd_files` ([]string) - A list of files to place onto a CD that is attached when the VM is + booted. This can include either files or directories; any directories + will be copied onto the CD recursively, preserving directory structure + hierarchy. Symlinks will have the link's target copied into the directory + tree on the CD where the symlink was. File globbing is allowed. + + Usage example (JSON): + + ```json + "cd_files": ["./somedirectory/meta-data", "./somedirectory/user-data"], + "cd_label": "cidata", + ``` + + Usage example (HCL): + + ```hcl + cd_files = ["./somedirectory/meta-data", "./somedirectory/user-data"] + cd_label = "cidata" + ``` + + The above will create a CD with two files, user-data and meta-data in the + CD root. This specific example is how you would create a CD that can be + used for an Ubuntu 20.04 autoinstall. + + Since globbing is also supported, + + ```hcl + cd_files = ["./somedirectory/*"] + cd_label = "cidata" + ``` + + Would also be an acceptable way to define the above cd. The difference + between providing the directory with or without the glob is whether the + directory itself or its contents will be at the CD root. + + Use of this option assumes that you have a command line tool installed + that can handle the iso creation. Packer will use one of the following + tools: + + * xorriso + * mkisofs + * hdiutil (normally found in macOS) + * oscdimg (normally found in Windows as part of the Windows ADK) + +- `cd_content` (map[string]string) - Key/Values to add to the CD. The keys represent the paths, and the values + contents. It can be used alongside `cd_files`, which is useful to add large + files without loading them into memory. If any paths are specified by both, + the contents in `cd_content` will take precedence. + + Usage example (HCL): + + ```hcl + cd_files = ["vendor-data"] + cd_content = { + "meta-data" = jsonencode(local.instance_data) + "user-data" = templatefile("user-data", { packages = ["nginx"] }) + } + cd_label = "cidata" + ``` + +- `cd_label` (string) - CD Label + +<!-- End of code generated from the comments of the CDConfig struct in multistep/commonsteps/extra_iso_config.go; --> + + +## Boot Command + +The `boot_command` configuration is very important: it specifies the keys to +type when the virtual machine is first booted in order to start the OS +installer. This command is typed after `boot_wait`, which gives the virtual +machine some time to actually load the ISO. + +As documented above, the `boot_command` is an array of strings. The strings +are all typed in sequence. It is an array only to improve readability within +the template. + +The boot command is "typed" character for character over the virtual keyboard +to the machine, simulating a human actually typing the keyboard. + +There are a set of special keys available. If these are in your boot +command, they will be replaced by the proper key: + +- `<bs>` - Backspace + +- `<del>` - Delete + +- `<enter> <return>` - Simulates an actual "enter" or "return" keypress. + +- `<esc>` - Simulates pressing the escape key. + +- `<tab>` - Simulates pressing the tab key. + +- `<f1> - <f12>` - Simulates pressing a function key. + +- `<up> <down> <left> <right>` - Simulates pressing an arrow key. + +- `<spacebar>` - Simulates pressing the spacebar. + +- `<insert>` - Simulates pressing the insert key. + +- `<home> <end>` - Simulates pressing the home and end keys. + +- `<pageUp> <pageDown>` - Simulates pressing the page up and page down keys. + +- `<menu>` - Simulates pressing the Menu key. + +- `<leftAlt> <rightAlt>` - Simulates pressing the alt key. + +- `<leftCtrl> <rightCtrl>` - Simulates pressing the ctrl key. + +- `<leftShift> <rightShift>` - Simulates pressing the shift key. + +- `<leftSuper> <rightSuper>` - Simulates pressing the ⌘ or Windows key. + +- `<wait> <wait5> <wait10>` - Adds a 1, 5 or 10 second pause before + sending any additional keys. This is useful if you have to generally wait + for the UI to update before typing more. + +- `<waitXX>` - Add an arbitrary pause before sending any additional keys. The + format of `XX` is a sequence of positive decimal numbers, each with + optional fraction and a unit suffix, such as `300ms`, `1.5h` or `2h45m`. + Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. For example + `<wait10m>` or `<wait1m20s>` + +### On/Off variants + +Any printable keyboard character, and of these "special" expressions, with the +exception of the `<wait>` types, can also be toggled on or off. For example, to +simulate ctrl+c, use `<leftCtrlOn>c<leftCtrlOff>`. Be sure to release them, +otherwise they will be held down until the machine reboots. + +To hold the `c` key down, you would use `<cOn>`. Likewise, `<cOff>` to release. + +### Templates inside boot command + +In addition to the special keys, each command to type is treated as a +[template engine](/packer/docs/templates/legacy_json_templates/engine). The +available variables are: + +- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server + that is started serving the directory specified by the `http_directory` + configuration parameter or the content specified in the `http_content` map. If + `http_directory` or `http_content` isn't specified, these will be blank! +- `Name` - The name of the VM. + +For more examples of various boot commands, see the sample projects from our +[community templates page](/community-tools#templates). +command.mdx' + +The example shown below is a working boot command used to start an Ubuntu +12.04 installer: + +```json +[ + "<esc><esc><enter><wait>", + "/install/vmlinuz noapic ", + "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{ .Name }} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false ", + "initrd=/install/initrd.gz -- <enter>" +] +``` + +For more examples of various boot commands, see the sample projects from our +[community templates page](/community-tools#templates). + +## Http directory configuration + +<!-- Code generated from the comments of the HTTPConfig struct in multistep/commonsteps/http_config.go; DO NOT EDIT MANUALLY --> + +Packer will create an http server serving `http_directory` when it is set, a +random free port will be selected and the architecture of the directory +referenced will be available in your builder. + +Example usage from a builder: + +``` +wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/foo/bar/preseed.cfg +``` + +<!-- End of code generated from the comments of the HTTPConfig struct in multistep/commonsteps/http_config.go; --> + + +### Optional: + +<!-- Code generated from the comments of the HTTPConfig struct in multistep/commonsteps/http_config.go; DO NOT EDIT MANUALLY --> + +- `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this + directory will be available over HTTP that will be requestable from the + virtual machine. This is useful for hosting kickstart files and so on. + By default this is an empty string, which means no HTTP server will be + started. The address and port of the HTTP server will be available as + variables in `boot_command`. This is covered in more detail below. + +- `http_content` (map[string]string) - Key/Values to serve using an HTTP server. `http_content` works like and + conflicts with `http_directory`. The keys represent the paths and the + values contents, the keys must start with a slash, ex: `/path/to/file`. + `http_content` is useful for hosting kickstart files and so on. By + default this is empty, which means no HTTP server will be started. The + address and port of the HTTP server will be available as variables in + `boot_command`. This is covered in more detail below. + Example: + ```hcl + http_content = { + "/a/b" = file("http/b") + "/foo/bar" = templatefile("${path.root}/preseed.cfg", { packages = ["nginx"] }) + } + ``` + +- `http_port_min` (int) - These are the minimum and maximum port to use for the HTTP server + started to serve the `http_directory`. Because Packer often runs in + parallel, Packer will choose a randomly available port in this range to + run the HTTP server. If you want to force the HTTP server to be on one + port, make this minimum and maximum port the same. By default the values + are `8000` and `9000`, respectively. + +- `http_port_max` (int) - HTTP Port Max + +- `http_bind_address` (string) - This is the bind address for the HTTP server. Defaults to 0.0.0.0 so that + it will work with any network interface. + +<!-- End of code generated from the comments of the HTTPConfig struct in multistep/commonsteps/http_config.go; --> + + +## Integration Services + +Packer will automatically attach the integration services ISO as a DVD drive +for the version of Hyper-V that is running. + +## Generation 1 vs Generation 2 + +Floppy drives are no longer supported by generation 2 machines. This requires +you to take another approach when dealing with preseed or answer files. Two +possible options are using the `cd_files` option or using Packer's built in web +server. + +When dealing with Windows you need to enable UEFI drives for generation 2 +virtual machines. + +## Creating an ISO From a Directory + +Programs like mkisofs can be used to create an ISO from a directory. There is +a [windows version of +mkisofs](http://opensourcepack.blogspot.co.uk/p/cdrtools.html) available. + +Below is a working PowerShell script that can be used to create a Windows +answer ISO: + +```powershell +$isoFolder = "answer-iso" +if (test-path $isoFolder){ + remove-item $isoFolder -Force -Recurse +} + +if (test-path windows\windows-2012R2-serverdatacenter-amd64\answer.iso){ + remove-item windows\windows-2012R2-serverdatacenter-amd64\answer.iso -Force +} + +mkdir $isoFolder + +copy windows\windows-2012R2-serverdatacenter-amd64\Autounattend.xml $isoFolder\ +copy windows\windows-2012R2-serverdatacenter-amd64\sysprep-unattend.xml $isoFolder\ +copy windows\common\set-power-config.ps1 $isoFolder\ +copy windows\common\microsoft-updates.ps1 $isoFolder\ +copy windows\common\win-updates.ps1 $isoFolder\ +copy windows\common\run-sysprep.ps1 $isoFolder\ +copy windows\common\run-sysprep.cmd $isoFolder\ + +$textFile = "$isoFolder\Autounattend.xml" + +$c = Get-Content -Encoding UTF8 $textFile + +# Enable UEFI and disable Non EUFI +$c | % { $_ -replace '<!-- Start Non UEFI -->','<!-- Start Non UEFI' } | % { $_ -replace '<!-- Finish Non UEFI -->','Finish Non UEFI -->' } | % { $_ -replace '<!-- Start UEFI compatible','<!-- Start UEFI compatible -->' } | % { $_ -replace 'Finish UEFI compatible -->','<!-- Finish UEFI compatible -->' } | sc -Path $textFile + +& .\mkisofs.exe -r -iso-level 4 -UDF -o windows\windows-2012R2-serverdatacenter-amd64\answer.iso $isoFolder + +if (test-path $isoFolder){ + remove-item $isoFolder -Force -Recurse +} +``` + +## Example For Windows Server 2012 R2 Generation 2 + +Packer config: + +```json +{ + "builders": [ + { + "vm_name": "windows2012r2", + "type": "hyperv-iso", + "disk_size": 61440, + "floppy_files": [], + "secondary_iso_images": [ + "./windows/windows-2012R2-serverdatacenter-amd64/answer.iso" + ], + "http_directory": "./windows/common/http/", + "boot_wait": "0s", + "boot_command": ["a<wait>a<wait>a"], + "iso_url": "http://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_EVAL_EN-US-IRM_SSS_X64FREE_EN-US_DV5.ISO", + "iso_checksum": "md5:458ff91f8abc21b75cb544744bf92e6a", + "communicator": "winrm", + "winrm_username": "vagrant", + "winrm_password": "vagrant", + "winrm_timeout": "4h", + "shutdown_command": "f:\\run-sysprep.cmd", + "memory": 4096, + "cpus": 4, + "generation": 2, + "switch_name": "LAN", + "enable_secure_boot": true + } + ], + "provisioners": [ + { + "type": "powershell", + "elevated_user": "vagrant", + "elevated_password": "vagrant", + "scripts": [ + "./windows/common/install-7zip.ps1", + "./windows/common/install-chef.ps1", + "./windows/common/compile-dotnet-assemblies.ps1", + "./windows/common/cleanup.ps1", + "./windows/common/ultradefrag.ps1", + "./windows/common/sdelete.ps1" + ] + } + ], + "post-processors": [ + { + "type": "vagrant", + "keep_input_artifact": false, + "output": "{{.Provider}}_windows-2012r2_chef.box" + } + ] +} +``` + +autounattend.xml: + +```xml +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="windowsPE"> + <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SetupUILanguage> + <UILanguage>en-US</UILanguage> + </SetupUILanguage> + <InputLocale>en-US</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguage>en-US</UILanguage> + <UILanguageFallback>en-US</UILanguageFallback> + <UserLocale>en-US</UserLocale> + </component> + <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <!-- Start Non UEFI --> + <DiskConfiguration> + <Disk wcm:action="add"> + <CreatePartitions> + <CreatePartition wcm:action="add"> + <Type>Primary</Type> + <Order>1</Order> + <Size>350</Size> + </CreatePartition> + <CreatePartition wcm:action="add"> + <Order>2</Order> + <Type>Primary</Type> + <Extend>true</Extend> + </CreatePartition> + </CreatePartitions> + <ModifyPartitions> + <ModifyPartition wcm:action="add"> + <Active>true</Active> + <Format>NTFS</Format> + <Label>boot</Label> + <Order>1</Order> + <PartitionID>1</PartitionID> + </ModifyPartition> + <ModifyPartition wcm:action="add"> + <Format>NTFS</Format> + <Label>Windows 2012 R2</Label> + <Letter>C</Letter> + <Order>2</Order> + <PartitionID>2</PartitionID> + </ModifyPartition> + </ModifyPartitions> + <DiskID>0</DiskID> + <WillWipeDisk>true</WillWipeDisk> + </Disk> + </DiskConfiguration> + <ImageInstall> + <OSImage> + <InstallFrom> + <MetaData wcm:action="add"> + <Key>/IMAGE/NAME </Key> + <Value>Windows Server 2012 R2 SERVERSTANDARD</Value> + </MetaData> + </InstallFrom> + <InstallTo> + <DiskID>0</DiskID> + <PartitionID>2</PartitionID> + </InstallTo> + </OSImage> + </ImageInstall> + <!-- Finish Non UEFI --> + <!-- Start UEFI compatible + <DiskConfiguration> + <Disk wcm:action="add"> + <CreatePartitions> + <CreatePartition wcm:action="add"> + <Order>1</Order> + <Size>300</Size> + <Type>Primary</Type> + </CreatePartition> + <CreatePartition wcm:action="add"> + <Order>2</Order> + <Size>100</Size> + <Type>EFI</Type> + </CreatePartition> + <CreatePartition wcm:action="add"> + <Order>3</Order> + <Size>128</Size> + <Type>MSR</Type> + </CreatePartition> + <CreatePartition wcm:action="add"> + <Order>4</Order> + <Extend>true</Extend> + <Type>Primary</Type> + </CreatePartition> + </CreatePartitions> + <ModifyPartitions> + <ModifyPartition wcm:action="add"> + <Order>1</Order> + <PartitionID>1</PartitionID> + <Label>WINRE</Label> + <Format>NTFS</Format> + <TypeID>de94bba4-06d1-4d40-a16a-bfd50179d6ac</TypeID> + </ModifyPartition> + <ModifyPartition wcm:action="add"> + <Order>2</Order> + <PartitionID>2</PartitionID> + <Label>System</Label> + <Format>FAT32</Format> + </ModifyPartition> + <ModifyPartition wcm:action="add"> + <Order>3</Order> + <PartitionID>3</PartitionID> + </ModifyPartition> + <ModifyPartition wcm:action="add"> + <Order>4</Order> + <PartitionID>4</PartitionID> + <Label>Windows</Label> + <Format>NTFS</Format> + </ModifyPartition> + </ModifyPartitions> + <DiskID>0</DiskID> + <WillWipeDisk>true</WillWipeDisk> + </Disk> + <WillShowUI>OnError</WillShowUI> + </DiskConfiguration> + <ImageInstall> + <OSImage> + <InstallFrom> + <MetaData wcm:action="add"> + <Key>/IMAGE/NAME </Key> + <Value>Windows Server 2012 R2 SERVERSTANDARD</Value> + </MetaData> + </InstallFrom> + <InstallTo> + <DiskID>0</DiskID> + <PartitionID>4</PartitionID> + </InstallTo> + </OSImage> + </ImageInstall> + Finish UEFI compatible --> + <UserData> + <!-- Product Key from http://technet.microsoft.com/en-us/library/jj612867.aspx --> + <ProductKey> + <!-- Do not uncomment the Key element if you are using trial ISOs --> + <!-- You must uncomment the Key element (and optionally insert your own key) if you are using retail or volume license ISOs --> + <!--<Key>D2N9P-3P6X9-2R39C-7RTCD-MDVJX</Key>--> + <WillShowUI>OnError</WillShowUI> + </ProductKey> + <AcceptEula>true</AcceptEula> + <FullName>Vagrant</FullName> + <Organization>Vagrant</Organization> + </UserData> + </component> + </settings> + <settings pass="specialize"> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <OEMInformation> + <HelpCustomized>false</HelpCustomized> + </OEMInformation> + <ComputerName>vagrant-2012r2</ComputerName> + <TimeZone>Coordinated Universal Time</TimeZone> + <RegisteredOwner /> + </component> + <component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon> + </component> + <component name="Microsoft-Windows-IE-ESC" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <IEHardenAdmin>false</IEHardenAdmin> + <IEHardenUser>false</IEHardenUser> + </component> + <component name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon> + </component> + <component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SkipAutoActivation>true</SkipAutoActivation> + </component> + </settings> + <settings pass="oobeSystem"> +<!-- Start Setup cache proxy during installation + <component name="Microsoft-Windows-IE-ClientNetworkProtocolImplementation" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <POLICYProxySettingsPerUser>0</POLICYProxySettingsPerUser> + <HKLMProxyEnable>true</HKLMProxyEnable> + <HKLMProxyServer>cache-proxy:3142</HKLMProxyServer> + </component> +Finish Setup cache proxy during installation --> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <AutoLogon> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Enabled>true</Enabled> + <Username>vagrant</Username> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> + <Description>Set Execution Policy 64 Bit</Description> + <Order>1</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> + <Description>Set Execution Policy 32 Bit</Description> + <Order>2</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm quickconfig -q</CommandLine> + <Description>winrm quickconfig -q</Description> + <Order>3</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm quickconfig -transport:http</CommandLine> + <Description>winrm quickconfig -transport:http</Description> + <Order>4</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}</CommandLine> + <Description>Win RM MaxTimeoutms</Description> + <Order>5</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="300"}</CommandLine> + <Description>Win RM MaxMemoryPerShellMB</Description> + <Order>6</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}</CommandLine> + <Description>Win RM AllowUnencrypted</Description> + <Order>7</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}</CommandLine> + <Description>Win RM auth Basic</Description> + <Order>8</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}</CommandLine> + <Description>Win RM client auth Basic</Description> + <Order>9</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"} </CommandLine> + <Description>Win RM listener Address/Port</Description> + <Order>10</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes </CommandLine> + <Description>Win RM adv firewall enable</Description> + <Order>11</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow</CommandLine> + <Description>Win RM port open</Description> + <Order>12</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow</CommandLine> + <Description>Win RM port open</Description> + <Order>13</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c net stop winrm </CommandLine> + <Description>Stop Win RM Service </Description> + <Order>14</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c sc config winrm start= disabled</CommandLine> + <Description>Win RM Autostart</Description> + <Order>15</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f</CommandLine> + <Order>16</Order> + <Description>Show file extensions in Explorer</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f</CommandLine> + <Order>17</Order> + <Description>Enable QuickEdit mode</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f</CommandLine> + <Order>18</Order> + <Description>Show Run command in Start Menu</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f</CommandLine> + <Order>19</Order> + <Description>Show Administrative Tools in Start Menu</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f</CommandLine> + <Order>20</Order> + <Description>Zero Hibernation File</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f</CommandLine> + <Order>21</Order> + <Description>Disable Hibernation Mode</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c wmic useraccount where "name='vagrant'" set PasswordExpires=FALSE</CommandLine> + <Order>22</Order> + <Description>Disable password expiration for vagrant user</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxShellsPerUser="30"}</CommandLine> + <Description>Win RM MaxShellsPerUser</Description> + <Order>23</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxProcessesPerShell="25"}</CommandLine> + <Description>Win RM MaxProcessesPerShell</Description> + <Order>24</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v DisablePasswordChange /t REG_DWORD /d 1 /f</CommandLine> + <Description>Turn off computer password</Description> + <Order>25</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow</CommandLine> + <Description>ICMP open for ping</Description> + <Order>26</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <!-- WITH WINDOWS UPDATES --> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\set-power-config.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\set-power-config.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\set-power-config.ps1)</CommandLine> + <Order>97</Order> + <Description>Turn off all power saving and timeouts</Description> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\microsoft-updates.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\microsoft-updates.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\microsoft-updates.ps1)</CommandLine> + <Order>98</Order> + <Description>Enable Microsoft Updates</Description> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\win-updates.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\win-updates.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\win-updates.ps1)</CommandLine> + <Description>Install Windows Updates</Description> + <Order>100</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <!-- END WITH WINDOWS UPDATES --> + </FirstLogonCommands> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideLocalAccountScreen>true</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Group>administrators</Group> + <DisplayName>Vagrant</DisplayName> + <Name>vagrant</Name> + <Description>Vagrant User</Description> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <RegisteredOwner /> + <TimeZone>Coordinated Universal Time</TimeZone> + </component> + </settings> + <settings pass="offlineServicing"> + <component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <EnableLUA>false</EnableLUA> + </component> + </settings> + <cpi:offlineImage cpi:source="wim:c:/projects/baseboxes/9600.16384.winblue_rtm.130821-1623_x64fre_server_eval_en-us-irm_sss_x64free_en-us_dv5_slipstream/sources/install.wim#Windows Server 2012 R2 SERVERDATACENTER" xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> +``` + +sysprep-unattend.xml: + +```xml +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="generalize"> + <component language="neutral" name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SkipRearm>1</SkipRearm> + </component> + </settings> + <settings pass="oobeSystem"> +<!-- Setup proxy after sysprep + <component name="Microsoft-Windows-IE-ClientNetworkProtocolImplementation" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <POLICYProxySettingsPerUser>1</POLICYProxySettingsPerUser> + <HKLMProxyEnable>false</HKLMProxyEnable> + <HKLMProxyServer>cache-proxy:3142</HKLMProxyServer> + </component> +Finish proxy after sysprep --> + <component language="neutral" name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>0809:00000809</InputLocale> + <SystemLocale>en-GB</SystemLocale> + <UILanguage>en-US</UILanguage> + <UILanguageFallback>en-US</UILanguageFallback> + <UserLocale>en-GB</UserLocale> + </component> + <component language="neutral" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Group>administrators</Group> + <DisplayName>Vagrant</DisplayName> + <Name>vagrant</Name> + <Description>Vagrant User</Description> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <DisableAutoDaylightTimeSet>true</DisableAutoDaylightTimeSet> + <TimeZone>Coordinated Universal Time</TimeZone> + <VisualEffects> + <SystemDefaultBackgroundColor>2</SystemDefaultBackgroundColor> + </VisualEffects> + </component> + </settings> +</unattend> +``` + +-> **Warning:** Please note that if you're setting up WinRM for provisioning, you'll probably want to turn it off or restrict its permissions as part of a shutdown script at the end of Packer's provisioning process. For more details on the why/how, check out this useful blog post and the associated code: +https://cloudywindows.io/post/winrm-for-provisioning-close-the-door-on-the-way-out-eh/ + +## Example For Ubuntu Vivid Generation 2 + +If you are running Windows under virtualization, you may need to create a +virtual switch with an `External` connection type. + +### Packer config: + +```json +{ + "variables": { + "vm_name": "ubuntu-xenial", + "cpu": "2", + "memory": "1024", + "disk_size": "21440", + "iso_url": "http://releases.ubuntu.com/16.04/ubuntu-16.04.1-server-amd64.iso", + "iso_checksum": "sha1:DE5EE8665048F009577763EFBF4A6F0558833E59" + }, + "builders": [ + { + "vm_name": "{{user `vm_name`}}", + "type": "hyperv-iso", + "disk_size": "{{user `disk_size`}}", + "guest_additions_mode": "disable", + "iso_url": "{{user `iso_url`}}", + "iso_checksum": "{{user `iso_checksum`}}", + "communicator": "ssh", + "ssh_username": "packer", + "ssh_password": "packer", + "ssh_timeout": "4h", + "http_directory": "./", + "boot_wait": "5s", + "boot_command": [ + "<esc><wait10><esc><esc><enter><wait>", + "set gfxpayload=1024x768<enter>", + "linux /install/vmlinuz ", + "preseed/url=http://{{.HTTPIP}}:{{.HTTPPort}}/hyperv-taliesins.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{.Name}} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false <enter>", + "initrd /install/initrd.gz<enter>", + "boot<enter>" + ], + "shutdown_command": "echo 'packer' | sudo -S -E shutdown -P now", + "memory": "{{user `memory`}}", + "cpu": "{{user `cpu`}}", + "generation": 2, + "enable_secure_boot": false + } + ] +} +``` + +### preseed.cfg: + +```text +## Options to set on the command line +d-i debian-installer/locale string en_US.utf8 +d-i console-setup/ask_detect boolean false +d-i console-setup/layout string us + +d-i netcfg/get_hostname string nl-ams-basebox3 +d-i netcfg/get_domain string unassigned-domain + +d-i time/zone string UTC +d-i clock-setup/utc-auto boolean true +d-i clock-setup/utc boolean true + +d-i kbd-chooser/method select American English + +d-i netcfg/wireless_wep string + +d-i base-installer/kernel/override-image string linux-server + +d-i debconf debconf/frontend select Noninteractive + +d-i pkgsel/install-language-support boolean false +tasksel tasksel/first multiselect standard, ubuntu-server + +## Partitioning +d-i partman-auto/method string lvm + +d-i partman-lvm/confirm boolean true +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true + +d-i partman-auto-lvm/guided_size string max +d-i partman-auto/choose_recipe select atomic + +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Write the changes to disks and configure LVM? +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true + +d-i partman-partitioning/no_bootable_gpt_biosgrub boolean false +d-i partman-partitioning/no_bootable_gpt_efi boolean false +d-i partman-efi/non_efi_system boolean true + +# Default user +d-i passwd/user-fullname string packer +d-i passwd/username string packer +d-i passwd/user-password password packer +d-i passwd/user-password-again password packer +d-i user-setup/encrypt-home boolean false +d-i user-setup/allow-password-weak boolean true + +# Minimum packages +d-i pkgsel/include string openssh-server ntp linux-tools-$(uname -r) linux-cloud-tools-$(uname -r) linux-cloud-tools-common + +# Upgrade packages after debootstrap? (none, safe-upgrade, full-upgrade) +# (note: set to none for speed) +d-i pkgsel/upgrade select none + +d-i grub-installer/only_debian boolean true +d-i grub-installer/with_other_os boolean true +d-i finish-install/reboot_in_progress note + +d-i pkgsel/update-policy select none + +choose-mirror-bin mirror/http/proxy string +``` diff --git a/.web-docs/metadata.hcl b/.web-docs/metadata.hcl new file mode 100644 index 00000000..9ce8b706 --- /dev/null +++ b/.web-docs/metadata.hcl @@ -0,0 +1,17 @@ +# For full specification on the configuration of this file visit: +# https://github.com/hashicorp/integration-template#metadata-configuration +integration { + name = "Hyper-V" + description = "The Hyper-V plugin can be used with HashiCorp Packer to create custom images from Hyper-V." + identifier = "packer/hashicorp/hyperv" + component { + type = "builder" + name = "Hyper-V VMCX" + slug = "vmcx" + } + component { + type = "builder" + name = "Hyper-V ISO" + slug = "iso" + } +} diff --git a/.web-docs/scripts/compile-to-webdocs.sh b/.web-docs/scripts/compile-to-webdocs.sh new file mode 100755 index 00000000..51a72383 --- /dev/null +++ b/.web-docs/scripts/compile-to-webdocs.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash + +# 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 e1121513..020428c5 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -34,3 +34,9 @@ generate: install-packer-sdc @go generate ./... 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 0a7738b3..18f1b900 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,57 +1,38 @@ -# Hyper-V Plugins - The HyperV Packer Plugin is able to create [Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) virtual machines and export them. -- [hyperv-iso](/docs/builders/hyperv-iso.mdx) - Starts from an ISO file, - creates a brand new Hyper-V VM, installs an OS, provisions software within - the OS, then exports that machine to create an image. This is best for - people who want to start from scratch. - -- [hyperv-vmcx](/docs/builders/hyperv-vmcx.mdx) - Clones an an existing - virtual machine, provisions software within the OS, then exports that - machine to create an image. This is best for people who have existing base - images and want to customize them. - ## 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 { - name = { - version = ">= 1.1.1" - source = "github.com/hashicorp/name" + hyperv = { + source = "github.com/hashicorp/hyperv" + version = "~> 1" } } } ``` -#### Manual installation +Alternatively, you can use `packer plugins install` to manage installation of this plugin. -You can find pre-built binary releases of the plugin [here](https://github.com/hashicorp/packer-plugin-name/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). +```sh +$ packer plugins install github.com/hashicorp/hyperv +``` +### Components -#### From Source +#### Builders + +- [hyperv-iso](packer/integrations/hashicorp/hyperv/latest/components/builder/hyperv-iso.mdx) - Starts from an ISO file, + creates a brand new Hyper-V VM, installs an OS, provisions software within + the OS, then exports that machine to create an image. This is best for + people who want to start from scratch. -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-name` 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). +- [hyperv-vmcx](packer/integrations/hashicorp/hyperv/latest/components/builder/hyperv-vmcx.mdx) - Clones an an existing + virtual machine, provisions software within the OS, then exports that + machine to create an image. This is best for people who have existing base + images and want to customize them. diff --git a/docs/builders/index.mdx b/docs/builders/index.mdx deleted file mode 100644 index 66d294f0..00000000 --- a/docs/builders/index.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -description: | - The Hyper-V Packer builder is able to create Hyper-V virtual machines and - export them. -page_title: Hyper-V - Builders -nav_title: Overview ---- - -# HyperV Builder - -The HyperV Packer builder is able to create -[Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) -virtual machines and export them. - -- [hyperv-iso](/packer/plugins/builders/hyperv/iso) - Starts from an ISO file, - creates a brand new Hyper-V VM, installs an OS, provisions software within - the OS, then exports that machine to create an image. This is best for - people who want to start from scratch. - -- [hyperv-vmcx](/packer/plugins/builders/hyperv/vmcx) - Clones an an existing - virtual machine, provisions software within the OS, then exports that - machine to create an image. This is best for people who have existing base - images and want to customize them.