What are the best ways to pass data into an LXD Profile

I’ve written a profile for my LXD server that allows me to simply spin up a container and have it pre provisioned with .NET 6 SDK and a couple of build tools, via the use of the profile option EG:

lxc launch ubuntu:20.04 -p dotnet

I’ve made a copy publicly available here : LXD Profile to provision .NET 6 Containers

This all works beautifully, in fact it works much better than Ansible which is great.

However there is one thing that I’ve NOT been able to work out, and that’s how to dynamically change parts of the profile.

If you look on my GitHub gist for example, you’ll see that at line 24 I add a user called shawty, with full passwordless sudo and rsa key login.

However, I’d like to change this name (Ultimately these containers will be generated from a web interface by a development team for running experimental .NET code).

My research has gotten me nowhere with figuring out if this is possible.

I would ideally love to be able to do something like:

      - name: $(username)
          - $(rsakey)

And have ‘rsakey’ and ‘username’ passed in to the lxc command at run time somehow, maybe on the command line or as environment variables.

Any pointers on how I might achieve this?

I hope that post will help you, https://discuss.linuxcontainers.org/t/cloud-init-on-alpine-how-to-use-it/11933/7

Thanks @cemzafer I’ll have a read of it.

@cemzafer ah, I see what your doing there…

You are dynamically generating the cloud init, and injecting the vars when you “cat” the YML into the profile right?

Problem is, I’m not doing that.

I have the profile already added to LXD, and so am just using the -p parameter with lxc launch to activate it.

I was hoping I could just add the var substitution’s in the profile once it’s added to LXD, then LXD would just put the correct values in itself at launch time, is this possible?

No, iirc that’s not possible.

But, if you can generate your specific yaml file it can be possible, then you can apply that configuration to the container like that.

lxc launch ubuntu:22.04 <cname> --config=user.user-data="$(cat <cloud-init_file>.yml)"


@cemzafer yep, I see that, but the data I’m wanting to populate is not “cloud-init” data, it’s actual profile options that are outside the cloud-init section.

I probably could perform the operations I wanted by abusing cloud-init, and I may have to do that eventually.

Either that, or create the profile for LXD dynamically in a not too dissimilar way, apply it to a launch, then delete that profile afterwards.

What line numbers are you trying to overwrite?

@jarrodu - Users as shown in my first post on this thread

Those parts are part of the cloud-init section. I think it goes from line 3 to 33.

It would appear they might be:

Cloud config examples — cloud-init 22.2 documentation (cloudinit.readthedocs.io)

Still would prefer to not have to resort to such hammer & walnut tactics though just to change a couple of tiny bits, would have absolutely hoped that cloud-init could have had some var substitution of some kind built into it.

I think I was washing dishes or brushing my teeth, then I remembered that I ran in to a similar issue when writing Cloud Init configurations.

I used https://dhall-lang.org/ to parametrize my yaml.

It works really well, but it adds another tool. In this case, a little bit of bash, and CLI tools can do the same thing.

@jarrodu thanks will take a look.

Right now I’m toying with the idea of using the C# LXD connector library I’ve gotten from NuGet, and using that instead of trying to call out to the console and lot’s of behind the scenes shell scripts.