cloud-init#
LXD supports cloud-init via the following instance or profile configuration keys:
cloud-init.vendor-datacloud-init.user-datacloud-init.network-config
For more information, see the cloud-init instance options, and the documentation for the LXD data source in the cloud-init documentation.
Before trying to use cloud-init, however, first determine which image source you are
about to use as not all images have the cloud-init package installed.
The images from the ubuntu and ubuntu-daily remotes are all cloud-init enabled.
Images from the images remote have cloud-init enabled variants using the /cloud suffix, e.g. images:ubuntu/22.04/cloud.
Both vendor-data and user-data follow the same rules, with the following caveats:
Users have ultimate control over vendor data. They can disable its execution or disable handling of specific parts of multipart input.
By default it only runs on first boot.
Vendor data can be disabled by the user. If the use of vendor data is required for the instance to run, then vendor data should not be used.
User supplied
cloud-configis merged overcloud-configfrom vendor data.
For LXD instances, vendor-data should be used in profiles rather than the instance configuration.
Note
If both cloud-init.user-data and cloud-init.vendor-data are supplied, cloud-init merges the two configurations.
However, if you use the same keys in both configurations, merging might not be possible.
In this case, configure how cloud-init should merge the provided data.
See Merging User-Data Sections in the cloud-init documentation for instructions.
cloud-config examples can be found in the cloud-init documentation.
Working with cloud-init#
For a safe way to test, use a new profile that’s copied from the default profile.
lxc profile copy default test
Then edit the new test profile. You might want to set your EDITOR environment variable first.
lxc profile edit test
For a new LXD installation, the configuration file should look similar to this example:
config: {}
description: Default LXD profile
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
Once you’ve set up the cloud-init configuration, use lxc launch with --profile <profilename> to apply the profile to the instance.
Adding cloud-init keys to the configuration#
cloud-init keys require a specific syntax. You use a pipe symbol (|) to indicate that all indented text after the pipe should be passed to cloud-init as a single string, with new lines and indentation preserved; this is literal style format used in YAML.
config:
cloud-init.user-data: |
config:
cloud-init.vendor-data: |
config:
cloud-init.network-config: |
Custom user-data configuration#
cloud-init uses the user-data (and vendor-data) section to do things like upgrade packages, install packages or run arbitrary commands.
A cloud-init.user-data key must have a first line that indicates what type of data format is being passed to cloud-init. For activities like upgrading packages or setting up a user, #cloud-config is the data format to use.
An instance’s rootfs will contain the following files as a result:
/var/lib/cloud/instance/cloud-config.txt/var/lib/cloud/instance/user-data.txt
Upgrade packages on instance creation#
To trigger a package upgrade from the repositories for the instance, use the package_upgrade key:
config:
cloud-init.user-data: |
#cloud-config
package_upgrade: true
Install packages on instance creation#
To install specific packages when the instance is set up, use the packages key and specify the package names as a list:
config:
cloud-init.user-data: |
#cloud-config
packages:
- git
- openssh-server
Set the time zone on instance creation#
To set the time zone for the instance, use the timezone key:
config:
cloud-init.user-data: |
#cloud-config
timezone: Europe/Rome
Run commands#
To run a command (such as writing a marker file), use the runcmd key and specify commands as a list:
config:
cloud-init.user-data: |
#cloud-config
runcmd:
- [touch, /run/cloud.init.ran]
Add a user account#
To add a user account, use the user key. See the documentation for more details about default users and which keys are supported.
config:
cloud-init.user-data: |
#cloud-config
user:
- name: documentation_example
Custom network configuration#
cloud-init uses the network-config data to render the relevant network
configuration on the system using either ifupdown or netplan depending
on the Ubuntu release.
The default behavior is to use a DHCP client on an instance’s eth0 interface.
In order to change this you need to define your own network configuration
using cloud-init.network-config key in the configuration dictionary which will override
the default configuration (this is due to how the template is structured).
For example, to configure a specific network interface with a static IPv4 address and also use a custom name server use
config:
cloud-init.network-config: |
version: 1
config:
- type: physical
name: eth1
subnets:
- type: static
ipv4: true
address: 10.10.101.20
netmask: 255.255.255.0
gateway: 10.10.101.1
control: auto
- type: nameserver
address: 10.10.10.254
An instance’s rootfs will contain the following files as a result:
/var/lib/cloud/seed/nocloud-net/network-config/etc/network/interfaces.d/50-cloud-init.cfg(if usingifupdown)/etc/netplan/50-cloud-init.yaml(if usingnetplan)