Cloud-Init not working

Hi.

I am trying to move my network settings out of the containers (I have custom vlan setup) to organize it in the profiles that I have instead. However cloud-init does not seam to work for some reason.

I have flashed a fresh install of Ubuntu Server 22.04 to a test server where I have tried both LXD 5.0.1 and the latest 5.6. I have tried creating containers from ubuntu:22.04 and images:ubuntu/22.04/cloud, but nothing works. I have also tried using cloud-init.network-config as stated here: cloud-init - LXD documentation as well as user.network-config as stated here: Custom network configuration with cloud-init - LXD documentation. But nothing is changed at all.

I tried using some of the other options, just to see if I could get something to work:

config: 
  cloud-init.user-data: |
    runcmd:
      - [touch, /cloud.init.ran]

But this fails as well. No file is created.

The only way to affect the network from a profile, was to create a mount from the host to /etc/netplan on the container, with a yaml file. This works, but I would much rather have cloud-init work properly.

I just tested using LXD 5.6 and a fresh ubuntu/jammy/cloud image and it works for me using this config:

lxc init images:ubuntu/jammy/cloud c1
lxc config edit c1 #Adds `cloud-init.user-data` key
lxc config show c1
architecture: x86_64
config:
  cloud-init.user-data: |
    #cloud-config
    runcmd:
      - touch /root/cloud.init.ran
  image.architecture: amd64
  image.description: Ubuntu jammy amd64 (20221004_08:30)
  image.os: Ubuntu
  image.release: jammy
  image.serial: "20221004_08:30"
  image.type: squashfs
  image.variant: cloud
  volatile.base_image: 3f53f1fd15686a9a7388cff159e79f87ec3c3435930af9fd529b76923b71ce39
  volatile.cloud-init.instance-id: bf93214b-0af1-4df8-baaa-64d4774bd4da
  volatile.eth0.host_name: veth7b7f1a0f
  volatile.eth0.hwaddr: 00:16:3e:55:47:72
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
  volatile.uuid: 999b441c-29b7-45e7-b87a-1e75bd68638e
devices: {}
ephemeral: false
profiles:
- default
stateful: false
description: ""

lxc start c1
lxc exec c1 -- ls  /root
cloud.init.ran

So make sure that the cloud-init config is set before the first start of the instance (as it only runs on first start) and make sure you’ve got the #cloud-config line in your cloud-init config.

1 Like

I don’t get it, #cloud-config is just a comment, why would this be required?

Also, if cloud-init only runs once, then it’s not really useful for my usecase. If I change or add profiles, the configurations for that profile should change along with it. This is no different from my current static netplan setup.

My understanding that in both cases this is how cloud-init is designed, not a LXD specific thing.

You can see this in the cloud-init examples:

https://cloudinit.readthedocs.io/en/latest/topics/examples.html

As for when cloud-init runs, this is up to cloud-init, although I do believe that cloud-init will re-run when it thinks the ID of the instance has changed.

This was added fairly recently (and is in LXD 5.6):

And you can see what triggers an ID change here:

There’s a description of what changes trigger an ID change here:

Which may be sufficient for your use case.

Thanks, this is great info. Also I was not aware that cloud-init was a one-time initialization feature. I thought it ran on every init instance.

1 Like