Creating VM image out of thin air

thin air == access only to repo mirrors

George Shuklin
OpsOps
3 min readOct 26, 2020

--

I got a stupid problem: I need to run a VM on my hypervisor. It’s the problem because my hypervisor is very local (no Openstack infra, etc), and it’s stupid because I work in hosting company and we have trully amaizing image build/test/update pipelines for our clients, and I took a great deal of efforts in developing those.

My hypervisor host has only access to the global private network. No NAT, no internet connectivity. I got a few pro bono services (we provide them to all servers of our clients, including my own lab): DNS, NTP and mirror of Debian/Ubuntu repo. That’s all I have to use. Oh, and I have an SSH connection to the server, but you definitively don’t want to pass huge upload traffic from your machine to remote one. Moreover, it’s not very ansible-friendly (you can’t put this in a playbook without curses at a review time).

Now I need to find a way to make VM to boot out of this. 99 methods you find on the Internet says ‘download image bla-bla-bla’, or ‘run software which download image bla-bla-bla’. Nope, nope, nope. No more Internets jumping on the bed.

I was almost at the point of starting using debootstrap with thousands of following actions (install grub, make disk image, etc), when I realized, oh, I done something like this in the past. Our own pipelines for images. Of course we use diskimage-builder. Why not?

Naive run for Ubuntu has crashed, as there were few downloads required. Nope.

I found that Ubuntu has some issues with their images, and I wasn’t able to make it totally local. Good news, Debian is shining here.

The way to build images from thin air

And you have a bootable Debian image. It needs tons of tweaks, but generally, it’s the way. The image was created with zero Internet participation. Only Debian mirror was required, and that’s enough.

Now I’ll add pieces I need (like a good network configuration, etc). Diskimage-builder is unexpectedly good at doing this. The proper way it to create own elements, but I hope to deal with those pesky little issues with standard elements only.

Ansible integration

If you struggle with diskimage-builder as ‘command’ for Ansible, there is a good pattern to follow. Ansible provides ‘creates’ parameter for a ‘command’ module. By using ‘creates’ the non-idempotent command become idempotent. For example above (which is not a ‘production grade image’, but nevertheless), it would look like this:

P.S.

Some people may not realize how important this for ‘streamlined’ playbooks. If you need to depend on some ‘golden image’ on some yet-another-nexus, that’s a big burden. You need to have connectivity, you need to care about that image, etc. Using repo mirror lifts all that burden. OS giving birth to the OS using own genetic material is a class better than relying on some surrogate vagranting.

--

--

George Shuklin
OpsOps

I work at Servers.com, most of my stories are about Ansible, Ceph, Python, Openstack and Linux. My hobby is Rust.