Automated OpenStack instance configuration with cloud-init and metadata service

Cloud Creator

cloud-init Config File

Five stages of cloud-init are integrated into the boot procedure:

1. Generator. In this stage, the cloud-init service is enabled by the systemd unit generator.

2. Local. The purpose of this stage is to locate local data sources (i.e., user data config files and scripts) and apply networking configuration to the system, including possible fallback to DHCP discovery.

3. Network. With networking configured on an instance, this stage runs the disk_setup and mounts modules and configures mount points.

4. Config. This stage runs modules included in the cloud_final_modules section of the cloud.cfg file.

5. Final. Executed as late as possible, this stage runs package installations and user scripts.

The main cloud-init configuration is included in the /etc/cloud/cloud.cfg file, which by default comprises the following sections:

  • cloud_init_modules (e.g., growpart, resizefs, set_hostname, ssh)
  • cloud_config_modules (e.g., mounts, set-passwords, package-update-upgrade-install)
  • cloud_final_modules (e.g., scripts-per-instance, scripts-user, power-state-change)
  • system_info (e.g., default_user, distro, paths)

As you have probably noticed, the names of the module sections largely correspond to the mentioned cloud-init boot stages. What is most important here is that the cloud_final_modules section contains the scripts-user task, which allows you to inject customized configuration data to the instance during the final cloud-init stage.

Passing User Data to the Instance

User data can be passed to the instance by adding it as a parameter during instance launch. A number of file types are supported:

  • GZIP-compressed content
  • MIME multipart archive
  • User data script
  • cloud-config file
  • Upstart job
  • Cloud boothooks
  • Part handler (contains custom code for new MIME types in multipart user data)

In the example here, I present the most common file types used in OpenStack for user data injection – that is, the cloud-config file and user data scripts.

cloud-config File

The cloud-config file is most likely the fastest and easiest way to pass user data to an instance. It has a clear and human-readable format and basically the same syntax as the cloud.cfg configuration file. Listing 3 shows an example cloud-config file that creates an additional user, executes a command on first boot, upgrades the OS, and finally installs additional packages. Please note, that a cloud-config file must use valid YAML syntax and must begin with #cloud-config; otherwise, the file won't be readable by a cloud-init script.

Listing 3

cloud-config File

#cloud-config
# create additional user
users:
  - default
  - name: test
    gecos: Test User
    sudo: ALL=(ALL) NOPASSWD:ALL
# run command on first boot
bootcmd:
  - echo 192.168.2.99 myhost >> /etc/hosts
# upgrade OS on first boot
package_upgrade: true
# install additional packages
packages:
  - vim
  - epel-release

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

[root@controller ~(keystone_gjuszczak)]# openstack server create --flavor m2.tiny --image CentOS_7_cloud_init --nic net-id=int_net --key-name cloud --security-group default --user-data cloud-config CentOS_7_CI_CC

As soon as the instance is up and running and a floating IP is assigned, you can log in and monitor the cloud-init log (Listing 4) – probably while some cloud-config tasks are still running.

Listing 4

Sample cloud-init Log

[centos@centos-7-ci-cc ~]$ sudo tail -f /var/log/cloud-init.log
...
2018-10-17 21:54:06,826 - helpers.py[DEBUG]: Running config-package-update-upgrade-install using lock (<FileLock using file '/var/lib/cloud/instances/21697d2c-fcdd-4c36-ba88-275b78e546a7/sem/config_package_update_upgrade_install'>)
...
2018-10-17 21:54:06,988 - helpers.py[DEBUG]: Running update-sources using lock (<FileLock using file '/var/lib/cloud/instances/21697d2c-fcdd-4c36-ba88-275b78e546a7/sem/update_sources'>)
...
2018-10-17 21:54:07,006 - util.py[DEBUG]: Running command ['yum', '-t', '-y', 'makecache'] with allowed return codes [0] (shell=False, capture=False)
...
2018-10-17 22:00:06,125 - util.py[DEBUG]: Running command ['yum', '-t', '-y', 'upgrade'] with allowed return codes [0] (shell=False, capture=False)

If you are not sure what kind of user data has been injected into the instance, you can always display the contents of the /var/lib/lib/cloud/instance/ directory, which includes user data in the user-data.txt file, as well as the time the final stage ended, stored in the boot-finished file.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus