Hello,
I’m trying to use the ansible provisioner with a qemu builder. Everything runs through successfully… only the resulting image does not contain the changes imposed by ansible…
Really, I do not understand what’s happening here.
packer Version: 1.9.4
qemu builder plugin version: 1.0.9
ansible provisioner plugin version: 1.1.0
ansible version: 2.15.4
qemu version: 6.2.0
installed OS: Debian 12.1
This is my packer template:
packer {
required_plugins {
qemu = {
source = "github.com/hashicorp/qemu"
version = "~> 1"
}
ansible = {
source = "github.com/hashicorp/ansible"
version = "~> 1"
}
}
}
source "qemu" "debian" {
accelerator = "kvm"
iso_url = "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.1.0-amd64-netinst.iso"
iso_checksum = "sha256:9f181ae12b25840a508786b1756c6352a0e58484998669288c4eec2ab16b8559"
disk_size = 10000
memory = 1024
format = "qcow2"
machine_type = "q35"
output_directory = "output"
vm_name = "debian"
#headless = true
ssh_username = "debian"
ssh_password = "12345678"
ssh_timeout = "15m"
ssh_port = 22
boot_command = [
"<esc><wait>",
"install <wait>",
"preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/debian_preseed.cfg <wait>",
"debian-installer=en_US.UTF-8 <wait>",
"auto <wait>",
"locale=en_US.UTF-8 <wait>",
"kbd-chooser/method=us <wait>",
"keyboard-configuration/xkb-keymap=us <wait>",
"netcfg/get_hostname={{ .Name }} <wait>",
"netcfg/get_domain=local <wait>",
"fb=false <wait>",
"debconf/frontend=noninteractive <wait>",
"console-setup/ask_detect=false <wait>",
"console-keymaps-at/keymap=us <wait>",
"<enter><wait>"
]
http_directory = "http"
}
build {
sources = ["source.qemu.debian"]
provisioner "ansible" {
playbook_file = "./ansible/debian.yaml"
extra_arguments = [
"--extra-vars", "ansible_password=12345678 ansible_become_password=12345678",
"-vvvv"
]
ansible_env_vars = [
"ANSIBLE_HOST_KEY_CHECKING=False"
]
use_proxy = false
user = "debian"
local_port = 22
keep_inventory_file = true
}
}
This is my ansible playbook:
- name: 'Perform image setup'
hosts: default
become: true
tasks:
- name: Append to kernel parameters
ansible.builtin.lineinfile:
path: /etc/default/grub
search_string: 'GRUB_CMDLINE_LINUX='
line: 'GRUB_CMDLINE_LINUX="console=ttyS0,115200"'
register: test
- name: Slurp grub file
slurp:
src: /etc/default/grub
register: slurpfile
- debug:
msg:
- "{{ slurpfile['content'] | b64decode }}"
- name: update grub
ansible.builtin.command: '/usr/sbin/update-grub'
As you can see, I output the file /etc/default/grub
from within the ansible script. This gives the correct result. But when I boot the image after the packer build
, the file is unchanged as if ansible did not run at all.
I would be very thankful for an explaination and/or a fix.
Background:
My intention is to create VMs with terraform from this image. Also I would like to be able to connect to these VMs even if they do not have a working network setup (for debugging). If I created the VM from within virt-manager
or a similar tool, I would just open the graphical console (it’s backed by VNC, I suppose). But virt-manager
does not list VMs created with terraform. Instead I’ve found the solution virsh console
but this requires the kernel parameter console
to be set. This is what I would like to achieve with the ansible script.
In fact I’ve tried the shell provisioner before, but with the same result. I thought this was because I did not manage to deal correctly with four (!!) nested levels of quotes – so I’ve switched to ansible, which is much more readable, fortunately.
So as an alternative to answer my question above would be to suggest other means to connect to qemu VMs created by terraform…
Thanks and Regards,
Carsten
PS: this is the output of packer build
(without ansible -vvvv
):
qemu.debian: output will be in this color.
==> qemu.debian: Retrieving ISO
==> qemu.debian: Trying https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.1.0-amd64-netinst.iso
==> qemu.debian: Trying https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.1.0-amd64-netinst.iso?checksum=sha256%3A9f181ae12b25840a508786b1756c6352a0e58484998669288c4eec2ab16b8559
==> qemu.debian: https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.1.0-amd64-netinst.iso?checksum=sha256%3A9f181ae12b25840a508786b1756c6352a0e58484998669288c4eec2ab16b8559 => /home/carsten/.cache/packer/dced31146371c3392eb605a2c5ae08eb97048d9e.iso
==> qemu.debian: Starting HTTP server on port 8432
==> qemu.debian: Found port for communicator (SSH, WinRM, etc): 4341.
==> qemu.debian: Looking for available port between 5900 and 6000 on 127.0.0.1
==> qemu.debian: Starting VM, booting from CD-ROM
==> qemu.debian: Waiting 10s for boot...
==> qemu.debian: Connecting to VM via VNC (127.0.0.1:5984)
==> qemu.debian: Typing the boot commands over VNC...
qemu.debian: Not using a NetBridge -- skipping StepWaitGuestAddress
==> qemu.debian: Using SSH communicator to connect: 127.0.0.1
==> qemu.debian: Waiting for SSH to become available...
==> qemu.debian: Connected to SSH!
==> qemu.debian: Provisioning with Ansible...
qemu.debian: Not using Proxy adapter for Ansible run:
qemu.debian: Using ssh keys from Packer communicator...
==> qemu.debian: Executing Ansible: ansible-playbook -e packer_build_name="debian" -e packer_builder_type=qemu -e packer_http_addr=10.0.2.2:8432 --ssh-extra-args '-o IdentitiesOnly=yes' --extra-vars ansible_password=***** -i /tmp/packer-provisioner-ansible1226677173 /home/carsten/source/nomad/packer/ansible/debian.yaml
qemu.debian:
qemu.debian: PLAY [Perform image setup] *****************************************************
qemu.debian:
qemu.debian: TASK [Gathering Facts] *********************************************************
qemu.debian: ok: [default]
qemu.debian:
qemu.debian: TASK [Append to kernel parameters] *********************************************
qemu.debian: changed: [default]
qemu.debian:
qemu.debian: TASK [Slurp grub file] *********************************************************
qemu.debian: ok: [default]
qemu.debian:
qemu.debian: TASK [debug] *******************************************************************
qemu.debian: ok: [default] => {
qemu.debian: "msg": [
qemu.debian: "# If you change this file, run 'update-grub' afterwards to update\n# /boot/grub/grub.cfg.\n# For full documentation of the options in this file, see:\n# info -f grub -n 'Simple configuration'\n\nGRUB_DEFAULT=0\nGRUB_TIMEOUT=5\nGRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`\nGRUB_CMDLINE_LINUX_DEFAULT=\"quiet\"\nGRUB_CMDLINE_LINUX=\"console=ttyS0,115200\"\n\n# If your computer has multiple operating systems installed, then you\n# probably want to run os-prober. However, if your computer is a host\n# for guest OSes installed via LVM or raw disk devices, running\n# os-prober can cause damage to those guest OSes as it mounts\n# filesystems to look for things.\n#GRUB_DISABLE_OS_PROBER=false\n\n# Uncomment to enable BadRAM filtering, modify to suit your needs\n# This works with Linux (no patch required) and with any kernel that obtains\n# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)\n#GRUB_BADRAM=\"0x01234567,0xfefefefe,0x89abcdef,0xefefefef\"\n\n# Uncomment to disable graphical terminal\n#GRUB_TERMINAL=console\n\n# The resolution used on graphical terminal\n# note that you can use only modes which your graphic card supports via VBE\n# you can see them in real GRUB with the command `vbeinfo'\n#GRUB_GFXMODE=640x480\n\n# Uncomment if you don't want GRUB to pass \"root=UUID=xxx\" parameter to Linux\n#GRUB_DISABLE_LINUX_UUID=true\n\n# Uncomment to disable generation of recovery mode menu entries\n#GRUB_DISABLE_RECOVERY=\"true\"\n\n# Uncomment to get a beep at grub start\n#GRUB_INIT_TUNE=\"480 440 1\"\n"
qemu.debian: ]
qemu.debian: }
qemu.debian:
qemu.debian: TASK [update grub] *************************************************************
qemu.debian: changed: [default]
qemu.debian:
qemu.debian: PLAY RECAP *********************************************************************
qemu.debian: default : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
qemu.debian:
==> qemu.debian: Halting the virtual machine...
==> qemu.debian: Converting hard drive...
==> qemu.debian: Error getting file lock for conversion; retrying...
Build 'qemu.debian' finished after 7 minutes 26 seconds.
==> Wait completed after 7 minutes 26 seconds
==> Builds finished. The artifacts of successful builds are:
--> qemu.debian: VM files in directory: output