diff --git a/roles/proxmox-lxc-provision/README.md b/roles/proxmox-lxc-provision/README.md index 326e29a..edcf48a 100755 --- a/roles/proxmox-lxc-provision/README.md +++ b/roles/proxmox-lxc-provision/README.md @@ -26,14 +26,26 @@ It also includes tasks which may be used individually: ### Required Variables - | Variable | Description | Example | |----------|-------------|---------| -| `os_template` | The OS template to create the LXC from. Mutually exclusive with `ct_id`| `local:vztmpl/debian-12_amd64.tar.zst` | -| `ct_id` | The vmid of the container or template container to clone the LXC from. Mutually exclusive with `os_template` | `201` | +| `container_template` | The OS template to create the LXC from. Mutually exclusive with `clone_from`| `local:vztmpl/debian-12_amd64.tar.zst` | +| `clone_from` | The vmid of the container or template container to clone the LXC from. Mutually exclusive with `container_template` | `201` | ### Required Proxmox API Authentication Variables +**Note:** These should be defined in `group_vars/all.yml` as part of the `proxmox_api_connection` dictionary: + +```yaml +# group_vars/all.yml +proxmox_api_connection: + 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 }}" +``` + | Variable | Description | Example | |----------|-------------|---------| | `proxmox_api_user` | The username for Proxmox authentication, typically in format `username@realm` | `ansible@pve` | @@ -49,47 +61,68 @@ It also includes tasks which may be used individually: | Variable | Description | Default | |----------|-------------|---------| -| `clone_type` | Only use with `ct_id`. Supports `full` and `linked` clones. | `full` | -| `container_storage` | Target storage for the container | `local-zfs` | -| `disk` | The target storage and storage size | `local-zfs:16` | -| `container_password` | The password for the root account | `password123` | -| `container_cores` | The number of CPU cores | `4` | -| `container_memory` | Memory size in MB for container | `2048` | -| `swap_memory` | Swap memory size in MB | `2048` | -| `container_ipv4` | The IPv4 address | `dhcp` | -| `container_ipv6` | The IPv6 address | `auto` | -| `container_pubkey_file` | The SSH public key for authentication to root user | Creates a temp key in `/tmp` | -| `container_features` | List of additional container features | `- nesting=1` | +| `lxc_clone_type` | Only use with `lxc_clone_from`. Supports `full` and `linked` clones. | `full` | +| `lxc_storage` | Target storage for the container | `local-zfs` | +| `lxc_disk` | The target storage and storage size | `local-zfs:16` | +| `lxc_password` | The password for the root account | `password123` | +| `lxc_cores` | The number of CPU cores | `4` | +| `lxc_memory` | Memory size in MB for container | `2048` | +| `lxc_swap` | Swap memory size in MB | `2048` | +| `lxc_ipv4` | The IPv4 address | `dhcp` | +| `lxc_ipv6` | The IPv6 address | `auto` | +| `lxc_pubkey_file` | The SSH public key for authentication to root user | Creates a temp key in `/tmp` | +| `lxc_features` | List of additional container features | `- nesting=1` | ## Example Playbook -*Assuming Proxmox authentication variables are set* -#### Creating a new LXC + +### Prerequisites + +First, set up your Proxmox API connection in group vars: + ```yaml -- name: Create and start an LXC container - hosts: localhost - connection: local - vars: - - container_hostname: new-debian-container - - os_template: "local:vztmpl/debian-12_amd64.tar.zst" - - container_ipv4: "10.0.0.99" - roles: - - role: proxmox-provision +# group_vars/all.yml +proxmox_api_connection: + api_host: "10.0.1.1" + api_port: 8006 + api_user: "automation@pve" + api_token_id: "mytoken" + api_token_secret: "{{ vault_proxmox_token }}" + validate_certs: false + +proxmox_node: "pve01" ``` -#### Creating a new LXC by cloning an existing container with vmid 200 +### Creating a new LXC from template ```yaml - name: Create and start an LXC container hosts: localhost connection: local vars: - - container_hostname: new-debian-container - - ct_id: 200 - - container_ipv4: "10.0.0.99" + lxc_hostname: new-debian-container + lxc_template: "local:vztmpl/debian-12_amd64.tar.zst" + lxc_ipv4: "10.0.0.99" roles: - role: proxmox-lxc-provision ``` +### Creating a new LXC by cloning an existing container with vmid 200 +```yaml +- name: Create and start an LXC container + hosts: localhost + connection: local + vars: + lxc_hostname: new-debian-container + lxc_clone_from: 200 + lxc_ipv4: "10.0.0.99" + roles: + - role: proxmox-lxc-provision +``` + +### Idempotent Behavior + +The role now includes idempotency checking. If a container with the specified `container_vmid` already exists, the role will skip provisioning and exit gracefully. + #### Creating an LXC Container and Converting it to a Template ```yaml diff --git a/roles/proxmox-lxc-provision/defaults/main.yaml b/roles/proxmox-lxc-provision/defaults/main.yaml index c989f8f..3fbb7b9 100755 --- a/roles/proxmox-lxc-provision/defaults/main.yaml +++ b/roles/proxmox-lxc-provision/defaults/main.yaml @@ -1,20 +1,20 @@ --- -container_template: "local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst" -container_cores: 4 -container_memory: 2048 -container_swap: 2048 -container_storage: local-zfs -container_size: 16 -container_disk: "{{ container_storage }}:{{ container_size }}" -container_ipv4: dhcp -container_ipv6: auto -container_nameserver: 10.0.0.7 -container_gateway: 10.0.0.1 -container_pubkey_file: "~/.ssh/id_ed25519.pub" -container_unprivileged: true -container_features: +lxc_template: "local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst" +lxc_cores: 4 +lxc_memory: 2048 +lxc_swap: 2048 +lxc_storage: local-zfs +lxc_size: 16 +lxc_disk: "{{ lxc_storage }}:{{ lxc_size }}" +lxc_ipv4: dhcp +lxc_ipv6: auto +lxc_nameserver: 10.0.0.7 +lxc_gateway: 10.0.0.1 +lxc_pubkey_file: "~/.ssh/id_ed25519.pub" +lxc_unprivileged: true +lxc_features: - nesting=1 -container_nvidia_gpu_mount: false -container_tags: ["ansible-managed"] -clone_type: full -container_start: true +lxc_nvidia_gpu_mount: false +lxc_tags: ["ansible-managed"] +lxc_clone_type: full +lxc_start: true diff --git a/roles/proxmox-lxc-provision/tasks/clone.yaml b/roles/proxmox-lxc-provision/tasks/clone.yaml index 7fbe4dc..2212f58 100755 --- a/roles/proxmox-lxc-provision/tasks/clone.yaml +++ b/roles/proxmox-lxc-provision/tasks/clone.yaml @@ -1,37 +1,24 @@ --- - name: Create a full clone of the container community.general.proxmox: - api_user: "{{ proxmox_api_user }}" - api_token_id: "{{ proxmox_api_token_id }}" - api_token_secret: "{{ proxmox_api_token_secret }}" - api_host: "{{ proxmox_api_host }}" - node: "{{ proxmox_node }}" - - vmid: "{{ container_vmid | default(0) }}" - clone: "{{ clone_from }}" - clone_type: "{{ clone_type }}" - hostname: "{{ container_hostname }}" - storage: "{{ container_storage }}" + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_vmid | default(0) }}" + clone: "{{ lxc_clone_from }}" + clone_type: "{{ lxc_clone_type }}" + hostname: "{{ lxc_hostname }}" + storage: "{{ lxc_storage }}" register: clone_result -- name: Debug container_mounts - ansible.builtin.debug: - msg: - - "container_mounts: {{ container_mounts }}" - - "Type: {{ container_mounts | type_debug }}" - - "Defined: {{ container_mounts is defined }}" - - "Length: {{ container_mounts | length }}" - - name: Add bind mounts via pct become: yes ansible.builtin.shell: | - pct set {{ clone_result.vmid | default(container_vmid) }} {% for key, value in container_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_api_host }}" - when: container_mounts is defined + when: lxc_mounts is defined - name: Resize rootfs after clone ansible.builtin.command: - cmd: "pct resize {{ clone_result.vmid }} rootfs {{ container_size }}G" + cmd: "pct resize {{ clone_result.vmid }} rootfs {{ lxc_size }}G" delegate_to: "{{ proxmox_api_host }}" become: yes register: resize_result @@ -39,4 +26,4 @@ failed_when: - resize_result.rc != 0 - "'already at specified size' not in resize_result.stderr" - when: container_size is defined + when: lxc_size is defined diff --git a/roles/proxmox-lxc-provision/tasks/convert.yaml b/roles/proxmox-lxc-provision/tasks/convert.yaml index 43620b4..048f916 100755 --- a/roles/proxmox-lxc-provision/tasks/convert.yaml +++ b/roles/proxmox-lxc-provision/tasks/convert.yaml @@ -2,11 +2,7 @@ - ansible.builtin.include_tasks: stop.yaml - name: Convert container to template community.general.proxmox: - api_user: "{{ proxmox_api_user }}" - api_token_id: "{{ proxmox_api_token_id }}" - api_token_secret: "{{ proxmox_api_token_secret }}" - api_host: "{{ proxmox_api_host }}" - node: server + <<: "{{ proxmox_api_connection }}" state: template - hostname: "{{ container_hostname }}" + hostname: "{{ lxc_hostname }}" diff --git a/roles/proxmox-lxc-provision/tasks/create.yaml b/roles/proxmox-lxc-provision/tasks/create.yaml index fbfc30c..c12fd8f 100755 --- a/roles/proxmox-lxc-provision/tasks/create.yaml +++ b/roles/proxmox-lxc-provision/tasks/create.yaml @@ -1,32 +1,25 @@ --- - name: Create an LXC container community.general.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 }}" - vmid: "{{ container_vmid | default(omit) }}" - hostname: "{{ container_hostname }}" - password: "{{ container_password }}" - ostemplate: "{{ container_template }}" - cores: "{{ container_cores }}" - memory: "{{ container_memory }}" - swap: "{{ container_swap }}" - disk: "{{ container_disk }}" - mounts: "{{ container_mounts | default(omit) }}" + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_vmid | default(omit) }}" + hostname: "{{ lxc_hostname }}" + password: "{{ lxc_password }}" + ostemplate: "{{ lxc_template }}" + cores: "{{ lxc_cores }}" + memory: "{{ lxc_memory }}" + swap: "{{ lxc_swap }}" + disk: "{{ lxc_disk }}" + mounts: "{{ lxc_mounts | default(omit) }}" netif: > - {"net0": "name=eth0,gw={{ container_gateway }},ip={{ container_ipv4 }},ip6={{ container_ipv6 | default(omit) }},bridge=vmbr0"} - pubkey: "{{ lookup('file', container_pubkey_file) | default(omit) }}" - onboot: "{{ container_onboot | default(false) }}" - startup: "{{ container_startup | default(omit) }}" - unprivileged: "{{ container_unprivileged | default(true) }}" - features: "{{ container_features | default(omit) }}" - timezone: "{{ container_timezone | default(omit) }}" - nameserver: "{{ container_nameserver | default(omit) }}" + {"net0": "name=eth0,gw={{ lxc_gateway }},ip={{ lxc_ipv4 }},ip6={{ lxc_ipv6 | default(omit) }},bridge=vmbr0"} + pubkey: "{{ lookup('file', lxc_pubkey_file) | default(omit) }}" + onboot: "{{ lxc_onboot | default(false) }}" + startup: "{{ lxc_startup | default(omit) }}" + unprivileged: "{{ lxc_unprivileged | default(true) }}" + features: "{{ lxc_features | default(omit) }}" + timezone: "{{ lxc_timezone | default(omit) }}" + nameserver: "{{ lxc_nameserver | default(omit) }}" state: present - tags: "{{ container_tags | default(omit) }}" - register: container_result + tags: "{{ lxc_tags | default(omit) }}" + register: lxc_result diff --git a/roles/proxmox-lxc-provision/tasks/delete.yaml b/roles/proxmox-lxc-provision/tasks/delete.yaml index 25e495c..2c40c2a 100755 --- a/roles/proxmox-lxc-provision/tasks/delete.yaml +++ b/roles/proxmox-lxc-provision/tasks/delete.yaml @@ -2,15 +2,9 @@ - ansible.builtin.include_tasks: stop.yaml - name: Delete a container community.general.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 }}" - - vmid: "{{ container_vmid | default(omit) }}" - hostname: "{{ container_hostname | default(omit) }}" + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_vmid | default(omit) }}" + hostname: "{{ lxc_hostname | default(omit) }}" state: absent register: delete_result failed_when: | diff --git a/roles/proxmox-lxc-provision/tasks/edit-config.yaml b/roles/proxmox-lxc-provision/tasks/edit-config.yaml index ab5ac73..6b37b47 100755 --- a/roles/proxmox-lxc-provision/tasks/edit-config.yaml +++ b/roles/proxmox-lxc-provision/tasks/edit-config.yaml @@ -2,21 +2,21 @@ - name: Remove all existing ID mappings lineinfile: - path: "/etc/pve/lxc/{{ container_vmid }}.conf" + path: "/etc/pve/lxc/{{ lxc_vmid }}.conf" regexp: '^lxc\.idmap:' state: absent - when: container_id_mappings is defined + when: lxc_id_mappings is defined - name: Add ID mappings blockinfile: - path: "/etc/pve/lxc/{{ container_vmid }}.conf" - block: "{{ container_id_mappings }}" + path: "/etc/pve/lxc/{{ lxc_vmid }}.conf" + block: "{{ lxc_id_mappings }}" insertafter: EOF - when: container_id_mappings is defined + when: lxc_id_mappings is defined - name: Remove existing GPU configuration lineinfile: - path: "/etc/pve/lxc/{{ container_vmid }}.conf" + path: "/etc/pve/lxc/{{ lxc_vmid }}.conf" regexp: "{{ item }}" state: absent loop: @@ -26,11 +26,11 @@ - '^lxc\.mount\.entry: /dev/nvidiactl' - '^lxc\.mount\.entry: /dev/nvidia-uvm ' - '^lxc\.mount\.entry: /dev/nvidia-uvm-tools' - when: container_nvidia_gpu_mount + when: lxc_nvidia_gpu_mount - name: Add GPU device for passthrough blockinfile: - path: /etc/pve/lxc/{{ container_vmid }}.conf + path: /etc/pve/lxc/{{ lxc_vmid }}.conf block: | lxc.cgroup2.devices.allow: c {{ gpu_device_id }}:* rwm lxc.cgroup2.devices.allow: c {{ uvm_device_id }}:* rwm @@ -38,6 +38,6 @@ lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file - when: container_nvidia_gpu_mount + when: lxc_nvidia_gpu_mount \ No newline at end of file diff --git a/roles/proxmox-lxc-provision/tasks/main.yaml b/roles/proxmox-lxc-provision/tasks/main.yaml index 05a54f3..eac864a 100755 --- a/roles/proxmox-lxc-provision/tasks/main.yaml +++ b/roles/proxmox-lxc-provision/tasks/main.yaml @@ -1,11 +1,23 @@ --- -- name: Container source must be defined (clone_from or container_template) +- name: Check if container exists + community.general.proxmox: + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_vmid }}" + state: current + register: existing_container + ignore_errors: true + +- name: Skip if container already exists + meta: end_host + when: existing_container is succeeded + +- name: Container source must be defined (lxc_clone_from or lxc_template) ansible.builtin.fail: - msg: "Neither clone_from or container_template are defined" - when: clone_from is undefined and container_template is undefined + msg: "Neither lxc_clone_from or lxc_template are defined" + when: lxc_clone_from is undefined and lxc_template is undefined - name: Clone container from another container or template, then update - when: clone_from is defined + when: lxc_clone_from is defined block: - name: Clone from template ansible.builtin.include_tasks: clone.yaml @@ -14,25 +26,25 @@ - name: Update container ansible.builtin.include_tasks: update.yaml vars: - container_vmid: "{{ clone_result.vmid }}" - register: container_result + lxc_vmid: "{{ clone_result.vmid }}" + register: lxc_result - name: Create the new container ansible.builtin.include_tasks: create.yaml - when: container_template is defined and clone_from is undefined + when: lxc_template is defined and lxc_clone_from is undefined - name: Start the created container and wait for ssh vars: - container_vmid: "{{ container_result.vmid }}" + lxc_vmid: "{{ lxc_result.vmid }}" ansible.builtin.include_tasks: "{{ item }}" loop: - start.yaml - wait.yaml - when: container_start + when: lxc_start - name: Post clone updates - when: clone_from is defined - delegate_to: "{{ container_hostname }}" + when: lxc_clone_from is defined + delegate_to: "{{ lxc_hostname }}" block: - name: Include post-clone tasks ansible.builtin.include_tasks: post-clone.yaml diff --git a/roles/proxmox-lxc-provision/tasks/post-clone.yaml b/roles/proxmox-lxc-provision/tasks/post-clone.yaml index 9412535..642c43b 100755 --- a/roles/proxmox-lxc-provision/tasks/post-clone.yaml +++ b/roles/proxmox-lxc-provision/tasks/post-clone.yaml @@ -2,9 +2,9 @@ - name: Change root password ansible.builtin.user: name: root - password: "{{ container_password | password_hash('sha512') }}" + password: "{{ lxc_password | password_hash('sha512') }}" update_password: always - when: container_password is defined + when: lxc_password is defined - name: Change admin password ansible.builtin.user: @@ -22,6 +22,6 @@ - name: Remove previous entry from known hosts ansible.builtin.known_hosts: - name: "{{ hostvars[container_hostname]['ansible_host'] }}" + name: "{{ hostvars[lxc_hostname]['ansible_host'] }}" state: absent delegate_to: localhost diff --git a/roles/proxmox-lxc-provision/tasks/start.yaml b/roles/proxmox-lxc-provision/tasks/start.yaml index 512f948..492eb0d 100755 --- a/roles/proxmox-lxc-provision/tasks/start.yaml +++ b/roles/proxmox-lxc-provision/tasks/start.yaml @@ -1,14 +1,8 @@ --- - name: Start the LXC container community.general.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 }}" - - vmid: "{{ container_result.vmid }}" + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_result.vmid }}" state: started register: start_result retries: 3 diff --git a/roles/proxmox-lxc-provision/tasks/stop.yaml b/roles/proxmox-lxc-provision/tasks/stop.yaml index bac188b..a721f70 100755 --- a/roles/proxmox-lxc-provision/tasks/stop.yaml +++ b/roles/proxmox-lxc-provision/tasks/stop.yaml @@ -1,13 +1,9 @@ --- - name: Stop container if it is running community.general.proxmox: - api_user: "{{ proxmox_api_user }}" - api_token_id: "{{ proxmox_api_token_id }}" - api_token_secret: "{{ proxmox_api_token_secret }}" - api_host: "{{ proxmox_api_host }}" - - vmid: "{{ container_vmid | default(omit) }}" - hostname: "{{ container_hostname | default(omit) }}" + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_vmid | default(omit) }}" + hostname: "{{ lxc_hostname | default(omit) }}" state: "stopped" register: stop_result failed_when: |- diff --git a/roles/proxmox-lxc-provision/tasks/update.yaml b/roles/proxmox-lxc-provision/tasks/update.yaml index f0daab7..afd5ed4 100755 --- a/roles/proxmox-lxc-provision/tasks/update.yaml +++ b/roles/proxmox-lxc-provision/tasks/update.yaml @@ -1,29 +1,22 @@ --- - name: Update an LXC container community.general.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 }}" - - vmid: "{{ container_vmid }}" - hostname: "{{ container_hostname }}" - password: "{{ container_password | default(omit) }}" # Updating password does not work - cores: "{{ container_cores }}" - memory: "{{ container_memory }}" - swap: "{{ container_swap }}" - disk: "{{ container_disk }}" - netif: '{"net0": "name=eth0,gw={{ container_gateway }},ip={{ container_ipv4 }},ip6={{ container_ipv6 | default(omit) }},bridge=vmbr0"}' - pubkey: "{{ lookup('file', container_pubkey_file) | default(omit) }}" - onboot: "{{ container_onboot | default(false) }}" - startup: "{{ container_startup | default(omit) }}" - features: "{{ container_features | default(omit) }}" - timezone: "{{ container_timezone | default(omit) }}" - nameserver: "{{ container_nameserver | default(omit) }}" + <<: "{{ proxmox_api_connection }}" + vmid: "{{ lxc_vmid }}" + hostname: "{{ lxc_hostname }}" + password: "{{ lxc_password | default(omit) }}" # Updating password does not work + cores: "{{ lxc_cores }}" + memory: "{{ lxc_memory }}" + swap: "{{ lxc_swap }}" + disk: "{{ lxc_disk }}" + netif: '{"net0": "name=eth0,gw={{ lxc_gateway }},ip={{ lxc_ipv4 }},ip6={{ lxc_ipv6 | default(omit) }},bridge=vmbr0"}' + pubkey: "{{ lookup('file', lxc_pubkey_file) | default(omit) }}" + onboot: "{{ lxc_onboot | default(false) }}" + startup: "{{ lxc_startup | default(omit) }}" + features: "{{ lxc_features | default(omit) }}" + timezone: "{{ lxc_timezone | default(omit) }}" + nameserver: "{{ lxc_nameserver | default(omit) }}" state: present - tags: "{{ container_tags | default(omit) }}" + tags: "{{ lxc_tags | default(omit) }}" update: true - register: container_result + register: lxc_result diff --git a/roles/proxmox-lxc-provision/tasks/wait.yaml b/roles/proxmox-lxc-provision/tasks/wait.yaml index 917f8d9..4b43b2e 100755 --- a/roles/proxmox-lxc-provision/tasks/wait.yaml +++ b/roles/proxmox-lxc-provision/tasks/wait.yaml @@ -7,12 +7,12 @@ - name: Debug - Check if container is in inventory ansible.builtin.debug: - msg: "Container {{ container_hostname }} found with IP: {{ hostvars[container_hostname]['ansible_host'] | default('NOT FOUND') }}" + msg: "Container {{ lxc_hostname }} found with IP: {{ hostvars[lxc_hostname]['ansible_host'] | default('NOT FOUND') }}" - name: Wait for SSH to become available ansible.builtin.wait_for: - host: "{{ hostvars[container_hostname]['ansible_host'] }}" + host: "{{ hostvars[lxc_hostname]['ansible_host'] }}" port: 22 delay: 3 state: started