Using cloud-init with SmartOS

SmartOS provides the ability to inject cloud-init data into a zone/VM. This is extremely useful for automating some of the menial tasks one would normally have to perform manually like setting up users, installing packages, or pulling down a git repo. Basically, anything you can stuff into cloud-init user-data is at your disposal.

However, since SmartOS zone definitions are in JSON and cloud-init data is in yaml, it’s not immediately obvious how to supply this information. What it boils down to is, escape all double-quotes (“) and line-feeds.

Here’s our cloud-init config which creates a new user and import their ssh key from


  - default
  - name: shaner
    ssh_import_id: shaner
    lock_passwd: false
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    shell: /bin/bash

So following the above escape rules above, here’s our full SmartOS zone spec, including the cloud-init data. Note the cloud-init:user-data key.

  "brand": "kvm",
  "alias": "ubuntu-xenial",
  "ram": "2048",
  "vcpus": "2",
  "resolvers": [
  "nics": [
      "nic_tag": "admin",
      "ip": "",
      "netmask": "",
      "gateway": "",
      "model": "virtio",
      "primary": true
  "disks": [
      "image_uuid": "429bf9f2-bb55-4c6f-97eb-046fa905dd03",
      "boot": true,
      "model": "virtio"
  "customer_metadata": {
    "cloud-init:user-data": "#cloud-config\n\nusers:\n  - default\n  - name: shaner\n    ssh_import_id: shaner\n    lock_passwd: false\n    sudo: \"ALL=(ALL) NOPASSWD:ALL\"\n    shell: /bin/bash"

Let’s go ahead and create the zone on our SmartOS box.

[root@vmm01 /opt/templates]# vmadm create < ubuntu-xenial.json
Successfully created VM 0e908925-600a-4365-f161-b3a51467dc08
[root@vmm01 /opt/templates]# vmadm list 
UUID                                  TYPE  RAM      STATE             ALIAS
0e908925-600a-4365-f161-b3a51467dc08  KVM   2048     running           ubuntu-xenial

After a bit of time, we can try logging in as our new user we requested. Recall, we asked cloud-init to pull in our public ssh key from launchpad so, if you get prompted for a password, something is wrong.

shaner@tp25:~$ ssh
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:hFPjwUJjd7N/Gb9EE37fTVt2Lk6NVzoLKvhFN7wYw2M.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-116-generic x86_64)
Certified Ubuntu Cloud Image

   __        .                   .
 _|  |_      | .-. .  . .-. :--. |-
|_    _|     ;|   ||  |(.-' |  | |
  |__|   `--'  `-' `;-| `-' '  ' `-'
                   /  ;  Instance (Ubuntu 16.04.3 LTS 20180222)

 * Documentation:
 * Management:
 * Support:

  Get cloud support with Ubuntu Advantage Cloud Guest:

0 packages can be updated.
0 updates are security updates.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

shaner@0b8d7a26-ffe4-e859-eb56-d96d02bf213e:~$ sudo ls
shaner@0b8d7a26-ffe4-e859-eb56-d96d02bf213e:~$ sudo apt-update &amp;&amp; sudo apt-upgrade -y

There’s a LOT you can do with cloud-init data. See the below links for more info.

Cloud-init examples:
Joyent Datasource:
Joyent Ubuntu Image documentation:

SmartOS on Alix APU2c2

Over the past few years, I’ve been using SmartOS as my hypervisor of choice coupled with a management layer called Project-Fifo. I have to say, it’s been a joy to work with.

I had a couple Alix APU’s laying around and was curious how well SmartOS would run it.

To begin, I downloaded the SmartOS USB image and pushed onto a USB drive.


bzcat smartos-latest-USB.img.bz2 | dd of=/dev/sdb conv=fdatasync

Now,  we can plug the USB drive into the USB port of our APU then power it up. Be sure to plug in your serial cable first so you can see what’s going on.

Soon as you see the GRUB boot menu, press ‘c’ enter the below to switch the console output to ttya from vga. Then hit enter.

variable os_console ttya

After doing the above, you should see something like this

And eventually this. You can now follow along and configure your new SmartMachine.

After networking is all configured, you’ll be prompted to layout a zpool on your disk (hopefully you have an m-sata installed).

Now, just hit enter and be sure to remove the USB drive so SmartOS will boot from the m-sata drive. Eventually, you’ll be presented with the login screen like the below where you can login as root using the password you provided during setup.

Okay, so let’s import a debian dataset and spin up a zone (read: container)

Define the zone config and use vmadm to create it and login!

Cool! A fully functioning Debian 9 container. Let’s setup wordpress and run a load test for funsies.


Now, let’s use Siege to perform some load testing

Not Bad!

Adding WiFi Card to Alix apu Running pfSense

I always thought it would be neat to manage my home WiFi from the same interface as the rest of my network. After eyeing the hardware for a long time and doing some research every couple months or so, I finally made the leap and purchased the necessary hardware.

As I’m using an Alix apu2c2, some initial research showed that the WLE200NX coupled with a pair of 6dBi antennas was the way to go. 

After backing up my pfSense config (ALWAYS make a backup!) I shut it down and cracked it open to install the WiFi card.

This was mostly trivial, note that we use the third (mPCIe 1) slot for this. The first slot is for an mSATA drive.

All set, ready to power up and get it configured!

Head over to Interfaces -> Assignments then down to the Wireless tab. Click Add, select the detected device and set the mode to ‘Access Point‘. Then, click Save.

Head back to Interfaces -> Assignments and create a new interface, selecting new WiFi device.


Now, click on the newly created interface (OPT1, likely) and configure it like any other interface. Note, because it’s a wireless interface, you’re presented with a LOT more options as your scroll further down. Here’s, where you configure Channel, SSID, WPA2, etc…

Once you have everything configured, head over to Services -> DHCP Server and configure the DHCP server for your new interface.

Okay, just about done. All we have to do now is let traffic pass through the interface. To do so, head over to Firewall -> Rules and click your new WiFi interface. Below, you see I just added a quick ‘Allow All’ rule to make sure everything works as expected.

Testing this with both my phone and my laptop, I couldn’t be happier with the results!