Is there a way to configure lxd containers with cloud config at provision time?
So there are multiple ways you can do so, either directly for a container:
lxc init ubuntu: CONTAINER
lxc config set CONTAINER user.user-data - < cloud-init-config.yml
lxc start CONTAINER
Or even shorter:
lxc launch ubuntu: CONTAINER --config=user.user-data="$(cat cloud-init-config.yml)"
Or through a profile:
lxc profile create dev
lxc profile set dev user.user-data - < cloud-init-config.yml
lxc launch ubuntu: CONTAINER -p default -p dev
I had a slightly more specific question than the OP but it took me a while to work out what I was doing wrong. I thought I would post it here to help anyone else getting similarly stumped.
I wanted static networking settings for an LXC/LXD Ubuntu 16.04 container hosted on Ubuntu 16.04. I started by trying what Stéphane wrote but it wasn't working. All I ended up with was the default DHCP-attempting container with an IPv6 link local, as there is no DHCP being served in my configuration.
My initial YAML looked (something) like the following (taken from the cloud-init docs).
network:
version: 1
config:
- type: physical
name: eth0
subnets:
- type: static
address: 192.168.23.14/27
gateway: 192.168.23.1
dns_nameservers:
- 192.168.23.2
- 8.8.8.8
dns_search:
- exemplary.maas
And I was loading this into user.user-data
as described above.
lxc config set CONTAINER user.user-data - < CONTAINER.cloud-init-config.yml
It wasn't until I found Stéphane's documentation in the LXC/LXD source that I realised I needed to load that value into user.network-config
.
So my final YAML looked (something) like this.
version: 1
config:
- type: physical
name: eth0
subnets:
- type: static
address: 192.168.23.14/27
gateway: 192.168.23.1
dns_nameservers:
- 192.168.23.2
- 8.8.8.8
dns_search:
- exemplary.maas
Then I loaded this into user.network-config
instead.
lxc config set CONTAINER user.network-config - < CONTAINER.network-config.yaml
It seems like I will need to keep two different files per container: one for network settings to load to user.network-config
; and one for other config to load into user.user-data
unless I can find a way of using a single file for everything.
Another problem I found which wasn't obvious to me at all was trying to configure non-network components automatically.
lxc config set CONTAINER user.user-data - < CONTAINER.user-data.yaml
The following YAML applied with the command above (despite looking correct using lxc config show CONTAINER
) did not create anything inside my container.
write_files:
- content: |
# My new /etc/foo.bar file
Foo
Bar
path: /etc/foo.bar
The clue buried away in User Data Input Formats, item 5: Cloud Config Data reads:
begins with
"#cloud-config"
or"Content-Type: text/cloud-config"
This content is "cloud-config" data. See the examples for a commented example of supported config formats.
I don't believe this documentation is very clear. I could not get anything to work using the "Content-Type: text/cloud-config" form but I did find if you put #cloud-config
on the first line, the YAML is parsed. I can only assume something isn't quite right, either my understanding, or someone's programming. It makes no sense to me that YAML you've explicitly loaded as the value of the key user.user-data
should be used as anything other than cloud configuration data. Why else would anyone do that if it wasn't meant to be cloud configuration, and therefore why would a comment (which doesn't even use the normal shebang syntax) be required?
So, nonsense aside, the syntax which worked for user.user-data
is:
#cloud-config
write_files:
- content: |
# My new /etc/foo.bar file
Foo
Bar
path: /etc/foo.bar
One liner I went with today, this one sets it in the default profile for new containers:
echo -e "#cloud-config\nssh_authorized_keys:\n - $(cat ~/.ssh/id_rsa.pub)" | lxc profile set default user.user-data -
This one sets it in an existing container, but beware it will not work on containers that already booted as the SSH key stuff only gets done on first boot:
echo -e "#cloud-config\nssh_authorized_keys:\n - $(cat ~/.ssh/id_rsa.pub)" | lxc config set CONTAINER_NAME user.user-data -