Using cloud-init and uvtool to initialize cloud instances (including local Fedora/Ubuntu cloud images)

CloudInit is the defacto multi-distribution package that handles early initialization of a cloud instance. Its a kind of “chef/puppet/kickstart/anaconda” for cloud images. cloud-init behavior can be configured via user-data and injected into image from a datasource.

$ nano user-data

# User and Group Management
  - name: demo
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
      - ssh-rsa ...
  - group1
  - group2: [user1, user2]

# Change Passwords for Existing Users
  list: |
  expire: False

# Writing out arbitrary files
  - path: /test.txt
    content: |
      Here is a line.
      Another line is here.

# Run apt or yum upgrade
package_upgrade: true

# Install arbitrary packages
  - package_1
  - package_2
  - [package_3, version_num]

# Add apt repositories

# Configure instances ssh-keys
  - ssh-rsa ...

# Run Arbitrary Commands for More Control
  - [ sed, -i, -e, 's/here/there/g', some_file]
  - echo "modified some_file"
  - [cat, some_file]

# Adjust mount points mounted
 - [ ephemeral0, /mnt, auto, "defaults,noexec" ]
 - [ sdc, /opt/data ]
 - [ xvdh, /opt/data, "auto", "defaults,nobootwait", "0", "0" ]
 - [ dd, /dev/zero ]

# Shutdown or Reboot the Server
  timeout: 120
  delay: "+5"
  message: Rebooting in five minutes. Please save your work.
  mode: reboot

from cloud-init scripting and cloud config examples

Injecting depends on datasource (EC2, vSphere, …)

# amazon ec2
$ ec2-run-instances --user-data-file or via magic '' address

# config-drive: un-partitioned block device filesystem label 'config-2', see
$ mkdir -p /tmp/new-drive/openstack/latest
$ cp user_data /tmp/new-drive/openstack/latest/user_data
$ mkisofs -R -V config-2 -o data.iso /tmp/new-drive
$ rm -r /tmp/new-drive

# vSphere/No cloud
% genisoimage -o user-data.iso -rock user-data meta-data

# coreos uses config-drive, see

Fedora and Ubuntu both provide compact cloud images that are useful for spinning up small VM’s quickly (much quicker than installing from a huge ISO or even net-install).

#0 - install
$ sudo apt-get install qemu-kvm genisoimage cloud-utils | sudo yum install genisoimage qemu-kvm cloud-utils (EPEL)

#1 - download
$ export URL=""
$ export URL=""
$ export IMG=`basename $URL`
$ wget|axel $URL -o $IMG
$ [[ $IMG =~ \.xz$ ]] && xz -d $IMG

#2 - optionally (otherwise done on reads) compressed qcow file '.img' to a uncompressed qcow2 '.raw'
$ [[ $IMG =~ \.img ]] && qemu-img convert -O qcow2 $IMG $IMG\.raw

#3 - create the disk with NoCloud data on it
$ { echo instance-id: iid-local01; echo local-hostname: cloudimg; } > meta-data
$ printf "#cloud-config\npassword: passw0rd\nchpasswd: { expire: False }\nssh_pwauth: True\n" > user-data
$ export SEED="seed.img" ; cloud-localds $SEED user-data
$ export SEED="seed.iso" ; genisoimage -output $SEED -volid cidata -joliet -rock user-data meta-data

$4 - optionally, create a new qcow image to boot, backed by your original image
$ qemu-img create -f qcow2 -b $IMG\.raw boot-dist.img

#5 - boot a kvm, otionaly append '-display sdl or -display curses'
# use 'ubuntu'/'fedora' users for login
# use 'sudo loadkeys pt'
$ kvm -m 512 -drive file=boot-dist.img,if=virtio -drive file=$SEED,if=virtio \
    # (default) user-mode networking '-net user': allow outbound, needs redir for inbound
    -net nic -net user -redir :8090::80 -redir :8022::22
    # or bridged networking '-net tap': needs 'bridge-utils'
    -net nic -net tap
$ ssh -p 8022 user@localhost

from nocloud@cloud-init, UEC Images@ubuntu and Running cloud images locally

uvtool facilitates the task of generating virtual machines (VM) using the cloud images. Ubuntu 14.04 and later only.

# install
$ sudo apt-get install uvtool
$ sudo usermod -a -G libvirtd username
$ newgrp libvirtd

# download image from, filter by 'release/arch'
$ export RELEASE=utopic
$ uvt-simplestreams-libvirt sync release=$RELEASE arch=amd64

# create, connect and destroy a VM
$ uvt-kvm create --wait $RELEASE-test release=$RELEASE --password=passw0rd
# or same but using public key authentication
$ ssh-keygen -f .ssh/id_rsa ; uvt-kvm create --wait $RELEASE-test release=$RELEASE --ssh-public-key-file=.ssh/
$ uvt-kvm list
$ ssh ubuntu@`uvt-kvm ip $RELEASE-test`
$ uvt-kvm destroy $RELEASE-test

uvt-kvm create [options] hostname [filter]
'--memory/--dist/--cpu' limit resources
'--password password' alternative to public key authentication
'--run-script-once script_file' run script_file as root on the VM the first time it is booted
'--packages package_list' install the comma-separated packages on first boot

# start instance using cloudinit user-data
$ nano user-data
  ssh_enabled: True
    - htop
$ uvt-kvm create --wait $RELEASE-test --release=$RELEASE --user-data=user-data

# same but using snappy release
$ sudo apt-add-repository ppa:snappy-dev/tools ; sudo apt-get update ; sudo apt-get install uvtool
$ uvt-simplestreams-libvirt sync --snappy flavor=core release=devel
$ uvt-kvm create --wait snappy-test flavor=core
$ uvt-kvm ssh snappy-test
$ uvt-kvm destroy snappy-test

from Snappy Ubuntu Core and cloud-init


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s