Score:2

How do I pass a cloud-init config when creating an LXD container?

ck flag

I've been reading through the LXD documentation and blogs and stackexchange answers that say LXD is supposed to have some kind of init syntax that allows you to pass cloud-config data to your containers as they're created, but none of the many examples have worked for me. I've tried following examples that set up a profile, examples that pass data in using --config, examples that pass yaml data directly in, and examples that set the data after init but before starting. Nothing has worked. I'm pasting in what I currently have... Could someone please tell me what I'm doing wrong and how to fix it?

The most basic example I can think of:

lxc delete -f x

cat << EOF >config.yml
#cloud-config
output: {all: '| tee -a /var/log/my-cloud-init-output.log'}
package_update: true
package_upgrade: true
package_reboot_if_required: true
packages:
  - tree
runcmd:
  - touch /run/cloud-config-did-run
EOF

lxc launch ubuntu: x --config=user.user-data="$(cat config.yml)"
sleep 5
lxc exec x -- bash -c "ls /run"
lxc exec x -- bash -c "tree /etc"

This should output to /var/log/my-cloud-init-output.log, install tree and also make an empty file in /run. The output to /var/log/my-cloud-init-output.log works, but nothing else does. The logs don't show anything special.

ck flag
Yes, I've tried profiles, but that also didn't work (the directives never run). I'm just looking for SOMETHING, ANYTHING that works out-of-the-box so that I have a base to work from.
ck flag
That blog is actually the one I followed when I was trying to use profiles.
ck flag
Literally all I want is to launch an ubuntu container and have some extra packages installed. I don't need dynamic changes (not even sure what that is). I just need the end result to be a standard ubuntu container + some packages installed (and me not having to manually log in and apt install everything).
Score:2
th flag

It appears you need to wait longer. Since you have both package_update and package_upgrade specified as true, you're essentially run apt-get update; apt-get upgrade (which can take more than 5 seconds) before tree can get installed or the runcmd executes.

Your exact commands work for me if I substitute the sleep 5 with

lxc exec x -- bash -c "cloud-init status --wait"
sleep 2  # because of the `package_reboot_if_required: true`
user535733 avatar
cn flag
+5 if I could. I had the *exact same problem* (not waiting for cloud-init to complete) a couple months ago, yet failed to recognize it in the question. Kudos for the detective work!
ck flag
Hmm interesting... When I substitute those commands I get a screen full of dots as it waits forever (I gave up after 15 minutes). Even removing everything but the touch command doesn't work. And this fails on two separate systems (NixOS running LXD 2.40 and Ubuntu running 2.41).
th flag
You should be able to `lxc shell x` into the container and see what's going on. `systemd-analyze critical-chain` should complain if anything is blocking boot. If not, `/var/log/cloud-init.log` should indicate any cloud-init specific failures.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.