refactor(proxmox_lxc_provision): centralize module_defaults so tasks_from works without setup

Previously the community.proxmox.proxmox / proxmox_vm_info module_defaults
were defined inline on the outer block in main.yml. Invoking individual
task files via 'tasks_from: stop' (or delete/convert/etc.) bypassed
main.yml, leaving the API parameters unset and producing
'missing required arguments: api_host, api_user' errors. The README
worked around this by telling callers to repeat the module_defaults
block at the play level — easy to forget, and duplicated config.

Extract the defaults dict into _proxmox_module_defaults in
defaults/main.yml (using a YAML anchor to share between the two
modules), and wrap every task file that calls a Proxmox module in a
block that references it. Callers only need the proxmox_* connection
vars in scope (typically group_vars/all/) — both 'roles:' and
'tasks_from:' invocations now configure the API consistently.

Files wrapped: check-exists, create, clone, update, start, stop,
delete, convert. wait/post-clone/edit-config don't call Proxmox modules
and are unchanged. main.yml's now-redundant outer module_defaults is
removed.

README updated to drop the 'Using Standalone Tasks' workaround
boilerplate.
This commit is contained in:
2026-06-28 13:42:41 -04:00
parent 8a9903eb4c
commit d5cf6f656e
11 changed files with 200 additions and 193 deletions
+5 -23
View File
@@ -144,26 +144,17 @@ The role includes idempotency checking. If a container with the specified `lxc_v
### Using Standalone 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: Individual task files (`stop`, `start`, `delete`, `convert`, etc.) can be invoked via `tasks_from` directly — each task file wraps its work in a block with the role's shared `module_defaults`, so the Proxmox API connection is configured automatically as long as the `proxmox_*` connection variables are in scope (typically from `group_vars/all/`).
```yaml ```yaml
- name: Convert container to a template - name: Convert container to a template
hosts: localhost 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: tasks:
- include_role: - include_role:
name: proxmox_lxc_provision name: proxmox_lxc_provision
tasks_from: convert tasks_from: convert
vars:
lxc_hostname: my-container
``` ```
### Creating an LXC Container and Converting it to a Template ### Creating an LXC Container and Converting it to a Template
@@ -185,19 +176,10 @@ When using individual task files via `tasks_from`, you must set `module_defaults
- name: Convert the created container to a template - name: Convert the created container to a template
hosts: localhost 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: tasks:
- include_role: - include_role:
name: proxmox_lxc_provision name: proxmox_lxc_provision
tasks_from: convert tasks_from: convert
vars:
lxc_hostname: "{{ lxc_hostname }}"
``` ```
@@ -5,6 +5,19 @@ proxmox_api_validate_certs: false
# Host to delegate pct commands to (use inventory hostname for become_password to work) # Host to delegate pct commands to (use inventory hostname for become_password to work)
proxmox_delegate_host: "{{ proxmox_api_host }}" proxmox_delegate_host: "{{ proxmox_api_host }}"
# Shared module_defaults applied by every task file that calls the Proxmox API.
# Override the underlying proxmox_* vars (e.g. from group_vars/all/) to customize.
_proxmox_module_defaults:
community.proxmox.proxmox: &_proxmox_api_args
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 }}"
community.proxmox.proxmox_vm_info: *_proxmox_api_args
# LXC defaults # LXC defaults
lxc_template: "local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst" lxc_template: "local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst"
lxc_cores: 4 lxc_cores: 4
@@ -1,10 +1,13 @@
--- ---
- name: Query Proxmox for existing LXCs - name: Check if LXC exists
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- name: Query Proxmox for existing LXCs
community.proxmox.proxmox_vm_info: community.proxmox.proxmox_vm_info:
type: lxc type: lxc
register: proxmox_lxcs register: proxmox_lxcs
- name: Check if LXC already exists - name: Check if LXC already exists
ansible.builtin.set_fact: ansible.builtin.set_fact:
lxc_exists: >- lxc_exists: >-
{{ {{
+6 -3
View File
@@ -1,5 +1,8 @@
--- ---
- name: Create a full clone of the container - name: Clone LXC container
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- name: Create a full clone of the container
community.proxmox.proxmox: community.proxmox.proxmox:
vmid: "{{ lxc_vmid | default(0) }}" vmid: "{{ lxc_vmid | default(0) }}"
clone: "{{ lxc_clone_from }}" clone: "{{ lxc_clone_from }}"
@@ -8,14 +11,14 @@
storage: "{{ lxc_storage }}" storage: "{{ lxc_storage }}"
register: clone_result register: clone_result
- name: Add bind mounts via pct - name: Add bind mounts via pct
become: yes become: yes
ansible.builtin.shell: | ansible.builtin.shell: |
pct set {{ clone_result.vmid | default(lxc_vmid) }} {% for key, value in lxc_mounts.items() %}-{{ key }} {{ value }} {% endfor %} pct set {{ clone_result.vmid | default(lxc_vmid) }} {% for key, value in lxc_mounts.items() %}-{{ key }} {{ value }} {% endfor %}
delegate_to: "{{ proxmox_delegate_host }}" delegate_to: "{{ proxmox_delegate_host }}"
when: lxc_mounts is defined when: lxc_mounts is defined
- name: Resize rootfs after clone - name: Resize rootfs after clone
ansible.builtin.command: ansible.builtin.command:
cmd: "pct resize {{ clone_result.vmid }} rootfs {{ lxc_size }}G" cmd: "pct resize {{ clone_result.vmid }} rootfs {{ lxc_size }}G"
delegate_to: "{{ proxmox_delegate_host }}" delegate_to: "{{ proxmox_delegate_host }}"
@@ -1,7 +1,10 @@
--- ---
- ansible.builtin.include_tasks: stop.yml - name: Convert LXC container to template
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- ansible.builtin.include_tasks: stop.yml
- name: Convert container to template - name: Convert container to template
community.proxmox.proxmox: community.proxmox.proxmox:
hostname: "{{ lxc_hostname }}" hostname: "{{ lxc_hostname }}"
state: template state: template
+4 -1
View File
@@ -1,5 +1,8 @@
--- ---
- name: Create an LXC container - name: Create LXC container
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- name: Create an LXC container
community.proxmox.proxmox: community.proxmox.proxmox:
vmid: "{{ lxc_vmid | default(omit) }}" vmid: "{{ lxc_vmid | default(omit) }}"
hostname: "{{ lxc_hostname }}" hostname: "{{ lxc_hostname }}"
+5 -2
View File
@@ -1,7 +1,10 @@
--- ---
- ansible.builtin.include_tasks: stop.yml - name: Delete LXC container
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- ansible.builtin.include_tasks: stop.yml
- name: Delete a container - name: Delete a container
community.proxmox.proxmox: community.proxmox.proxmox:
vmid: "{{ lxc_vmid | default(omit) }}" vmid: "{{ lxc_vmid | default(omit) }}"
hostname: "{{ lxc_hostname | default(omit) }}" hostname: "{{ lxc_hostname | default(omit) }}"
+7 -19
View File
@@ -1,30 +1,18 @@
--- ---
- name: Proxmox LXC provision - name: Check if container exists
module_defaults:
community.proxmox.proxmox: &proxmox_defaults
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 }}"
community.proxmox.proxmox_vm_info: *proxmox_defaults
block:
- name: Check if container exists
ansible.builtin.include_tasks: ansible.builtin.include_tasks:
file: check-exists.yml file: check-exists.yml
- name: Skip if container already exists - name: Skip if container already exists
meta: end_host meta: end_host
when: lxc_exists | bool when: lxc_exists | bool
- name: Container source must be defined (lxc_clone_from or lxc_template) - name: Container source must be defined (lxc_clone_from or lxc_template)
ansible.builtin.fail: ansible.builtin.fail:
msg: "Neither lxc_clone_from or lxc_template are defined" msg: "Neither lxc_clone_from or lxc_template are defined"
when: lxc_clone_from is undefined and lxc_template is undefined when: lxc_clone_from is undefined and lxc_template is undefined
- name: Clone container from another container or template, then update - name: Clone container from another container or template, then update
when: lxc_clone_from is defined when: lxc_clone_from is defined
block: block:
- name: Clone from template - name: Clone from template
@@ -39,12 +27,12 @@
lxc_vmid: "{{ clone_result.vmid }}" lxc_vmid: "{{ clone_result.vmid }}"
register: lxc_result register: lxc_result
- name: Create the new container - name: Create the new container
ansible.builtin.include_tasks: ansible.builtin.include_tasks:
file: create.yml file: create.yml
when: lxc_template is defined and lxc_clone_from is undefined when: lxc_template is defined and lxc_clone_from is undefined
- name: Start the created container and wait for ssh - name: Start the created container and wait for ssh
vars: vars:
lxc_vmid: "{{ lxc_result.vmid }}" lxc_vmid: "{{ lxc_result.vmid }}"
ansible.builtin.include_tasks: ansible.builtin.include_tasks:
@@ -54,7 +42,7 @@
- wait.yml - wait.yml
when: lxc_start when: lxc_start
- name: Post clone updates - name: Post clone updates
when: lxc_clone_from is defined when: lxc_clone_from is defined
delegate_to: "{{ lxc_hostname }}" delegate_to: "{{ lxc_hostname }}"
block: block:
+4 -1
View File
@@ -1,5 +1,8 @@
--- ---
- name: Start the LXC container - name: Start LXC container
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- name: Start the LXC container
community.proxmox.proxmox: community.proxmox.proxmox:
vmid: "{{ lxc_result.vmid }}" vmid: "{{ lxc_result.vmid }}"
state: started state: started
+4 -1
View File
@@ -1,5 +1,8 @@
--- ---
- name: Stop container if it is running - name: Stop LXC container
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- name: Stop container if it is running
community.proxmox.proxmox: community.proxmox.proxmox:
vmid: "{{ lxc_vmid | default(omit) }}" vmid: "{{ lxc_vmid | default(omit) }}"
hostname: "{{ lxc_hostname | default(omit) }}" hostname: "{{ lxc_hostname | default(omit) }}"
+4 -1
View File
@@ -1,5 +1,8 @@
--- ---
- name: Update an LXC container - name: Update LXC container
module_defaults: "{{ _proxmox_module_defaults }}"
block:
- name: Update an LXC container
community.proxmox.proxmox: community.proxmox.proxmox:
vmid: "{{ lxc_vmid }}" vmid: "{{ lxc_vmid }}"
hostname: "{{ lxc_hostname }}" hostname: "{{ lxc_hostname }}"