Introduction to cloud-init

This technical guide provides a general introduction to the cloud-init tool. Cloud-init is an open source tool which enables you to customize a Linux virtual machine (VM) during its first start.

For example, you can use cloud-init to install packages, write files, or configure users on the operating system or security parameters. Since cloud-init runs during the first start of the VM, no additional or manual steps are required afterward to apply the configuration.

For more information about cloud-init, see the official cloud-init documentation.

cloud-config File

A cloud-config file is a script intended to be run by the cloud-init process.

The cloud-config format uses a declarative syntax that can perform many common tasks, while keeping the flexibility of a script for more complex features.

Cloud-init is compatible with most Linux distributions. For example, you do not need to indicate specific commands such as apt-get install or yum install in your script to install a package. Instead, you can define a list of packages to install, and then cloud-init will automatically use the native package manager that corresponds to the distribution of the VM.

cloud-config YAML Format

The cloud-config file uses the YAML data-serialization format. This format was designed to be both easy to understand for humans and easy to parse for programs.

Below is an example of cloud-config file that we will analyze:

#cloud-config
users:
 - name: demo
   groups: sudo
   shell: /bin/bash
   sudo: ['ALL=(ALL) NOPASSWD:ALL']
   ssh-authorized-keys:
     - ssh-rsa
runcmd:
 - touch /test.txt

All cloud-config files must start with the mention #cloud-config. This mention indicates to the cloud-init program that the content must be interpreted like a cloud-config file. This is the equivalent, in an ordinary script, of indicating the interpreter to use to execute the file.

The file above has two top-level directives: users and runcmd. These two mentions serve as keys. The values of these keys are indicated on indented lines.

Examples of cloud-config Directives

The following examples represent some common use cases.

Other examples are included in the machine where cloud-init is installed, in the /usr/share/doc/cloud-init/examples directory.

Managing Users

To define new users in the operating system, you can use the users directive. Each new user must be preceded by a dash. For each user, parameters are set by key-value pairs:

#cloud-config
users:
 - first-user-parameter: value
   first-user-parameter: value

 - second-user-parameter: value
   second-user-parameter: value
   second-user-parameter: value

Below is an example that creates a new user named demo:

#cloud-config
users:
 - name: demo
   groups: sudo
   shell: /bin/bash
   sudo: ['ALL=(ALL) NOPASSWD:ALL']
   ssh-authorized-keys:
     - ssh-rsa

Managing Packages

To update the apt database in Debian-based distributions, you can set the package_update directive to true. This directive corresponds to an apt-get update command in the terminal. The default value for this directive is true. Therefore, you need to specify this directive only if you want to disable it:

#cloud-config
package_update: false

To upgrade all packages of the VM during the first start, you can use the package_upgrade directive. This directive corresponds to an apt-get upgrade command in the terminal. The default value for this directive is false. Therefore, make sure you set it to true if you want to enable it:

#cloud-config
package_upgrade: true

To install additional packages, you can list the package names after the packages directive. Each package of the list can take one of the following forms:

  • The package name.

  • A bracketed list with two elements. The first element is the package name and the second element is the package version number:

#cloud-config
packages:
  - package_1
  - package_2
  - [package_3, version_num]

Using the packages directive automatically sets package_update to true, even if you previously set the latter to false.

Writing Files to Disk

To write files to disk, you can use the write_files directive. The two keys required for this directive are as follows:

  • path, which specifies the location where to write the file.

  • content, the text to write in the file.

For example, if you want to write a file at the /test.txt location of the VM with the following text:

Here is a line.
Another line is here.

The part of cloud-config to specify is as follows:

#cloud-config
write_files:
  - path: /test.txt
    content: |
      Here is a line.
      Another line is here.

For a multiline text, you must type a pipe (|) on the content line, followed by a line break and your text on an indented block.

As for binary files, they must include the mention !! binary | instead of a simple pipe.

Executing Arbitrary Commands

To execute arbitrary commands, you can use the runcmd directive.

This directive takes a list of elements to execute. These elements can be specified in two ways:

  • If the element is a simple text string, the entirety of the element is transmitted to the sh shell process to execute.

  • If the element is itself a bracketed list, the first element is interpreted as the name of the command to execute while the other elements are transmitted as arguments of this command.

#cloud-config
runcmd:
 - echo "modified some_file"
 - [cat, some_file]
 - [sed, -i, -e, 's/here/there/g', some_file]

Any output will be printed to the standard output as well as the /var/log/cloud-init-output.log file of the VM.

Use of cloud-init at OUTSCALE

In OUTSCALE VMs, you must put the content of the cloud-config file in the user data of the VM in order to apply a cloud-init configuration. For more information, see Using cloud-init with User Data.

Related Pages