Building a Home Lab server β€” Part III

Automating LXC container deployment using Pulumi and Go in Proxmox

Madhan published on
3 min, 517 words

In this article we will explore how to automate the process of LXC container deployment on Proxmox using Pulumi.

How LXC is different from Docker ?

Application containers (like Docker) run a single process and are designed for stateless, ephemeral workloads, allowing you to quickly scale up or down without worrying about container lifecycle. In contrast, System containers (like LXC) act more like virtual machines, running a full OS where you can manage services, install packages, and apply updates. They’re long-lasting and managed like traditional servers, receiving regular security updates directly from the OS distribution.

Code Walkthrough

1. Loading Environment Variables

The script starts by loading environment variables from a .env file using the godotenv package.

.env file

PROXMOX_USERNAME=XXXXXXXXXXXX
PROXMOX_PASSWORD=XXXXXXXXXXXX
CONTAINER_PASSWORD=XXXXXXXXXX

main.go file

err := godotenv.Load()

It then reads the Proxmox username, password and container password from the environment. These values are used to authenticate with the Proxmox server.

proxmoxUsername := os.Getenv("PROXMOX_USERNAME")
proxmoxPassword := os.Getenv("PROXMOX_PASSWORD")
containerPassword := os.Getenv("CONTAINER_PASSWORD")

if proxmoxUsername == "" || proxmoxPassword == "" || containerPassword == "" {
    return fmt.Errorf("PROXMOX_USERNAME, PROXMOX_PASSWORD and CONTAINER_PASSWORD must be set in the .env file")
}

2. Configuring the Proxmox Provider

The next step is setting up the Proxmox provider, Endpoint specifies the URL for the Proxmox server, Username and Password are used for authentication, Insecurewhether to skip the TLS verification step.

provider, err := proxmoxve.NewProvider(ctx, "proxmoxve", &proxmoxve.ProviderArgs{
    Endpoint: pulumi.String("https://192.168.1.198:8006/"),
    Username: pulumi.String(proxmoxUsername),
    Password: pulumi.String(proxmoxPassword),
    Insecure: pulumi.Bool(true),
})

3. Download LXC template

The below code downloads an LXC template for Ubuntu 22.04 from a public image repository using the download.NewFile function.

ctTemplate, err := download.NewFile(ctx, "latest-ubuntu22-jammy-lxc", &download.FileArgs{
    ContentType: pulumi.String("vztmpl"),
    DatastoreId: pulumi.String("local"),
    NodeName:    pulumi.String("pve"),
    Url:         pulumi.String("https://images.linuxcontainers.org/images/ubuntu/jammy/amd64/default/20241101_07%3A42/rootfs.tar.xz"),
}, pulumi.Provider(provider))

4. Creating the Container

Once the template is successfully downloaded, it then proceeds to create a new LXC container in Proxmox.

newCT, err := ct.NewContainer(ctx, "container", &ct.ContainerArgs{
    NodeName: pulumi.String("pve"),
    OperatingSystem: &ct.ContainerOperatingSystemArgs{
        TemplateFileId: ctTemplate.ID(),
        Type:           pulumi.String("ubuntu"),
    },
    Memory: &ct.ContainerMemoryArgs{
        Dedicated: pulumi.Int(14096),
        Swap:      pulumi.Int(4096),
    },
    Cpu: &ct.ContainerCpuArgs{
        Cores: pulumi.Int(2),
    },
    Disk: &ct.ContainerDiskArgs{
        DatastoreId: pulumi.String("local-lvm"),
        Size:        pulumi.Int(10),
    },
    NetworkInterfaces: ct.ContainerNetworkInterfaceArray{
        &ct.ContainerNetworkInterfaceArgs{
            Name:    pulumi.String("eth0"),
            Bridge:  pulumi.String("vmbr0"),
            Enabled: pulumi.Bool(true),
        },
    },
    Initialization: &ct.ContainerInitializationArgs{
        UserAccount: &ct.ContainerInitializationUserAccountArgs{
            Password: pulumi.String(containerPassword),
        },
    },
    VmId:    pulumi.Int(200),
    Started: pulumi.Bool(true),
}, pulumi.DependsOn([]pulumi.Resource{ctTemplate}), pulumi.Provider(provider))
* * * *

Originally published on Medium

🌟 🌟 🌟 The source code for this blog post can be found here 🌟🌟🌟

GitHub - madhank93/pulumi-proxmox at proxmox_container

Reference:

[1] https://ubuntu.com/blog/lxd-vs-docker

[2] https://ubuntu.com/blog/what-are-linux-containers

[3] https://www.pulumi.com/registry/packages/proxmoxve/api-docs/ct/container/

[4] https://github.com/bpg/terraform-provider-proxmox

[5] https://images.lxd.canonical.com/