Ubuntu 20.04 Vagrant with Packer
Ubuntu have recently released the new 20.04 LTS codenamed “Focal Fossa”. I’d also recently seen a tool that piqued my interest, Hashicorp Packer. Packer builds machine images that can be deployed to a cloud or as a virtual machine, or just even a plain disk image. You can even generate many images at once, really simplfying deployment. Very handy if you wanted to create virtual machines for a cluster for example, with a similar but slightly different configuration.
I decided to take Packer for a spin and try create a virtual machine image for Virtualbox/Vagrant that can easily be spun up for any project. Firstly you’ll need to install Virtualbox and then Vagrant on your machine. Next install Packer.
Then create directories:
$ mkdir ubuntu ubuntu/http ubuntu/output ubuntu/scripts
$ cd ubuntu
http
will hold our configuration files for Ubuntu, output
will store our
disk image we build and scripts
will hold any scripts we want to run.
Ubuntu 20.04 has a new way to automate installs (they used to use debian preseed files) - they now use a yaml file (also see their handy quickstart on which I based the below file), so we’ll need to create it:
$ cat > http/user-data << 'EOF'
#cloud-config
autoinstall:
version: 1
locale: en_US
keyboard:
layout: en
variant: uk
identity:
hostname: vagrant
password: '$2y$12$zfS.Dpm682guriw6fJ5PXu4Kv7GSs7VYHUPGphQdSnT0wb4Rt1tVS'
username: vagrant
ssh:
install-server: true
EOF
$ touch http/meta-data
As you can see, we set a hostname, username, password - all the normal things
you would need to set up. We should now have two files - http/user-data
containing our setup information and also http/meta-data
.
Next, we should set up our script(s) - we’ll setup just one for now:
$ cat > scripts/init.sh << 'EOF'
#!/bin/bash
sudo apt update
sudo apt upgrade -y
EOF
Finally, we should set up our Packer configuration file (config options for virtualbox explained here and for vagrant options):
{% raw %}
$ cat > ubuntu2004.json << 'EOF'
{
"builders": [
{
"name": "ubuntu-2004",
"type": "virtualbox-iso",
"guest_os_type": "ubuntu-64",
"headless": false,
"iso_url": "http://releases.ubuntu.com/20.04/ubuntu-20.04-live-server-amd64.iso",
"iso_checksum": "caf3fd69c77c439f162e2ba6040e9c320c4ff0d69aad1340a514319a9264df9f",
"iso_checksum_type": "sha256",
"ssh_username": "vagrant",
"ssh_password": "vagrant",
"ssh_handshake_attempts": "20",
"http_directory": "http",
"memory": 1024,
"boot_wait": "5s",
"boot_command": [
"<enter><enter><f6><esc><wait> ",
"autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/",
"<enter>"
],
"shutdown_command": "echo 'vagrant'|sudo -S shutdown -P now",
"guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso",
"virtualbox_version_file": ".vbox_version",
"vm_name": "packer-ubuntu-20.04-amd64",
"vboxmanage": [
[
"modifyvm",
"{{.Name}}",
"--memory",
"1024"
],
[
"modifyvm",
"{{.Name}}",
"--cpus",
"1"
]
]
}
],
"provisioners": [
{
"type": "shell",
"script": "scripts/init.sh",
"execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E bash '{{.Path}}'"
},
{
"type": "shell",
"script": "scripts/cleanup.sh",
"execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E bash '{{.Path}}'"
}
],
"post-processors": [{
"type": "vagrant",
"compression_level": "8",
"output": "output/ubuntu-20.04.box"
}]
}
EOF
{% endraw %}
Then we can build the image:
$ packer build ubuntu2004.json
And add it to Vagrant:
$ vagrant box add --name ubuntu20.04 output/ubuntu-20.04.box
Finally, in any other directory, we can create a Vagrantfile
:
$ cat > Vagrantfile << 'EOF'
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu20.04"
config.ssh.password = "vagrant"
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = false
end
end
EOF
Then lastly, all we need to do:
$ vagrant up && vagrant ssh
You should now be in your very own configured machine!
You can also reference my repository if you get stuck, it has configuration for Ubuntu 18.04 also.