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
- ssh/authorized_keys so they can log in configure
ssh private keys add ssh keys to user’s .
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:
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.
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
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.
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.
starts with “#cloud-boothook” or “
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)
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
The user data script starts with: “#!” or “Content-Type: text/x-shellscript”script will run at the “rc.local-like” level
Upstart work starts with “#upstart-job” or “
The part handler starts with “#part-handler” or “
of user data scripting
As popularized by alestic.com, 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.
$ cat myscript.sh #!/bin/sh echo “Hello World. The time is now $(date -R)!” | tee /root/output.txt $ euca-run-instances -key mykey -user-data-file myscript.sh 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
- used Additional apt fonts must be added Certain
- SSH keys
must be imported The file
a valid yaml
Here are some simple examples of what can be done with cloud-config syntax
: Run ‘
apt-get upgrade’ on first boot
enable byobu by default for all system users
import ssh keys for launchpad user
‘smoser’ and add his ppa #cloud-config ssh_import_id: [smoser] apt_sources: – source: “ppa: smoser/ppa”
first boot The result of these commands will appear in the console output
#cloud-config runcmd: – [ wget, “http://slashdot.org”, -O, /tmp/index.html ] – [ sh, -xc, “echo $(date) ‘: hello world!'” ]
#cloud-config apt_upgrade: true
#cloud-config byobu_by_default: system
execute some commands on
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 http://www.ubuntu.com/robots.txt http://www.w3schools.com/html/lastpage.htm $ cat my-upstart-job.txt description “a test upstart job” start on stopped rc RUNLEVEL= 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.
- .txt.i containing the post-processed user data (uncompressed, with includes resolved). A ‘/var/lib/cloud/data/user-data.txt.i
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
- 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
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: