Skip to content

Introduction

Could-init provides a method to customize any Linux distribution instance during the initialization process. By adding cloud-init user-data to your instance, you can perform some actions such as adding users, injecting SSH keys, installing packages and other system configurations.

Note: When configuring cloud-init directly for an instance, keep in mind that cloud-init runs only on the first start of the instance. That means that you must configure cloud-init before you start the instance.

Step 1 - Creating cloud-init configuration file

The cloud-init options require YAML’s style format. In this example, an Ubuntu 22.04 instance is being customized.

#cloud-config
users:
  - name: clouduser
    groups: sudo
    shell: /bin/bash
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDLFFx4fLeNeLLJnhGaiWkaXGXNibwYvn4BdU3GXYvSLSN5poSRwtkcgswn+sdfasdfasfsaf3FVEDASFSADF/fwtt6Z+0t8ua4bC7hVhmVo1k3pDlg1iPqAx4bO0/IO/CleYciDayrA5LiDrlnM0Ok+F4k26ACV5YXYeHrhd0wBQ4RmNqCoG0iaEW5Ff2nUwgm15guPFREXHP+AQ3gT0+1bNyThUiW93qwStDL226l652U6TpYLznf3TatfOclgffc634234afPRaHp9xk4Fu94cUGNN2eJQiy9RZPOcYew4u0LDZBEKzDO97ycQdk5+P3243+F8sNl8gqCIXzDldJ7ZmusbBUaPyBYBIyGGUoh880Qqsin0CAs+LUP8bS0l7+hjcchvjzfBAcbJQ4d0k8GkWZs5p5S5wLmQUdN1odpgkSVS97q1aNjuUTAe0GQMjEyn2sfu0MAixr+flkTdihA8CnE=
package_update: true
package_upgrade: true
package_reboot_if_required: true
timezone: UTC
packages:
  - python3-pip
  - python3-venv
runcmd:
  - cd /root/
  - python3 -m venv env
  - pip install ansible
  - echo 192.168.1.100 breqwatr-deploy >> /etc/hosts
write_files:
  - path: /root/.bashrc
    content: |
      source /root/env/bin/activate

Explanation

Note: Use the correct YAML syntax, which is how cloud-init is expressed, otherwise it would result in errors during the launching process.

#cloud-config

This is the first line (#cloud-config) indicating that is a cloud-config file which is used by the cloud-init during the initialization process.

Create Users

In the example below, there are some options that you can use when creating a user.

users:
  - name: breqwatr
    groups: sudo
    shell: /bin/bash
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDLFFx4fLeNeLLJnhGaiWkaXGjBkMK1DXNibwYvn4BdU3GXYvSLSN5poSRwtkcgswn+G6wWbb16BdNvWyf4rYqhUWWF1OBODYfy77kwY8Se/fwtt6Z+0t8ua4bC7hVhmVo1k3pDlg1iPqAx4bO0/IO/CleYciDayrA5LiDrlnM0Hr8Q+Ok+F4k26ACV5YXYeHrhd0wBQ4RmNqCoG0iaEW5Ff2nUwgm15guPFREXHP+AQ3gT0+1bNyThUiW93qwStDL226l652U6TpYLznf3cQqcI/qnNzfeQjpTatfOclgffc6DtD/PRaHp9xk4Fu94cUGNN2eJQiy9RZPOcYew4u0LDZBEKzDO97ycQdk5+P/xJ+F8sNl8gqCIXzDldJ7ZmusbBUaPyBYBIyGGUoh880Qqsin0CAs+LUP8bS0l7+hjcchvjzfBAcbJQ4d0k8GkWZs5p5S5wLmQUdN1odpgkSVS97q1aNjuUTAe0GQMjEyn2sfu0MAixr+flkTdihA8CnE= ruth@MacBook-Pro.local
  • name: Specify the username.
  • groups: Add breqwatr user to the required groups. By default, new users are not added to additional groups.
  • shell: The login shell for the created user (default: sh shell).
  • sudo: Set the user's sudo rights.
  • ssh-authorized-keys: A list of SSH keys that will be added to the user's authorized_keys file.
Update and Upgrade

The package update and upgrade options are equivalent to apt-get update and apt-get upgrade respectively.

package_update: true
package_upgrade: true
package_reboot_if_required: true
Change TimeZone

To set the instance's time zone automatically, use the timezone directive.

timezone: UTC
Install Packages

Declare the packages that are not usually installed by default on Ubuntu distribution.

packages:
  - python3-pip
  - python3-venv
Run commands

Specify any commands you would like to run during the launching process. In this example, there are commands to create a virtual environment, install Ansible using pip and inject an IP address entry in the host file.

runcmd:
  - cd /root/
  - python3 -m venv env
  - pip install ansible
  - echo 192.168.1.100 breqwatr-deploy >> /etc/hosts
Write files

You can write or make changes to existing or new configuration or regular files by supplying the new values. Also, you have the options to specify the owner and permissions set on the file.

write_files:
  - path: /root/.bashrc
    content: |
      source /root/env/bin/activate

Finally, save the cloud-init config file for example user-data.yaml and use it in the --user-data openstack's argument.

Step 2 - Launching the instance in OpenStack

To launch an instance with cloud-config user data, you need to modify your openstack server create command slightly by adding the user-data argument:

openstack server create --flavor medium-1 --volume ubuntu-boot --network private-net --user-data user-data.yaml ubuntu

Step 3 - Verifying the status and logs

To verify if cloud-init file work correctly, you can perform the following steps:

  • SSH or Log into the new instance and type:
cloud-init status

output

status: done

  • Review the logs located at:

/var/log/cloud-init.log: By default, all cloud-init events with a priority of debug or higher, are written to cloud-init.log. This provices verbose logs of every event that ocurred during cloud-init initialization. In many cases cloud-init will have run OS commands or performed provisioning operations prior to the error, which can provide insights as to why errors appeared in the logs.

/var/log/cloud-init-output.log: You can get information from the stdout and stderr during the stages of cloud-init. This normally involves routing table information, networking information, ssh host key verification information, stdout and stderr for each stage of cloud-init, along with the timestamp for each stage.