Packer CentOS Virtualbox image
SATA Wanted
Many of the public CentOS Vagrant boxes are configured with only an IDE controller. I assume this is for compatibility reasons. The SATA controller on VirtualBox performs better, so that is what I want.
Like a real SATA controller, Oracle VM VirtualBox’s virtual SATA controller operates faster and also consumes fewer CPU resources than the virtual IDE controller. Also, this enables you to connect up to 30 virtual hard disks to one machine instead of just three, when compared to the Oracle VM VirtualBox IDE controller with a DVD drive attached.
Getting started
To start the process of building your Vagrant box using Packer, create a working directory. Within that directory create the Packer template. The Packer template, which I named centos-7.7-x86_64.json
, is a file that describes how to build the image.
Packer Template
Within the JSON
file we define the builder type virtualbox-iso. This builder will create a new image from an ISO file. Here is where we can define the hard_drive_interface as SCSI.
hard_drive_interface (string) - The type of controller that the primary hard drive is attached to, defaults to ide. When set to sata, the drive is attached to an AHCI SATA controller. When set to scsi, the drive is attached to an LsiLogic SCSI controller.
centos-7.7-x86_64.json
The information about the Packer template configuration options are detailed in the docs.
{% raw %}
{
"builders": [
{
"type": "virtualbox-iso",
"guest_os_type": "RedHat_64",
"iso_url": "{{user `mirror`}}/7/isos/x86_64/CentOS-7-x86_64-NetInstall-1908.iso",
"iso_checksum": "{{user `iso_checksum`}}",
"iso_checksum_type": "{{user `iso_checksum_type`}}",
"output_directory": "output-centos-7.7-x86_64-{{build_type}}",
"vm_name": "packer-centos-7.7-x86_64",
"disk_size": "{{user `disk_size`}}",
"hard_drive_discard": "{{user `hard_drive_discard`}}",
"hard_drive_nonrotational": "{{user `hard_drive_nonrotational`}}",
"headless": "{{user `headless`}}",
"hard_drive_interface": "{{user `hard_drive_interface`}}",
"http_directory": "http",
"boot_wait": "5s",
"boot_command": [
"<esc>",
"<wait>",
"linux inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg biosdevname=0 net.ifnames=0",
"<enter>"
],
"ssh_timeout": "{{user `ssh_timeout`}}",
"ssh_username": "vagrant",
"ssh_password": "vagrant",
"ssh_pty": true,
"shutdown_command": "sudo systemctl poweroff",
"vboxmanage": [
["modifyvm", "{{.Name}}", "--memory", "{{user `memory`}}"],
["modifyvm", "{{.Name}}", "--cpus", "{{user `cpus`}}"],
["modifyvm", "{{.Name}}", "--nic1", "nat", "--nictype1", "virtio"]
]
}
],
"provisioners": [
{
"type": "shell",
"scripts": [
"scripts/sshd.sh",
"scripts/virtualbox.sh",
"scripts/cleanup.sh"
]
}
],
"post-processors": [
{
"type": "vagrant",
"compression_level": "{{user `compression_level`}}",
"output": "centos-7.7-x86_64-{{.Provider}}.box"
}
],
"variables": {
"compression_level": "6",
"cpus": "1",
"disk_size": "8000",
"hard_drive_discard": "true",
"hard_drive_interface": "sata",
"hard_drive_nonrotational": "true",
"headless": "true",
"iso_checksum": "6ffa7ad44e8716e4cd6a5c3a85ba5675a935fc0448c260f43b12311356ba85ad",
"iso_checksum_type": "sha256",
"memory": "512",
"mirror": "http://mirror.lug.udel.edu/pub/centos",
"ssh_timeout": "60m"
}
}
{% endraw %}
Validate the contents of the json file packer validate <template>
.
➜ packer validate .\centos-7.7-x86_64.json
Template validated successfully.
CentOS kickstart file
Documentation and example kickstart files can be found online. This file will install CentOS with configuration to fit my needs.
- Install a minimal set of packages
- Disable firewall and SELinux
- Add and configure the Vagrant user
Warning: Recommended for local development and lab use only. This kickstart file is insecure by default. {: .flash .flash-warn }
# RHEL7 - Vagrant lab system
# Install OS instead of upgrade
install
# Keyboard layouts
keyboard 'us'
# After installation reboot
reboot
# Root password
rootpw --plaintext vagrant
# Use text mode install
text
firstboot --disable
# Setup network interface
network --device=eth0 --bootproto=dhcp --onboot=yes --activate
# Install from an installation tree on a remote server
# Required when using a miniml ISO
url --mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
# Set repo to mirror.centos.org
repo --name="CentOS" --baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/ --cost=100
repo --name="Updates" --baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/ --cost=100
repo --name="epel" --baseurl=https://download.fedoraproject.org/pub/epel/7/x86_64/ --cost=100
# System language
lang en_US.UTF-8
# Logging
logging --level=debug
# System timezone
timezone --utc Etc/UTC
# Firewall
firewall --disable
# SELinux
selinux --permissive
# Accept EULA
eula --agreed
# Services
services --enabled=ntpd,ntpdate
# Add Vagrant user
user --name=vagrant --plaintext --password=vagrant --groups=vagrant,wheel
# System bootloader configuration
bootloader --location=mbr
# Clear the Master Boot Record
zerombr
# Partition clearing information
clearpart --all --initlabel
# Automatically create partition, LVM
autopart --type=lvm
%packages --ignoremissing --excludedocs
@core
epel-release
dkms
kernel-devel
kernel-headers
make
automake
perl
gcc
gcc-c++
bzip2
which
wget
ntp
ntpdate
# mandatory packages in the @core group
-btrfs-progs
-iprutils
-kexec-tools
-plymouth
# default packages in the @core group
-*-firmware
-dracut-config-rescue
-kernel-tools
-libsysfs
-microcode_ctl
-NetworkManager*
-postfix
-rdma
%end
%post
# Apply Vagrant public key.
echo "Applying Vagrant public key"
sudo mkdir -p /home/vagrant/.ssh
sudo curl -fsSLo /home/vagrant/.ssh/authorized_keys https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant.pub
# Change owner and group on SSH authorized keys file for vagrant user
sudo chown -R vagrant:vagrant /home/vagrant/.ssh
sudo chmod 700 /home/vagrant/.ssh
sudo chmod 600 /home/vagrant/.ssh/authorized_keys
# Configure Vagrant for no password sudo
echo "Configuring Vagrant for passwordless sudo"
sudo cat > /etc/sudoers.d/vagrant <<'EOF'
Defaults:vagrant !requiretty
vagrant ALL=(ALL) NOPASSWD: ALL
EOF
# Change permissions on vagrant sudo file
sudo chmod 440 /etc/sudoers.d/vagrant
%end
Project directory
The project directory should resemble the outline below.
📦centos-packer-virtualbox
┃ ┣ 📂http
┃ ┗ 📜ks.cfg
┣ 📂scripts
┃ ┣ 📜cleanup.sh
┃ ┣ 📜sshd.sh
┃ ┗ 📜virtualbox.sh
┣ 📜.gitignore
┗ 📜centos-7.7-x86_64.json
Building the box
Once everything is in place run packer build <template>
.
➜ packer build centos-7.7-x86_64.json
virtualbox-iso output will be in this color.
...
truncated output
...
==> virtualbox-iso: Running post-processor: vagrant
==> virtualbox-iso (vagrant): Creating Vagrant box for 'virtualbox' provider
virtualbox-iso (vagrant): Copying from artifact: output-centos-7.7-x86_64-virtualbox-iso\packer-centos-7.7-x86_64-disk001.vmdk
virtualbox-iso (vagrant): Copying from artifact: output-centos-7.7-x86_64-virtualbox-iso\packer-centos-7.7-x86_64.ovf
virtualbox-iso (vagrant): Renaming the OVF to box.ovf...
virtualbox-iso (vagrant): Compressing: Vagrantfile
virtualbox-iso (vagrant): Compressing: box.ovf
virtualbox-iso (vagrant): Compressing: metadata.json
virtualbox-iso (vagrant): Compressing: packer-centos-7.7-x86_64-disk001.vmdk
Build 'virtualbox-iso' finished.
==> Builds finished. The artifacts of successful builds are:
--> virtualbox-iso: 'virtualbox' provider box: centos-7.7-x86_64-virtualbox.box
.gitignore
The packer_cache
directory contains the ISO files used for building the image. The *.box
file is the output image. These are large files that do not need to be tracked via Git. It’s recommended to exclude these items in your .gitignore
file.
# Cache objects
packer_cache/
# For built boxes
*.box