Cloud-init is a popular way to automate deployments of instances in a cloud or none cloud environment. To save having to repeat tasks, we can configure Cloud-init modules or Cloudinit script to set up networking, configure hostnames or even IP addresses. Snippets are used with the information required and Cloud-init makes the required changes. In this guide, we’re going to go through some Cloud-init modules that are appended to the Cloud-init configuration file located at /etc/cloud/cloud.cfg in Cloud Operating System images.
We have already covered how to create Cloud Operating Systems in the link above. Although aimed at Proxmox environments, it can be used to create Cloud images for any platform that utilizes Cloud-init. The guide above shows you how to edit the /etc/cloud/cloud.cfg file before creating an image. So first, open up the cloud.cfg file on any Cloud image. We are using the stock Ubuntu 22 LTS image.
cd /root
# Download a cloud image
wget https://cloud-images.ubuntu.com/jammy/20220622/jammy-server-cloudimg-amd64.img
# Set editor to use nano
export EDITOR=nano
# Use virt-edit to edit the image
virt-edit -a jammy-server-cloudimg-amd64.img /etc/cloud/cloud.cfg
So now in the console, you should be looking at the default cloud-init configuration file. Your file will likely look a bit different because we have already edited this to create an Ubuntu 22 image for use on the Discovery NVMe VPS network.

Cloud-init Modules
At the end of this file, we add further modules to expand what Cloud-init will do during boot. Let’s look at some modules.
bootcmd
bootcmd can be used to perform tasks that can’t be run later in the build process. This example set’s up our hostname in the /etc/hosts file. You shouldn’t use bootcmd to perform tasks like updates. That is done later in the build process.
- Runs: Always
- Support By: All Distributions
bootcmd:
- echo 168.115.114.0 uk.f2h.cloud > /etc/hosts
Timezone
The timezone Cloud-init module can be used to set a specific timezone in the instance.
- Runs: Always
- Support By: All Distributions
timezone: Europe/London
Write Files
The write files module can be used to append text to file or write new files on startup. This is useful if you want to add cron jobs, place a script in a specific directory or create an Apache Virtual Host for example.
- Runs: One Per instance
- Support By: All Distributions
# Add cron job to crontab
write_files:
- content: |
0/5 * * * * root sh /path/to/script.sh
path: /etc/crontab
append: true
# Create Apache virtual host
write_files:
- path: /etc/apache2/sites-available/f2h.conf
content: |
server {
server_name f2h.com www.f2h.com;
listen 80;
root /home/local;
location / {
try_files $uri $uri/ $uri.html =404;
}
}
owner: 'nginx:nginx'
permissions: '0640'
defer: true
Keyboard
The Keyboard module is used to set a different keyboard. So that’s very useful if you have users who use a different layout other than the default QWERTY. You use codes to set the layout.
- Runs: One per instance
- Support By: All Distributions

keyboard:
layout: uk
Power State Change
We can use the Power State Cloud-init module to perform tasks related to boots and reboots. The module directs the instance to reboot after X seconds. But there isn’t really any need for this because you can end up in an endless reboot loop. So if you need to reboot to apply updates. You can use the package_reboot_if_required statement.
- Runs: Always
- Support By: All Distributions
# Only reboot if package updates demand it
package_reboot_if_required: True
# Reboot after 30 seconds
power_state:
delay: 30
mode: reboot
message: Rebooting
condition: true
# Power off straight away and display message "Powering off"
power_state:
delay: now
mode: poweroff
message: Powering off
timeout: 2
condition: true
ResizeFS Cloud-init Script
ResizeFS will expand a root partition to use all of the available space. So imagine your instance has 100GB of space. You add a further 100GB. You have a total of 200GB but at the moment, only 100GB is available to use. ResizeFS will automatically expand your 100GB root partition to 200GB. ResizeFS blocks the boot process until it has completed its task.
- Runs: Always
- Support By: All Distributions
# Disable automatic resize.
resize_rootfs: false
# Enable automatic HDD resize in the background
resize_rootfs: noblock
Final Message
The final message cloud-init script will print a message to the console once Cloud-init has completed all tasks.
- Runs: Always
- Support By: All Distributions
# Basic Message
final_message: This F2H instance is ready for production.
# Advanced with switches
final_message: |
This F2H instance is ready for production.
version: $version
timestamp: $timestamp
datasource: $datasource
uptime: $uptime
So these are just a few of the less common Cloudinit modules you can use to automate tasks at startup. Sometimes it may be better to use a SystemD service and bash script to run at startup other than cloud-init.
A full list of Cloudinit modules and Cloud-init script can be found using the Cloud-init module reference guide.
How was this article?
You might also like
More from Dedicated Servers
Enable Mod_RemoteIP – See Visitors Real IP address when using Cloudflare & Apache
If you are using Cloudflare on your Apache server you will always see Cloudflare IPs in your logs and not …
Fix 413 Request Entity Too Large Errors When Using NGINX
Just like Apache, NGINX imposes default limits on the size of files that can be uploaded. A 413 Request Entity …
Install Ioncube Loaders In Ubuntu, Debian, CentOS and AlmaLinux
Ioncube Loaders are a piece of software that is used to protect the underlying code in PHP applications. Its aim …