51c1c5b611
Rename lxc_password to lxc_root_password for consistency with the new lxc_user_password (replaces the previously bare 'password' variable in post-clone.yml, which silently collided with any same-named caller var). Add lxc_user_name (default: admin) so the non-root account managed in post-clone.yml is no longer hardcoded. Apply default(omit) to the root password in create.yml so it is genuinely optional as documented. BREAKING CHANGE: callers passing lxc_password or a bare 'password' var must rename to lxc_root_password and lxc_user_password respectively.
8.0 KiB
Executable File
8.0 KiB
Executable File
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 templateconvert.yml: Converts an LXC container to a templatecreate.yml: Creates a new LXC containerdelete.yml: Deletes an LXC container given its vmid or hostnamestart.yml: Starts an LXC containerstop.yml: Stops an LXC containerupdate.yml: Updates an existing LXC containerwait.yml: Waits for SSH to be available on the containercheck-exists.yml: Checks if an LXC exists bylxc_vmidorlxc_hostnamepost-clone.yml: Post-clone configuration (passwords, SSH host key regeneration). Runs against the new container; depends on thesystem_setuprole.edit-config.yml: Edits/etc/pve/lxc/<vmid>.confdirectly 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_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