Just like Docker or Kubernetes, Vagrant also uses initial “images” to create VMs, but in the case of Vagrant, called Box. Creating base images, with certain customized configurations, is a common practice, even in clouds like Azure or AWS. As this is an example of a personal Lab, and it would be financially unfeasible to create so many VMs in a cloud, of course, I use VMs in Vagrant.

All hosts that I create in Vagrant, from now on, that the services are more stabilized and a new server has been configured, will be created with a customized image/box, with some configurations and must be updated with the Lab logo.

The first configuration I will do is, in addition to apt upgrade, enable SSH and create a default user for administration/SSH, which will be used by Ansibles.

The first step to creating a base image/box is, of course, choosing an OS. I have been using Ubuntu 22.04 until now: “bento/ubuntu-22.04

Create a Vagrant VM with as little as possible, you don’t need any additional configuration at this point, such as network, DNS, etc.

Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.define "base-image-ubuntu", autostart: true do |base_ubuntu|
    base_ubuntu.vm.box = "bento/ubuntu-22.04"
    base_ubuntu.vm.hostname = 'base-image-ubuntu'
  end
end

Create the VM and access it with ssh.

$ vagrant up

#######################################################################################################################

$ vagrant ssh
vagrant@base-image-ubuntu:~$ sudo -s

The next steps will be to create a user, usr_linuxadmin with the password sg8BnHlWpkoQlLwmAZPePZ9JnLgwDffjIKTcLwP1NXCN5L2tms and give it sudo permissions.

Next, I enable SSH and upgrade the OS.

It is important to say that usermod expects an encrypted password, unlike many internet pages show with plain text, before applying the password, we need to encrypt it, check man usermod.

To make things easier and to ensure you have the correct standards, use openssl passwd for this, in the example below I use SHA512 (parameter -6).

In the usermod manual, there is an instruction that it is not advisable to use this method, as the password is identified in the /etc/passwd or /etc/passwd file, even if encrypted.

If you really don’t want this to happen, then the method is to add the user with adduser and apply the password manually. Since it’s not a process that needs to be done so many times, it’s up to you.

sudo useradd -p $(openssl passwd -6 sg8BnHlWpkoQlLwmAZPePZ9JnLgwDffjIKTcLwP1NXCN5L2tms) usr_linuxadmin -e '' -g 'sudo' -m -s /bin/bash
sudo sed -i 's/\#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config
sudo apt update
sudo apt upgrade -y

If you want to do some checks on user creation:

$ sudo cat /etc/passwd | grep usr_linuxadmin
usr_linuxadmin:x:1001:27::/home/usr_linuxadmin:/bin/bash
#######################################################################################################################

$ sudo cat /etc/shadow | grep usr_linuxadmin
usr_linuxadmin:$6$q9iO96PGwZVE1Mjj$38UHPROVMNp.xcewKxTIhe.lLFq3Wi2N.ETdlRWhttNauCaKxdbkRo/8/OGJXDOuPH05VRu4vsawkbm5czX7./:19872:0:99999:7:::
#######################################################################################################################

$ chage -l usr_linuxadmin
Last password change                                    : May 29, 2024
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 7

Now, exit the VM and return to the host, let’s create the Box, this process may take a few minutes and consume some resources.

$ vagrant package --output base-image-ubuntu.box  

==> base-image-ubuntu: Attempting graceful shutdown of VM...
==> base-image-ubuntu: Clearing any previously set forwarded ports...
==> base-image-ubuntu: Exporting VM...
==> base-image-ubuntu: Compressing package to: /work/teste/base-image-ubuntu.box

Check that a large file was created in the Vagrantfile folder, with the box extension. This is your Vagrant image/box.
Ideally, it should be stored in a repository, fileshare, artifacts, etc.

$ ll
-rw-r--r--  1 faustobranco faustobranco 1.8G May 29 10:03 base-image-ubuntu.box

The next step is to validate the Boxes installed in Vagrant, in the example below I only have the Box that I always use, bento/ubuntu-22.04.

$ vagrant box list
bento/ubuntu-22.04 (virtualbox, 202404.23.0, (amd64))

Now, let’s import the box created into Vagrant and name it base-ubuntu-1.0.0.

$ vagrant box add base-ubuntu-1.0.0 base-image-ubuntu.box --force

==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'base-ubuntu-1.0.0' (v0) for provider:
    box: Unpacking necessary files from: file:///work/teste/base-image-ubuntu.box
==> box: Successfully added box 'base-ubuntu-1.0.0' (v0) for ''!

Check again:

$ vagrant box list
base-ubuntu-1.0.0  (virtualbox, 0)
bento/ubuntu-22.04 (virtualbox, 202404.23.0, (amd64))

Application of the new box.

With the base box ready, let’s create a test Vagrant with this new image.

See that the testvm.vm.box parameter is already the new Box: “base-ubuntu-1.0.0

Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.define "srv-infrastructure-test-master-01", autostart: true do |testvm|
    testvm.vm.box = "base-ubuntu-1.0.0"
    testvm.vm.hostname = 'srv-infrastructure-test-master-01'

    testvm.vm.network "public_network", use_dhcp_assigned_default_route: true, bridge: "enp7s0", ip: "172.21.5.157"
    testvm.vm.synced_folder "/work/", "/work"
    testvm.vm.provider :virtualbox do |v|
        v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
        v.customize ["modifyvm", :id, "--memory", 1024]
        v.customize ["modifyvm", :id, "--name", "srv-infrastructure-test-master-01"]
    end
  end
end

After the already known vagrant up and vagrant ssh:

$ sudo cat /etc/passwd | grep usr_linuxadmin
usr_linuxadmin:x:1001:27::/home/usr_linuxadmin:/bin/bash
#######################################################################################################################

$ sudo cat /etc/shadow | grep usr_linuxadmin
usr_linuxadmin:$6$q9iO96PGwZVE1Mjj$38UHPROVMNp.xcewKxTIhe.lLFq3Wi2N.ETdlRWhttNauCaKxdbkRo/8/OGJXDOuPH05VRu4vsawkbm5czX7./:19872:0:99999:7:::

Exit the VM and test the SSH connection:

$ ssh usr_linuxadmin@172.21.5.157

usr_linuxadmin@172.21.5.157's password:
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-107-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Wed May 29 01:55:58 PM UTC 2024

  System load:  0.08               Processes:             147
  Usage of /:   14.5% of 30.34GB   Users logged in:       1
  Memory usage: 25%                IPv4 address for eth0: 10.0.2.15
  Swap usage:   0%


This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
Last login: Wed May 29 13:55:58 2024 from 172.21.5.76


usr_linuxadmin@srv-infrastructure-test-master-01:~$ sudo -s


root@srv-infrastructure-test-master-01:/home/usr_linuxadmin#

Done!