Creating The Perfect Software Development Environment: Day 04

Sharing

Now that we have a working Vagrant box, we need to share it with others. Vagrant Cloud is a public repository where you can publish your boxes, making available to your team. You'll need to create an account before we can proceed. You also need to create an access token that Packer can use to publish your box.

Vagrant Cloud Post-Processor

Currently, our Packer descriptor has a single entry in post-processors section, telling Packer to create a Vagrant box. We'll be adding a second entry: Vagrant Cloud. After the Vagrant box is created, this post-processor will push it to repository. Our updated Packer descriptor looks like this. Notice how it is referencing some variables, which means we'll need to add those as well.


"variables": {
    "ssh_name"            : "vagrant",
    "ssh_pass"            : "vagrant",
    "virtualbox_appliance": "bionic-beaver.ova",
    "version": "0.0.0",
    "comment": "Test of Vagrant Cloud upload.",
    "cloud_user": "{{env `VAGRANT_CLOUD_ACCOUNT`}}",
    "cloud_token": "{{env `VAGRANT_CLOUD_TOKEN`}}"
},

"post-processors": [
    [
        {
            "compression_level": 9,
            "keep_input_artifact": false,
            "output": "vagrant/bionic-xubuntu.box",
            "type": "vagrant"
        },
        {
            "access_token": "{{user `cloud_token`}}",
            "box_tag": "{{user `cloud_user`}}/bionic-xubuntu",
            "type": "vagrant-cloud",
            "version": "{{user `version`}}",
            "version_description": "{{user `comment`}}"
        }
    ]
]
            

Instead of hard coding our Vagrant Cloud username and access token, we tell Packer to fetch those values from the environment, helping to ensure that you don't accidentally leak credentials to GitHub.

Publishing The Box

Before we can publish to Vagrant Cloud, we need to create the repository. If you forget this step, the post-processor will fail saying the the box is not accessable.

Create the repository.
Create the new Vagrant Cloud repository.
Empty repository.
The empty repository.

Everything we need to push our box is in place, so let's give a test. We run the same commands as last time to verify the descriptor and run the build:


Template validated successfully.
virtualbox-ovf output will be in this color.

==> virtualbox-ovf: Downloading or copying OVF/OVA
    virtualbox-ovf: Downloading or copying: file:///home/rkurr/GitHub/packer-xubuntu-bionic/bionic-beaver.ova
==> virtualbox-ovf: Importing VM: /home/rkurr/GitHub/packer-xubuntu-bionic/bionic-beaver.ova
==> virtualbox-ovf: Creating forwarded port mapping for communicator (SSH, WinRM, etc) (host port 3836)
==> virtualbox-ovf: Executing custom VBoxManage commands...
    virtualbox-ovf: Executing: modifyvm packer-bionic-xubuntu --vram 32
    virtualbox-ovf: Executing: modifyvm packer-bionic-xubuntu --memory 2048
    virtualbox-ovf: Executing: modifyvm packer-bionic-xubuntu --cpus 1
==> virtualbox-ovf: Starting the virtual machine...
==> virtualbox-ovf: Waiting 30s for boot...
==> virtualbox-ovf: Typing the boot command...
==> virtualbox-ovf: Waiting for SSH to become available...
==> virtualbox-ovf: Connected to SSH!
==> virtualbox-ovf: Uploading VirtualBox version info (5.2.10)
==> virtualbox-ovf: Gracefully halting virtual machine...
==> virtualbox-ovf: Preparing to export machine...
    virtualbox-ovf: Deleting forwarded port mapping for the communicator (SSH, WinRM, etc) (host port 3836)
==> virtualbox-ovf: Exporting virtual machine...
    virtualbox-ovf: Executing: export packer-bionic-xubuntu --output output-virtualbox-ovf/packer-bionic-xubuntu.ova
==> virtualbox-ovf: Deregistering and deleting imported VM...
==> virtualbox-ovf: Running post-processor: vagrant
==> virtualbox-ovf (vagrant): Creating Vagrant box for 'virtualbox' provider
    virtualbox-ovf (vagrant): Unpacking OVA: output-virtualbox-ovf/packer-bionic-xubuntu.ova
    virtualbox-ovf (vagrant): Renaming the OVF to box.ovf...
    virtualbox-ovf (vagrant): Compressing: Vagrantfile
    virtualbox-ovf (vagrant): Compressing: box.ovf
    virtualbox-ovf (vagrant): Compressing: metadata.json
    virtualbox-ovf (vagrant): Compressing: packer-bionic-xubuntu-disk001.vmdk
==> virtualbox-ovf: Running post-processor: vagrant-cloud
==> virtualbox-ovf (vagrant-cloud): Verifying box is accessible: kurron/bionic-xubuntu
    virtualbox-ovf (vagrant-cloud): Box accessible and matches tag
==> virtualbox-ovf (vagrant-cloud): Creating version: 0.0.0
==> virtualbox-ovf (vagrant-cloud): Creating provider: virtualbox
==> virtualbox-ovf (vagrant-cloud): Preparing upload of box: vagrant/bionic-xubuntu.box
==> virtualbox-ovf (vagrant-cloud): Uploading box: vagrant/bionic-xubuntu.box
    virtualbox-ovf (vagrant-cloud): Depending on your internet connection and the size of the box,
    virtualbox-ovf (vagrant-cloud): this may take some time
    virtualbox-ovf (vagrant-cloud): Uploading box, attempt 1
    virtualbox-ovf (vagrant-cloud): Box successfully uploaded
==> virtualbox-ovf (vagrant-cloud): Releasing version: 0.0.0
    virtualbox-ovf (vagrant-cloud): Version successfully released and available
Build 'virtualbox-ovf' finished.

==> Builds finished. The artifacts of successful builds are:
--> virtualbox-ovf: 'virtualbox' provider box: vagrant/bionic-xubuntu.box
--> virtualbox-ovf: 'virtualbox': kurron/bionic-xubuntu
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'bionic-xubuntu' (v0) for provider:
    box: Unpacking necessary files from: file:///home/rkurr/GitHub/packer-xubuntu-bionic/vagrant/bionic-xubuntu.box
==> box: Successfully added box 'bionic-xubuntu' (v0) for 'virtualbox'!
bionic-xubuntu        (virtualbox, 0)
kurron/xenial-xubuntu (virtualbox, 5.2.6)
xenial-server-bare    (virtualbox, 0)
xenial-server-docker  (virtualbox, 0)
xenial-xubuntu        (virtualbox, 0)

Once your box has been pushed, you should see it in your Vagrant Cloud account.

Image published.
Successful publication.

Conclusion

We've learned the basics of creating our very own Vagrant box. The next thing we need to learn is how to customize it to our liking, prior to publication.

Full Packer File


{
    "description": "Builds a Xubuntu 18.04 desktop box with various software development tools installed",
    "min_packer_version": "1.2.3",

    "variables": {
        "ssh_name"            : "vagrant",
        "ssh_pass"            : "vagrant",
        "virtualbox_appliance": "bionic-beaver.ova",
        "version": "0.0.0",
        "comment": "Test of Vagrant Cloud upload.",
        "cloud_user": "{{env `VAGRANT_CLOUD_ACCOUNT`}}",
        "cloud_token": "{{env `VAGRANT_CLOUD_TOKEN`}}"
    },

    "builders": [{
        "type"        : "virtualbox-ovf",
        "source_path" : "{{user `virtualbox_appliance`}}",
        "ssh_username": "{{user `ssh_name`}}",
        "ssh_password": "{{user `ssh_pass`}}",

        "boot_wait": "30s",
        "format": "ova",
        "guest_additions_mode": "disable",
        "headless": false,
        "keep_registered": false,
        "shutdown_command": "sudo shutdown --poweroff now",
        "shutdown_timeout": "2m",
        "skip_export": false,
        "output_directory": "output-virtualbox-ovf",
        "vboxmanage": [
		        ["modifyvm", "{{.Name}}", "--vram", "32"],
		        ["modifyvm", "{{.Name}}", "--memory", "2048"],
		        ["modifyvm", "{{.Name}}", "--cpus", "1"]
	      ],
          "vm_name": "packer-bionic-xubuntu"
    }],
    "provisioners": [],
    "post-processors": [
        [
            {
                "compression_level": 9,
                "keep_input_artifact": false,
                "output": "vagrant/bionic-xubuntu.box",
                "type": "vagrant"
            },
            {
                 "access_token": "{{user `cloud_token`}}",
                 "box_tag": "{{user `cloud_user`}}/bionic-xubuntu",
                 "type": "vagrant-cloud",
                 "version": "{{user `version`}}",
                 "version_description": "{{user `comment`}}"
            }
        ]
    ]
}