CloudInit – Community Help Wiki – Ubuntu Documentation


cloud-init is the Ubuntu package that handles early initialization of a cloud instance. It is installed on the official Ubuntu Live Server images since the release of 18.04, Ubuntu Cloud Images and also on the official Ubuntu images available on EC2.

Some of the things it configures are:

  • set a default locale
  • hostname generate

  • ssh private keys add ssh keys to user’s .

  • ssh/authorized_keys so they can log in configure
  • ephemeral
  • mount points

Cloud-init’s behavior can be configured through user data. User data is passed to cloud-init by the user to the cloud provider at launch, typically as a parameter in the cloud CLI, template, or portal used to launch an instance.

User data entry formats

The user data that cloud-init will act on must be in one of the following types:

  • Gzip


    • content Content that is compressed with gzip will be decompressed. Uncompressed data will be used as if it were not compressed. Data compression is useful because user data is limited to 16384 bytes 1

  • Mime Multi Part


    • This list of rules applies to each part of this multi-part file. Using a mime-multipart file, the user can specify more than one data type. For example, you could specify both a user data script and a cloud configuration type.
  • The user data script starts with: “#!” or “Content-Type: text/x-shellscript”script will run at the “rc.local-like” level

    • during the first boot. rc.local-like stands for “very late in boot sequence” Include file starts with “#include” or “Content-Type: text/x-include-url

    • This content is an “include” file. The file contains a list of URLs, one per line. Each of the URLs will be read and their content will be passed through this same set of rules. That is, the content read from the URL can be gzipped, mime-multi-part, or plain

  • text

  • Cloud Config Data

    starts with “#cloud-config” or “

    • Content-Type: text/cloud-config”This content is “cloud-config” data. See the examples for an annotated example of supported configuration formats.

  • Upstart work starts with “#upstart-job” or “

    • Content-Type: text/upstart-job”The content is placed in a file in /etc/init, and will be consumed by upstart like any other upstart job.

  • Cloud Boothook

    starts with “#cloud-boothook” or “

    • Content-Type: text/cloud-boothook

      This content is “boothook” data. It is stored in a file under /var/lib/cloud and then executed immediately. This is the first “hook” available. Note that there is no mechanism provided to run only once. The starter hook should take care of this by itself. It is provided with the instance identifier in the environment variable “INSTANCE_ID”. This could be used to provide a ‘once per instance’ Only available on 10.10 or later (cloud-init 0.5.12 and later)

  • The part handler starts with “#part-handler” or “

    • Content-Type: text/


      This is a ‘part-handler’. It will be written to a file in /var/lib/cloud/data based on its file name. It must be Python code that contains a list_types method and a handle_type method. Once the section is read, the ‘list_types’ method will be called. You must return a list of mime types that this part handler controls. The ‘handle_type’ method should be like:

      def handle_part(data,ctype,filename,payload): # data = the cloudinit object # ctype = “__begin__”, “__end__”, or the mime type of the part being handled. # filename = the filename of the part (or a generated filename if none are present in the MIME data) # payload = the contents of the parts’

      Cloud-init will call the ‘handle_type’ method once at the beginning, once per received part, and once at the end. The ‘begin’ and ‘end’ calls are to allow the part driver to perform initialization or disassembly. There is an example in doc/examples/part-handler.txt. In addition, this blog post offers another example

of user data scripting

As popularized by, user data scripts are a convenient way to do something on the first boot of a launched instance. This input format is accepted in cloud-init and handled as you would expect. The script will be invoked at a point similar to “rc.local” in the boot sequence.

For example:

$ cat #!/bin/sh echo “Hello World. The time is now $(date -R)!” | tee /root/output.txt $ euca-run-instances -key mykey -user-data-file ami-a07d95c9

After executing the above, you can expect /root/output.txt to contain the desired text

. Cloud Config


Cloud Config is the easiest way to accomplish a few things through user data. Using cloud-config syntax, the user can specify certain things in a human-friendly format. These things include

: apt upgrade must run on first boot

  • A different apt mirror
  • must be

  • used Additional apt fonts must be added Certain
  • SSH keys
  • must be imported The file

  • must


a valid yaml


Here are some simple examples of what can be done with cloud-config syntax

: Run ‘

  • apt-get upgrade’ on first boot

  • #cloud-config apt_upgrade: true

  • enable byobu by default for all system users

  • #cloud-config byobu_by_default: system

  • import ssh keys for launchpad user

    ‘smoser’ and add his ppa #cloud-config ssh_import_id: [smoser] apt_sources: – source: “ppa: smoser/ppa”

  • execute some commands on

  • first boot The result of these commands will appear in the console output

    #cloud-config runcmd: – [ wget, “”, -O, /tmp/index.html ] – [ sh, -xc, “echo $(date) ‘: hello world!'” ]

Multipart input

A single user data format might not be enough to achieve what you want. For example, you might want to insert an upstart job and also run a user data script.

There is a tool in the

bin/ directory of cloud-utils called ‘write-mime-multipart’ that can help create multipart mime content


Consider the following example:

$ cat my-boothook.txt #!/bin/sh echo “Hello World!” echo “This will run as soon as possible in the boot sequence” $ cat my-user-script.txt #!/usr/bin/perl print “This is a user script (rc.local)\n” $ cat my-include.txt # These URLs will be read extracted if they were part of the data of the user # Comments are allowed. The format is one url per line $ cat my-upstart-job.txt description “a test upstart job” start on stopped rc RUNLEVEL=[2345] console output task script echo “====BEGIN=======” echo “HELLO From an Upstart Job” echo “=====END========” end script $ cat my-cloudconfig.txt #cloud-config ssh_import_id: [smoser] apt_sources: – source: “ppa:smoser/ppa”

Now, given the above files in the current directory, you can do

: $ ls my-boothook.txt my-include.txt my-user-script.txt my-cloudconfig.txt my-upstart-job.txt $ write-mime-multipart -output=combined-userdata.txt \ my-boothook.txt:text/cloud-boothook \ my-include.txt:text/x-include-url \ my-upstart-job.txt:text/upstart-job \ my-user-script.txt:text/x-shellscript \ my-cloudconfig.txt $ ls -l combined-userdata.txt -rw-r-r- 1 smoser smoser 1782 01/07/2010 16:08 combined-userdata.txt $ gzip combined-userdata.txt $ ls -l combined-userdata.txt.gz -rw-r-r- 1 smoser smoser 659 2010-07-01 16:08 combined-userdata.txt.gz $ euca-run-instances ami-a07d95c9 -user-data-file=combined-userdata.txt.gz

Now, when your instance starts, you will have

  • the smoser’s keys imported into ubuntu users ~/.ssh/authorized_keys. Note that I did not specify ‘-key’ on the command line, as it was not necessary. Instead, my launchpad keys were imported.
  • A root-owned file in /var/lib/cloud/data/user-data.txt containing the gzipped compressed user data. A root-owned file in /var/lib/cloud/data/user-data

  • .txt.i containing the post-processed user data (uncompressed, with includes resolved). A ‘/var/lib/cloud/data/user-data.txt.i
  • file

also note


  • Because ‘my-cloudconfig.txt’ starts with ‘#cloud-config’ we don’t need to specify the MIME type.
  • 600799 makes boothook read like a user script

More information

Video:- Introduction to

cloud-init Examples of user data for cloud-init can be viewed in the Github samples directory.

Using cloud-init with sample clouds:

  • AWS

  • Azure

  • Google Cloud

  • Multipass