1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
---
discourse: 12559
relatedlinks: https://cloudinit.readthedocs.org/
---
(cloud-init)=
# How to use `cloud-init`
```{youtube} https://www.youtube.com/watch?v=8OCG15TAldI
```
[`cloud-init`](https://cloud-init.io/) is a tool for automatically initializing and customizing an instance of a Linux distribution.
By adding `cloud-init` configuration to your instance, you can instruct `cloud-init` to execute specific actions at the first start of an instance.
Possible actions include, for example:
* Updating and installing packages
* Applying certain configurations
* Adding users
* Enabling services
* Running commands or scripts
* Automatically growing the file system of a VM to the size of the disk
See the {ref}`cloud-init:index` for detailed information.
```{note}
The `cloud-init` actions are run only once on the first start of the instance.
Rebooting the instance does not re-trigger the actions.
```
## `cloud-init` support in images
To use `cloud-init`, you must base your instance on an image that has `cloud-init` installed, which is the case for all images from the `ubuntu` and `ubuntu-daily` {ref}`image servers <remote-image-servers>`.
However, images for Ubuntu releases prior to `20.04` require special handling to integrate properly with `cloud-init`, so that `lxc exec` works correctly with virtual machines that use those images. Refer to {ref}`vm-cloud-init-config`.
## Configuration options
LXD supports two different sets of configuration options for configuring `cloud-init`: `cloud-init.*` and `user.*`.
Which of these sets you must use depends on the `cloud-init` support in the image that you use.
As a rule of thumb, newer images support the `cloud-init.*` configuration options, while older images support `user.*`.
However, there might be exceptions to that rule.
The following configuration options are supported:
* `cloud-init.vendor-data` or `user.vendor-data` (see {ref}`cloud-init:vendordata`)
* `cloud-init.user-data` or `user.user-data` (see {ref}`cloud-init:user_data_formats`)
* `cloud-init.network-config` or `user.network-config` (see {ref}`cloud-init:network_config`)
For more information about the configuration options, see the [`cloud-init` instance options](instance-options-cloud-init), and the documentation for the {ref}`LXD data source <cloud-init:datasource_lxd>` in the `cloud-init` documentation.
### Vendor data and user data
Both `vendor-data` and `user-data` are used to provide {ref}`cloud configuration data <explanation/format:cloud config data>` to `cloud-init`.
The main idea is that `vendor-data` is used for the general default configuration, while `user-data` is used for instance-specific configuration.
This means that you should specify `vendor-data` in a profile and `user-data` in the instance configuration.
LXD does not enforce this method, but allows using both `vendor-data` and `user-data` in profiles and in the instance configuration.
If both `vendor-data` and `user-data` are supplied for an instance, `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 {ref}`cloud-init:merging_user_data` for instructions.
## How to configure `cloud-init`
To configure `cloud-init` for an instance, add the corresponding configuration options to a {ref}`profile <profiles>` that the instance uses or directly to the {ref}`instance configuration <instances-configure>`.
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.
To do so, create the instance with `lxc init` instead of `lxc launch`, and then start it after completing the configuration.
### YAML format for `cloud-init` configuration
The `cloud-init` options require YAML's [literal style format](https://yaml.org/spec/1.2.2/#812-literal-style).
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.
The `vendor-data` and `user-data` options usually start with `#cloud-config`.
For example:
```yaml
config:
cloud-init.user-data: |
#cloud-config
package_upgrade: true
packages:
- package1
- package2
```
```{tip}
See {doc}`cloud-init:howto/debug_user_data` for information on how to check whether the syntax is correct.
```
## How to check the `cloud-init` status
`cloud-init` runs automatically on the first start of an instance.
Depending on the configured actions, it might take a while until it finishes.
To check the `cloud-init` status, log on to the instance and enter the following command:
cloud-init status
If the result is `status: running`, `cloud-init` is still working. If the result is `status: done`, it has finished.
Alternatively, use the `--wait` flag to be notified only when `cloud-init` is finished:
```{terminal}
:input: cloud-init status --wait
:user: root
:host: instance
.....................................
status: done
```
## How to specify user or vendor data
The `user-data` and `vendor-data` configuration can be used to, for example, upgrade or install packages, add users, or run commands.
The provided values must have a first line that indicates what type of {ref}`user data format <cloud-init:user_data_formats>` is being passed to `cloud-init`.
For activities like upgrading packages or setting up a user, `#cloud-config` is the data format to use.
The configuration data is stored in the following files in the instance's root file system:
* `/var/lib/cloud/instance/cloud-config.txt`
* `/var/lib/cloud/instance/user-data.txt`
### Examples
See the following sections for the user data (or vendor data) configuration for different example use cases.
You can find more advanced {ref}`examples <cloud-init:yaml_examples>` in the `cloud-init` documentation.
#### Upgrade packages
To trigger a package upgrade from the repositories for the instance right after the instance is created, use the `package_upgrade` key:
```yaml
config:
cloud-init.user-data: |
#cloud-config
package_upgrade: true
```
#### Install packages
To install specific packages when the instance is set up, use the `packages` key and specify the package names as a list:
```yaml
config:
cloud-init.user-data: |
#cloud-config
packages:
- git
- openssh-server
```
#### Set the time zone
To set the time zone for the instance on instance creation, use the `timezone` key:
```yaml
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 the commands as a list:
```yaml
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 {ref}`cloud-init:reference/examples:including users and groups` example in the `cloud-init` documentation for details about default users and which keys are supported.
```yaml
config:
cloud-init.user-data: |
#cloud-config
user:
- name: documentation_example
```
## How to specify network configuration data
By default, `cloud-init` configures a DHCP client on an instance's `eth0` interface.
You can define your own network configuration using the `network-config` option to override the default configuration (this is due to how the template is structured).
`cloud-init` then renders the relevant network configuration on the system using either `ifupdown` or `netplan`, depending on the Ubuntu release.
The configuration data is stored in the following files in the instance's root file system:
* `/var/lib/cloud/seed/nocloud-net/network-config`
* `/etc/network/interfaces.d/50-cloud-init.cfg` (if using `ifupdown`)
* `/etc/netplan/50-cloud-init.yaml` (if using `netplan`)
### Example
To configure a specific network interface with a static IPv4 address and also use a custom name server, use the following configuration:
```yaml
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
```
|