Files
ansible-collection-infrastr…/roles/proxmox_lxc_provision
patrick 4f09e886c2 feat(proxmox_lxc_provision): support custom bridge, interface name, and VLAN tag
The bridge (vmbr0) and interface name (eth0) were previously hardcoded
in the netif string, and there was no way to set an 802.1Q VLAN tag.
Expose lxc_bridge, lxc_iface_name, and lxc_vlan_tag (optional) so
containers can be attached to non-default bridges or tagged into a VLAN
without forking the role.

Also drop the misleading 'lxc_ipv6 | default(omit)' filter — default(omit)
does not produce omission inside a string context, and lxc_ipv6 always
has a default of 'auto' in defaults/main.yml.
2026-06-27 21:23:14 -04:00
..

Ansible Role: proxmox_lxc_provision

Description

This Ansible role manages the provision of LXC containers and templates on a Proxmox host. By default the role will create and start an LXC container. It allows creating a new container from a container image or cloning an existing container or template container.

It also includes tasks which may be used individually:

  • clone.yml: Creates a new LXC container by cloning another container or template
  • convert.yml: Converts an LXC container to a template
  • create.yml: Creates a new LXC container
  • delete.yml: Deletes an LXC container given its vmid or hostname
  • start.yml: Starts an LXC container
  • stop.yml: Stops an LXC container
  • update.yml: Updates an existing LXC container
  • wait.yml: Waits for SSH to be available on the container
  • check-exists.yml: Checks if an LXC exists by lxc_vmid or lxc_hostname
  • post-clone.yml: Post-clone configuration (passwords, SSH host key regeneration). Runs against the new container; depends on the system_setup role.
  • edit-config.yml: Edits /etc/pve/lxc/<vmid>.conf directly to add ID mappings and NVIDIA GPU passthrough entries. Must be delegated to the Proxmox host.

Requirements

  • Ansible 2.12 or higher
  • Python 3.6 or higher
  • requests
  • proxmoxer
  • passlib

Role Variables

Required Proxmox API Variables

Variable Description Example
proxmox_api_host The IP address or hostname of the Proxmox server 192.168.1.10
proxmox_api_user The username for Proxmox authentication, typically in format username@realm ansible@pve
proxmox_api_token_id The API token ID used for authentication token
proxmox_api_token_secret The secret key associated with the API token xxx-yyy-zzz
proxmox_node The name of the Proxmox node to target pve01

Optional Proxmox API Variables

Variable Description Default
proxmox_api_port The port on which the Proxmox API is listening 8006
proxmox_api_validate_certs Whether to validate SSL certificates false
proxmox_delegate_host Inventory hostname for delegated tasks (pct commands). Use this to inherit ansible_become_password from inventory. {{ proxmox_api_host }}

Required Container Variables

Variable Description Example
lxc_template The OS template to create the LXC from. Mutually exclusive with lxc_clone_from local:vztmpl/debian-12_amd64.tar.zst
lxc_clone_from The vmid of the container or template to clone. Mutually exclusive with lxc_template 201
lxc_hostname The hostname for the container my-container
lxc_vmid The VM ID for the container 100

Optional Container Variables

Variable Description Default
lxc_clone_type Clone type when using lxc_clone_from full
lxc_storage Target storage for the container local-zfs
lxc_size Disk size in GB 16
lxc_disk The target storage and storage size local-zfs:16
lxc_root_password Password for the root account. On creates from lxc_template it is set via the Proxmox API; on clones it is applied inside the container by post-clone.yml. -
lxc_user_name Name of an additional non-root user to manage in post-clone.yml (clone path only). admin
lxc_user_password Password for lxc_user_name. Only applied on the clone path via post-clone.yml. The user must already exist in the source template. -
lxc_cores The number of CPU cores 4
lxc_memory Memory size in MB 2048
lxc_swap Swap memory size in MB 2048
lxc_ipv4 The IPv4 address dhcp
lxc_ipv6 The IPv6 address auto
lxc_gateway The default gateway 10.0.0.1
lxc_nameserver DNS nameserver 10.0.0.7
lxc_bridge Linux bridge on the Proxmox host to attach the container to vmbr0
lxc_iface_name Interface name inside the container eth0
lxc_vlan_tag 802.1Q VLAN tag (integer 1-4094). Omitted from netif when unset. -
lxc_pubkey_file Path to SSH public key file ~/.ssh/id_ed25519.pub
lxc_features List of container features ["nesting=1"]
lxc_tags Tags for the container ["ansible-managed"]
lxc_start Start container after creation true
lxc_unprivileged Create as an unprivileged container true
lxc_mounts Dict of additional bind mounts (e.g. { mp0: "/srv/data,mp=/data" }) -
lxc_onboot Start container on Proxmox host boot false
lxc_startup Startup order string passed to Proxmox (e.g. order=1,up=30) -
lxc_timezone Timezone inside the container (e.g. Europe/Berlin) -
lxc_nvidia_gpu_mount Add NVIDIA GPU passthrough entries via edit-config.yml false
gpu_device_id Major device number for /dev/nvidia* (required when lxc_nvidia_gpu_mount is true) -
uvm_device_id Major device number for /dev/nvidia-uvm* (required when lxc_nvidia_gpu_mount is true) -
lxc_id_mappings Multi-line lxc.idmap: block written into the container config by edit-config.yml -

Example Playbook

Prerequisites

Set up your Proxmox API connection variables in group vars:

# group_vars/all.yml
proxmox_api_host: "10.0.1.1"
proxmox_api_port: 8006
proxmox_api_user: "automation@pve"
proxmox_api_token_id: "mytoken"
proxmox_api_token_secret: "{{ vault_proxmox_token }}"
proxmox_api_validate_certs: false
proxmox_node: "pve01"
proxmox_delegate_host: "proxmox_server"  # inventory hostname for become_password

Creating a new LXC from template

- name: Create and start an LXC container
  hosts: localhost
  connection: local
  vars:
    lxc_vmid: 100
    lxc_hostname: new-debian-container
    lxc_template: "local:vztmpl/debian-12_amd64.tar.zst"
    lxc_ipv4: "10.0.0.99/24"
  roles:
    - role: proxmox_lxc_provision

Creating a new LXC by cloning an existing container

- name: Clone an LXC container
  hosts: localhost
  connection: local
  vars:
    lxc_vmid: 101
    lxc_hostname: cloned-container
    lxc_clone_from: 200
    lxc_ipv4: "10.0.0.100/24"
  roles:
    - role: proxmox_lxc_provision

Idempotent Behavior

The role includes idempotency checking. If a container with the specified lxc_vmid or lxc_hostname already exists, the role will skip provisioning and exit gracefully. Sets lxc_exists fact for use in subsequent tasks.

Using Standalone Tasks

When using individual task files via tasks_from, you must set module_defaults at the play level since the tasks bypass the role's main entry point:

- name: Convert container to a template
  hosts: localhost
  module_defaults:
    community.proxmox.proxmox:
      api_host: "{{ proxmox_api_host }}"
      api_port: "{{ proxmox_api_port }}"
      api_user: "{{ proxmox_api_user }}"
      api_token_id: "{{ proxmox_api_token_id }}"
      api_token_secret: "{{ proxmox_api_token_secret }}"
      validate_certs: "{{ proxmox_api_validate_certs }}"
      node: "{{ proxmox_node }}"
  vars:
    lxc_hostname: "{{ lxc_hostname }}"
  tasks:
    - include_role:
        name: proxmox_lxc_provision
        tasks_from: convert

Creating an LXC Container and Converting it to a Template

---
- name: Create and start an LXC container
  hosts: localhost
  connection: local
  vars:
    lxc_vmid: "{{ lxc_vmid }}"
    lxc_hostname: "{{ lxc_hostname }}"
    lxc_template: "local:vztmpl/debian-12_amd64.tar.zst"
    lxc_ipv4: "10.0.0.99/24"
  roles:
    - role: proxmox_lxc_provision

# Run configuration tasks on the container...

- name: Convert the created container to a template
  hosts: localhost
  module_defaults:
    community.proxmox.proxmox:
      api_host: "{{ proxmox_api_host }}"
      api_port: "{{ proxmox_api_port }}"
      api_user: "{{ proxmox_api_user }}"
      api_token_id: "{{ proxmox_api_token_id }}"
      api_token_secret: "{{ proxmox_api_token_secret }}"
      validate_certs: "{{ proxmox_api_validate_certs }}"
      node: "{{ proxmox_node }}"
  vars:
    lxc_hostname: "{{ lxc_hostname }}"
  tasks:
    - include_role:
        name: proxmox_lxc_provision
        tasks_from: convert