Boot with Cloud-Init

Overview

Cloud-init is a software package that automates the initialization of servers during system boot. When you deploy a new Linux server from an image, cloud-init gives you the option to set default user data.

User data must be written in shell scripts or cloud-config directives using YAML syntax. You can modify IONOS cloud-init's behavior via user-data. You can pass the user data in various formats to the IONOS cloud-init at launch time. Typically, this happens as a template, a parameter in the CLI, etc. This method is highly compatible across platforms and fully secure.

Compatibility: This service is supported on all public IONOS Cloud Linux distributions. You may submit user data through the DCD or via Cloud API. Existing cloud-init configurations from other providers are compatible with IONOS Cloud.

Limitations: Cloud-init is available on all public Linux images supplied by IONOS Cloud. If you wish to use your own Linux image, please make sure that it is cloud-init supported first. Otherwise, there is no guarantee that the package will function as intended. Windows images are currently out of scope; adding them may be considered at a later stage.

Provisioning: Cloud-init can only be set at initial provisioning. It cannot be applied to instances that have already been provisioned. Settings cannot be changed once provisioned.

Laptops: When using a laptop, scroll down the properties panel of the block storage volume that you want to create and configure, as additional fields are not immediately visible on a small screen. Clout-Init may only become visible when an supported image has been selected.

Supported user data formats

The following table demonstrates the use of cloud-config and user-data scripts. However, the cloud-init package supports a variety of formats.

Data FormatDescription

Base64

If the user data is base64 encoded, cloud-init verifies whether the decoded data is one of the supported types. It decodes and handles the decoded data appropriately if it comprehends it. If not, the base64 data is returned unaltered.

User-Data Script

Begins with #! or Content-Type: text/x-shellscript. The script is run by /etc/init.d/cloud-init-user-scripts during the first boot cycle. This occurs late in the boot process after the initial configuration actions are performed.

Include File

Begins with #include or Content-Type: text/x-include-url. The include file is the content. It contains a collection of URLs, one in each line. Each URL is read, and its content passes through the same set of rules. The content read from the URL can be MIME-multi-part or plaintext.

Cloud Config data

Begins with #cloud-config or Content-Type: text/cloud-config. For a commented example of supported configuration formats, see the examples.

Upstart Job

Begins with #upstart-job or Content-Type: text/upstart-job. This content is stored within a file in /etc/init, and upstart uses the content similar to other upstart jobs.

Cloud Boothook

Begins with #cloud-boothook or Content-Type: text/cloud-boothook. The boothook data is the content, which is stored in a file within /var/lib/cloud and executed immediately. This becomes the earliest hook and does not have any mechanism for executing it only one time. The must be handled by the boothook itself. It is provided with the instance ID in the environment variable INSTANCE_ID. Use this variable to provide a once-per-instance set of boothook data.

Configuring user data via the DCD

  1. Log in to the DCD with your username and password.

  2. In the Workspace, create a new virtual instance and attach any storage device to it.

  3. Select the storage device and from the Inspector pane associate an Image with it.

    • To associate a private image, select Own Images from the drop-down list.

    • To associate a public image, select IONOS Images from the drop-down list. Once you choose an image, additional fields will appear in the Inspector pane.

  1. Enter a Password. It is required for Remote Console access. You may change it later.

  2. (Optional) Upload a new SSH key or use an existing file. SSH Keys can also be injected as user data utilizing cloud-init.

  3. (Optional) Add a specific key to the Ad-hoc SSH Key field.

  4. Select No configuration for Cloud-Init user data and the Cloud-Init User Data window appears.

  5. Enter your User Data either using a bash script or a cloud-config file with a YAML syntax. For sample scripts, see Use shell scripts, Use cloud-config directives, and Configure user data via API.

  1. To complete setup, return to the Inspector pane and click Provision Changes.

Result: At boot, Cloud-Init executes automatically and applies the specified changes. The DCD returns a message when provisioning is complete, indicating that the infrastructure is virtually ready. However, bootstrapping, which includes the execution of cloud-init data, may require additional time. The message that DCD returns does not mention the additional time required for execution. We recommend allowing extra time for task completion before testing.

Use shell scripts

Using shell scripts is an easy way to bootstrap a server. The code creates, installs, and configures our CentOS web server in the following example. It also rewrites the default index.html file.

Note: Allow enough time for the instance to launch and run the commands in your script, and later verify if your script has completed the tasks you intended.

#!/bin/bash
# Use this for your user data (script from top to bottom)
# install httpd (Linux 2 version)
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello World from $(hostname -f)</h1>" > /var/www/html/index.html

To test if the cloud-init bootstrapped your VM successfully, you can open the corresponding IP address in your browser. You will be greeted with a “Hello World” message from your web server.

Use cloud-config directives

You can also bootstrap cloud-init images using cloud-config directives. The cloud-init website outlines all the supported modules and provides examples of basic directives.

Example 1: Create a swap partition

The following script is an example of how to create a swap partition with second block storage using a YAML script:

#cloud-config
fs_setup:
  - label: mylabel
    device: /dev/vda
    filesystem: ext4
  - label: swap
    device: /dev/vdb
    filesystem: swap
mounts:
- [ /dev/vda, /, ext4, defaults, 0, 0 ]
- [ /dev/vdb, none, swap, sw, 0, 0 ]

Example 2: Resize the file system

The following script is an example of how to resize your file system according to the chosen size of the block storage. It will also create a user with an SSH key using a cloud-config YAML script:

#cloud-config
resize_rootfs: True
users:
  - name: pb-user
    gecos: Demo User
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: users, admin
    ssh_import_id: None
    lock_passwd: true
    ssh_authorized_keys:
      - ssh-rsa AAAA...

Output log files

The cloud-init output log file (/var/log/cloud-init-output.log) captures console output. Depending on the default configuration for logging, a second log file exists within /var/log/cloud-init.log. This provides a comprehensive record based on the user data.

Configure user data via API

The cloud API offers increased convenience if you want to automate the provisioning and configuration of cloud instances. Enter the following details:

  • Name: Enter the userData.

  • Type: Enter the type in the form of a string.

  • Description: The cloud-init configuration for the volume as base64 encoded string. The property is immutable and is only allowed to be set on a new volume creation. It is mandatory to provide either public image or imageAliasthat has cloud-init compatibility in conjunction with this property.

Cloud-init is configured on the volume resource for cloud API V6 or later versions. For more information, see CLOUD API (6.0).

Curl example

The following script is an example of how to configure userData using curl:

curl --include \
     --request POST \
     --user '<user:password>' \
     --header "Content-Type: application/json" \
     --data-binary '{
         "properties": {
             "name": "Server-01",
             "ram": 2048,
             "cores": 1,
             "availabilityZone": "ZONE_1",
             "cpuFamily": "INTEL_SKYLAKE"
         },
         "entities": {
             "volumes": {
                 "items": [ {
                    "properties": {
                      "size": 10,
                      "type": "HDD",
                      "name": "Server-01_HDD",
                      "image": "bf4d1400-b48d-11eb-b9b3-d2869b2d44d9",
                      "imagePassword": "<pAsSW0rD>",
                      "sshKeys": ["<ssh_key>"],
                      "userData": "I2Nsb3VkLWNvbmZpZwoKcGFja2FnZXM6CiAgLSBodHRwZAogIC0gZmlyZXdhbGxkCgpydW5jbWQ6CiAgLSAvYmluL3N5c3RlbWN0bCBlbmFibGUgaHR0cGQKICAtIC9iaW4vc3lzdGVtY3RsIHN0YXJ0IGh0dHBkCiAgLSAvYmluL2ZpcmV3YWxsLW9mZmxpbmUtY21kIC0tYWRkLXBvcnQ9ODAvdGNwCiAgLSAvYmluL3N5c3RlbWN0bCBlbmFibGUgZmlyZXdhbGxkCiAgLSAvYmluL3N5c3RlbWN0bCBzdGFydCBmaXJld2FsbGQKICAtIGxvYWRrZXlzIGRlCgp3cml0ZV9maWxlczoKLSBjb250ZW50OiB8CiAgICA8IURPQ1RZUEUgaHRtbD4KICAgIDxodG1sPgogICAgICA8aGVhZD4KICAgICAgPC9oZWFkPgogICAgICA8Ym9keT4KICAgICAgICA8cD5XZWxjb21lIHRvIHlvdXIgbmV3IHdlYiBzZXJ2ZXIuPC9wPgogICAgICA8L2JvZHk+CiAgICA8L2h0bWw+CiAgcGF0aDogL3Zhci93d3cvaHRtbC9pbmRleC5odG1sCgpmaW5hbF9tZXNzYWdlOiAiVGhlIHN5c3RlbSBpcyBmaW5hbGx5IHVwLCBhZnRlciAkVVBUSU1FIHNlY29uZHMiCg=="
                    }
                 } ]
             },
             "nics": {
                 "items": [ {
                    "properties": {
                      "name": "NIC001",
                      "dhcp": true,
                      "lan": 1
                      }
                    } ]
             }
        }
        }' \
 https://api.ionos.com/cloudapi/v6/datacenters/<datacenter_id>/servers

Last updated