cloud-init: Creating a Classic Snap

21 April 2017
cloud-init snap classic


Snaps are a a fast, easy, and safe way of packaging software. While I had some experience earlier in 2016 trying to snap up Weka and a few other projects I wanted to see how snaps have changed since then. Given my work on cloud-init and the fact that it does not yet have a snpacraft.yaml I wanted to attempt to snap it.

Classic Confinement

The snap team recently announced the availability of a security policy that allows for greater access of the entire host system called classic confinement. One of the key selling points of snaps is the ability to restrict what a snap has access to on a system. In fact by default, it has access to nothing. However, there are tools and scripts that need access to the greater system.

Cloud-init is a perfect example of a software package needing access to the greater system given the setup and configuration it accomplishes. As such I decided to give making cloud-init a classic confinement snap.


The final snpacraft.yaml was merged into the repo in mid-April 2017 and is below. Read through it and then read below for a greater description of each part:

name: cloud-init
version: master
summary: Init scripts for cloud instances
description: |
  Cloud instances need special scripts to run during initialization to
  retrieve and install ssh keys and to let the user run various scripts.
grade: stable
confinement: classic

    # LP: #1669306
    command: usr/bin/python3 $SNAP/bin/cloud-init

    plugin: python
    source-type: git


The first six keys I generally refer to as metadata. The name, summary, and description are self-explanatory.

The version is master for two reasons: 1) as the parts section specifies the snapcraft checks out from master and 2) prevents the need to update the version in yet another place.

The grade is stable over devel as it was, albeit briefly, tested and not really under any further development.

The confinement as I alluded to above, is classic to take advantage of the additional system access.


I only expose a single app, namely cloud-init. Traditionally this should be as simple as specifying the command bin/cloud-init, however I quickly learned that it would not be so easy. Due to LP: #1669306 I was required to specify the python3 path. This is due to the classic confinement option being so new and still working out some of the experience.


The parts section is very straight forward, but required a great deal of consideration and a small change to cloud-init.

Cloud-init as a python based project with a obviously will use the python plugin, but not without a small change. The python plugin expects that running python install does not expect any required parameters. In cloud-init, we used to expect the init system as an option like python install --init-system=systemd. In order to get past this, if no init system is specified systemd will be used by default.

There was a brief debate on how to setup the source: either clone master each time or use the local directory. Due to the fact that the snapcraft.yaml file is kept in the git repository it seems redundant to specify the source as a git repo leading to two git checkouts.

Ultimately I choose to specify the git repo in order to prevent any accidental or untested local changes from making their way into a snap and to by default snap what is committed into master. Of course this is not prevent someone from locally modifying the value to ‘.’ or specifying a branch, but sets up what I believe to be sane and safe defaults.

Build & Install

At this point all that is left is to build and install the snap. Build of a classic confinement snap required installing the core snap, which I did not already have and then running snapcraft.

Install of the actual snap required adding a new option to allow the classic confinement.

sudo snap install core
git clone git+ssh://
cd cloud-init
sudo snap install cloud-init_master_amd64.snap --classic --dangerous


A brief video showing the snap installed and running a few basic commands:


cloud-init 18.3 Released

20 June 2018
cloud-init ubuntu

Using cloud-init with Multipass

30 March 2018
cloud-init multipass user-data

cloud-init 18.2 Released

28 March 2018
cloud-init ubuntu
comments powered by Disqus