Skip to content

grahamprimm/ansible-packer

 
 

Repository files navigation

Ansible Packer Role for VM/ISO Creation

License: GPLv2 License: GPLv3

Ansible role for building VM images with Packer.

Also supports creating custom ISO installer images.

Introduction

This role builds custom Linux and Windows VM template images using Packer. OS installation parameters are provided as Ansible variables to allow for high degree of customizations. Same customizations can be applied to both VM template images and unattended BIOS/UEFI-compatible ISO installer images.

See this example how a playbook could look like.

Currently (2022-04) tested Packer builders (platforms) are:

Currently tested OS variants and versions are:

VM images are prepared for imaging at the end of automated installation, RHEL with kickstart post-scripts and Windows with sysprep.

VM images can also be further customized and updated automatically at the end of the installation by using the Packer Ansible provisioner. VMware VM images are VMware Tools enabled so the hypervisor can customize the OS in VMs created from these images.

Both RHEL and Windows custom ISO installer images embed and load the installer configuration automatically on boot to proceed to install the OS completely unattended.

Less tested but verified to work in the past OS variants include:

Quick Usage Example

To build an image install Packer on a build host, install this role, and run a playbook as shown below.

After Packer installation, install this role:

mkdir roles
cat << EOF > roles/requirements.yml
---
roles:
  - src: https://github.com/myllynen/ansible-packer.git
    type: git
    version: master
EOF
ansible-galaxy role install -p roles -r roles/requirements.yml

Then, create a playbook to use this role.

This is a basic playbook for building an image with Qemu:

---
- name: Build image with Packer on Qemu
  hosts: all
  vars:
    packer_binary: packer.io
    packer_builder: qemu
    packer_target: rhel_8
    disk_size: 8192

    root_password: "{{ image_password }}"
    partitioning: auto

    hostname: localhost.localdomain
    ntp_servers: time.cloudflare.com
    timezone: Europe/Helsinki
    keyboard: fi

    # Builder: qemu
    # https://www.packer.io/docs/builders/qemu
    qemu_binary: /usr/libexec/qemu-kvm
    output_directory: /tmp/packer_images

    #
    # OS installer configuration
    #
    iso:
      rhel_8:
        url: file:///VirtualMachines/boot/rhel-8.5-x86_64-dvd.iso
        checksum: sha256:1f78e705cd1d8897a05afa060f77d81ed81ac141c2465d4763c0382aa96cadd0

  roles:
    - ansible-packer

This is a more complete playbook for building an image on VMware:

---
- name: Build image with Packer on VMware vSphere
  hosts: all
  vars:
    #
    # Base configuration
    #
    packer_binary: /usr/local/sbin/packer.io
    packer_builder: vmware
    packer_target: rhel_8_5
    image_name: rhel8-template
    disk_size: 30720

    do_cleanup: true
    use_force: true

    #
    # OS configuration
    #
    boot_password: "{{ image_password }}"
    root_password: "{{ image_password }}"
    partitioning: auto
    disable_ipv6: true
    #security_profile: cis_server_l1
    boot_parameters: net.ifnames.prefix=net quiet systemd.show_status=yes

    hostname: localhost.localdomain
    ntp_servers: time.cloudflare.com
    timezone: Europe/Helsinki
    keyboard: fi

    create_admin: true
    admin_user:
      uid: 4444
      gid: 4444
      name: admin
      group: admin
      groups: wheel
      home: /home/admin
      gecos: Admin User
      ssh_key: "ssh-rsa ... admin@image"
      passwordless_sudo: true

    root_permit_local: true
    root_permit_ssh: "no"

    custom_packages: |
      cloud-init
      cloud-utils-growpart

    # Builder: vmware
    # https://www.packer.io/docs/builders/vsphere/vsphere-iso
    #vcenter_credentials:
    #  vcenter_server: vcenter.example.com
    #  vcenter_username: vcuser
    #  vcenter_password: vcpass
    vcenter_insecure_connection: false
    vcenter_datacenter: DC1
    vcenter_folder: Linux/templates
    vcenter_cluster: DC1-C1
    vcenter_datastore: DC1-C1-LUN-1
    vcenter_network: DC1-C1-VLAN-123
    vcenter_convert_to_template: true

    #
    # OS installer configuration
    #
    iso:
      rhel_8_5:
        url: file:///VirtualMachines/boot/rhel-8.5-x86_64-dvd.iso
        checksum: sha256:1f78e705cd1d8897a05afa060f77d81ed81ac141c2465d4763c0382aa96cadd0

  roles:
    - ansible-packer

See the example playbook for more complete example and defaults/main for all the supported variables.

Finally, build image on a build host:

# Build latest RHEL 8 image with playbook defaults
ansible-playbook -c local -i localhost, packer.yml \
  -e packer_target=rhel_8

# Build RHEL 8.5 image on VMware vSphere with customizations
ansible-playbook -i 192.168.122.123, -u builder packer.yml \
  -e packer_builder=vmware -e packer_target=rhel_8_5 \
  -e bios_uefi_boot=true -e partitioning=single \
  -e disable_ipv6=true -e security_profile=cis_server_l1 \
  -e image_name=test_image

Custom ISO Installer Image Creation

A custom ISO can be used to perform unattended OS installation based on the configuration provided in a playbook. User would then only need to provide the correct IP address (RHEL) for the host on the boot prompt if not using DHCP (Windows). For the RHEL installer (Anaconda) the static network boot parameter format is ip=ip::gateway:netmask:hostname:interface:none, see RHEL documentation for more details.

A playbook to build custom ISO is almost identical to the above playbooks used to build OS images with Packer:

---
- name: Build custom ISO
  hosts: all
  vars:
    # Using packer_ variables for compatibility,
    # genisoimage not Packer used to build image
    packer_builder: iso
    packer_target: rhel_8_5
    packer_target_pretty: Custom RHEL 8.5
    image_name: custom.iso

    root_password: "{{ image_password }}"
    partitioning: auto

    hostname: localhost.localdomain
    ntp_servers: time.cloudflare.com
    timezone: Europe/Helsinki
    keyboard: fi

    # Builder: ISO (not a Packer builder)
    iso_boot_parameters: inst.geoloc=0 ip=dhcp
    output_directory: /tmp/iso_images

    iso:
      rhel_8_5:
        url: file:///VirtualMachines/boot/rhel-8.5-x86_64-dvd.iso
        checksum: sha256:1f78e705cd1d8897a05afa060f77d81ed81ac141c2465d4763c0382aa96cadd0

  roles:
    - ansible-packer

To build custom ISO on a build host:

# Build latest RHEL 8 image with playbook defaults
ansible-playbook -c local -i localhost, build_iso.yml \
  -e image_password=foobar

Role Description

Ansible role to allow for quickly building of RHEL, Windows, and other OS images with Packer using either Qemu or VMware vSphere as builders.

Linux builds do not save cleartext passwords on disk at any point, however Windows unattend files do have cleartext passwords in them. This is unavoidable as the Windows installer does not support encrypted passwords.

Three paramaters, packer_builder, packer_target and root_password for Linux or win_winrm_password for Windows are mandatory, the rest are optional. See defaults/main for all the supported variables.

See defaults/main/content_iso.yml how to define OS versions and ISO locations.

See defaults/main/builder_qemu.yml and defaults/main/builder_vmware.yml for Packer builder related variables and their default values. ISO related variables are in defaults/main/builder_iso.yml.

Create BIOS/UEFI bootable image by setting bios_uefi_boot to true, otherwise the VM image supports only the platform used for building the image.

See the provided partitioning alternatives at templates/cfg-rhel_8.j2, specify custom_partition and set partitioning: custom to use custom partitioning layout.

The value of security_profile is passed as-is to the Linux installer OpenSCAP module.

To create local admin user on the VM for Ansible etc, see defaults/main/os.yml for admin user data specification (Linux). Windows admin user is winrm, see defaults/main/windows.yml for details.

Vaulted password variables are supported. Note that the provided CentOS templates do not support all the variables as the latest RHEL templates.

Additionally, -e do_cleanup=true will delete anything left behind on the build host by earlier builds. Using -e use_force=true adds the -force parameter to the Packer command line.

See Also

See also https://github.com/myllynen/rhel-image.

See also https://github.com/myllynen/rhel-ansible-roles.

See also https://github.com/myllynen/windows-ansible-roles.

License

GPLv2+

About

Ansible Packer Role for VM/ISO Creation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Jinja 96.7%
  • Shell 3.3%