Skip to content

Instantly share code, notes, and snippets.

@zaenk
Last active February 18, 2023 18:38
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zaenk/20178e637299404dcdcc1ff4667f24d7 to your computer and use it in GitHub Desktop.
Save zaenk/20178e637299404dcdcc1ff4667f24d7 to your computer and use it in GitHub Desktop.
Packer, Hyper-V, Ansible, Windows, WLS

Create Linux images on Windows with Packer

Prerequisites:

  • Windows 10 Pro
  • WLS, Ubuntu 16.04 (a.k.a.: Bash on Ubuntu on Windows)
  • Hyper-V
  • Packer (1.0.0, added to path)
  • Ansible (2.3.0, installed on WSL)
  • qemu-img (2.3.0, added to path)

Prepare envitonment to run Ansible provisioner

  • Add ansible.cmd and ansible-playbook.cmd to your PATH
  • Either set USER environment variable in command line or configure ansible_user in packer template to the default user of th WLS

Packer template

Builder

I am using the Hyper-V sample template with the sample preseed

Provisioner

Sample playbook: ansible-bootstrap-ubuntu-16.04.yml

"provisioners": [
  {
    "type": "ansible",
    "playbook_file": "./ansible/ansible-bootstrap-ubuntu-16.04.yml"
  }

Post-processor

This step does not work yet: hashicorp/packer#4140 As of packer 1.0.0, There is no support for cmd/powershell step inside post-processors

Convert the vhdx into qcow2 format

"post-processors": [
  {
    "type": "shell-local",
    "inline": ["qemu-img convert \"output-hyperv-iso\\Virtual Hard Disks\\{{user `vm_name`}}.vhdx\" -O qcow2 ubuntu-xenial.qcow2"]
  }
]
# bashrc for Git Bash on Windows
alias wbash="/c/Windows/System32/bash.exe"
convert_path() {
# repace GitBash /driveletters with WLS bash /mnt/driveletters
# note: this not works with 1 letter directory letters
params=$(echo $* | sed -e "s/\/\b\(.\)\//\/mnt\/\1\//g")
echo $params
}
ansible() {
params=$(convert_path $*)
wbash -c "ansible $params"
}
ansible-playbook() {
params=$(convert_path $*)
wbash -c "ansible-playbook $params"
}
ansible-galaxy() {
params=$(convert_path $*)
wbash -c "ansible-galaxy $params"
}
@echo off
REM "alias" for ansible-galaxy in cmd/powershell because why the hell not?
set args=%*
REM replace backslashes with slashes
call set args=%%args:\=/%%
REM fix drive letters
call set args=%%args:C:=/mnt/c%%
REM call set args=%%args:D:=/mnt/d%%
REM call set args=%%args:E:=/mnt/e%%
C:\Windows\System32\bash.exe -c 'ansible-galaxy %args%'
@echo off
REM "alias" for packer ansible provisioner running in cmd/powershell
set args=%*
REM replace backslashes with slashes
call set args=%%args:\=/%%
REM fix drive letters
call set args=%%args:C:=/mnt/c%%
REM call set args=%%args:D:=/mnt/d%%
REM call set args=%%args:E:=/mnt/e%%
C:\Windows\System32\bash.exe -c 'ansible-playbook %args%'
@echo off
REM "alias" for packer ansible provisioner running in cmd/powershell
set args=%*
REM replace backslashes with slashes
call set args=%%args:\=/%%
REM fix drive letters
call set args=%%args:C:=/mnt/c%%
REM call set args=%%args:D:=/mnt/d%%
REM call set args=%%args:E:=/mnt/e%%
C:\Windows\System32\bash.exe -c 'ansible %args%'
@roobixx
Copy link

roobixx commented Oct 18, 2021

I am having the same issue outlined by @coolrazor007 with Packer 1.7.6

@roobixx
Copy link

roobixx commented Oct 19, 2021

@coolrazor007

After some investigating the issue was how things were being escaped. For instance double quotes were being escaped with a \ such in packer_build_name="vm" was being automatically escaped \"vm\" but that escaping \ then got clipped by the batch script to /"vm/".

Also the single quotes in the line 11 needed to be changed to double quotes

I'm sure you could reorder some of the call set lines to not need to do as much replacement and such but I wanted to leave everything intact as much as possible.

@echo off
REM "alias" for packer ansible provisioner running in cmd/powershell
set args=%*
REM replace backslashes with slashes
call set args=%%args:\=/%%
REM fix drive letters
call set args=%%args:C:=/mnt/c%%
REM call set args=%%args:D:=/mnt/d%%
REM call set args=%%args:E:=/mnt/e%%
call set args=%%args:/"=%%
call set args=%%args:"'='%%
call set args=%%args:'"='%%
call set args=%%args:"=^'%%

C:\Windows\System32\bash.exe -c "ansible-playbook %args%"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment