- name: specify connection parameters set_fact: pm_api_host: "{{ hostvars[selected_node]['ansible_host'] }}" pm_api_user: "{{ hostvars[selected_node]['api_user'] | d('root@pam') }}" pm_api_password: "{{ hostvars[selected_node]['api_password'] | d(hostvars[selected_node]['host_password'] | d(hostvars[selected_node]['ansible_password'])) }}" pm_lxc_storage: "{{ container_storage | d(hostvars[selected_node]['lxc_storage'] | d('local-zfs')) }}" no_log: yes - name: validate template and distribution parameters fail: msg: some container parameters are missing or invalid when: (container_distro is not defined) or (container_template is not mapping) or (container_template[container_distro] is not defined) or (container_id is not defined) - name: ensure pool exists on cluster node command: cmd: "pveum pool add {{ container_pool | quote }}" register: pool_res changed_when: pool_res.rc == 0 failed_when: (pool_res.rc != 0) and not ((pool_res.rc == 255) and ('already exists' in pool_res.stderr)) when: container_pool is defined delegate_to: "{{ selected_node }}" - block: - name: ensure python dependencies are installed on local node package: name: - py3-pip - py3-requests - py3-netaddr run_once: yes - name: ensure proxmoxer is installed on local node pip: name: proxmoxer run_once: yes - name: generate host ssh key include_tasks: gen_ssh_key.yml when: use_ssh_keys | d(true) == true - name: ensure there is a container template community.general.proxmox_template: node: "{{ selected_node }}" api_host: "{{ pm_api_host }}" api_user: "{{ pm_api_user }}" api_password: "{{ pm_api_password }}" content_type: vztmpl template: "{{ container_template[container_distro] }}" validate_certs: no timeout: 20 - name: build container network section set_fact: container_network_cfg: "{{ { 'name': 'eth0', 'hwaddr': container_mac | d(mac_prefix | community.general.random_mac(seed=inventory_hostname)), 'ip': ansible_host ~ '/' ~ networks[container_network].gw | ansible.utils.ipaddr('prefix'), 'gw': networks[container_network].gw | ansible.utils.ipaddr('address'), 'bridge': container_bridge | d('vmbr0'), 'firewall': 0, 'tag': networks[container_network].tag | d(None), 'type': 'veth', 'mtu': container_mtu | d(hostvars[selected_node]['container_mtu'] | d(1500)) } | dict2items | rejectattr('value', 'equalto', None) | list | items2dict }}" - name: create container if not exists community.general.proxmox: node: "{{ selected_node }}" api_host: "{{ pm_api_host }}" api_user: "{{ pm_api_user }}" api_password: "{{ pm_api_password }}" cores: "{{ host_hardware.cores }}" cpus: "{{ host_hardware.cpus }}" cpuunits: "{{ host_hardware.cpuunits }}" disk: "{{ host_hardware.disk | string }}" memory: "{{ host_hardware.memory }}" swap: "{{ host_hardware.swap }}" description: "{{ container_description | d(omit) }}" hostname: "{{ host_name }}" pool: "{{ container_pool | d(omit) }}" vmid: "{{ container_id }}" password: "{{ host_password }}" pubkey: "{{ (host_ssh_key | d({})).public_key | d(omit) }}" ostemplate: "local:vztmpl/{{ container_template[container_distro] }}" onboot: yes proxmox_default_behavior: no_defaults storage: "{{ pm_lxc_storage }}" unprivileged: yes timeout: 240 netif: "{{ { 'net0': container_network_cfg.keys() | zip(container_network_cfg.values()) | map('join', '=') | join(',') } | to_json(sort_keys=true) }}" nameserver: "{%- if container_nameserver is defined -%}\ {{ hostvars[container_nameserver]['ansible_host'] }}\ {%- elif services.filtering_ns is defined -%}\ {%- if services.filtering_ns | type_debug == 'list' -%} {{ hostvars[services.filtering_ns[0].hostname]['ansible_host'] }}\ {%- else -%} {{ hostvars[services.filtering_ns.hostname]['ansible_host'] }}\ {%- endif -%} {%- elif nameserver is defined -%}\ {{ nameserver }}\ {%- else -%}\ {{ omit }}\ {%- endif -%}" mounts: >- { {%- for item in (container_mounts | d([])) -%} "{{ item.id }}":"{{ pm_lxc_storage }}:{{ item.size | mandatory }},mp={{ item.mp | mandatory }}{% if item.readonly is defined and item.readonly %},ro=1{% endif %}", {%- endfor -%} } - block: - name: add features to lxc config lineinfile: path: "{{ ('/etc/pve/lxc', container_id ~ '.conf') | path_join }}" line: "features: {{ container_features | join(',') }}" when: container_features | d([]) | length > 0 - name: check that lxc config is correct lineinfile: path: "{{ ('/etc/pve/lxc', container_id ~ '.conf') | path_join }}" regexp: "^{{ item.name }}:(\\s*).*$" line: "{{ item.name | mandatory }}:\\g<1>{{ item.value | mandatory }}" backrefs: yes loop: - { name: cpus, value: "{{ host_hardware.cpus }}" } - { name: cores, value: "{{ [host_hardware.cores, hostvars[selected_node]['max_cores'] | d(host_hardware.cores)] | min }}" } - { name: cpuunits, value: "{{ host_hardware.cpuunits }}" } - { name: memory, value: "{{ host_hardware.memory }}" } - { name: swap, value: "{{ host_hardware.swap }}" } - { name: onboot, value: "{{ '1' if (container_active | d(true) == true) else '0' }}" } - name: set startup order and delay lineinfile: path: "{{ ('/etc/pve/lxc', container_id ~ '.conf') | path_join }}" regexp: '^startup:.*$' line: "startup: {{ 'order=' ~ (container_order | d(role_dependency_index | d('0'))) ~ ((',up=' ~ container_startup_delay) if container_startup_delay is defined else '') }}" insertbefore: '^[^\#]' firstmatch: yes when: (container_order is defined) or (role_dependency_index is defined) or (container_startup_delay is defined) - name: ensure that cpulimit is not set lineinfile: path: "{{ ('/etc/pve/lxc', container_id ~ '.conf') | path_join }}" regexp: '^cpulimit:.*$' state: absent delegate_to: "{{ selected_node }}" - name: start/stop container community.general.proxmox: node: "{{ selected_node }}" api_host: "{{ pm_api_host }}" api_user: "{{ pm_api_user }}" api_password: "{{ pm_api_password }}" vmid: "{{ container_id }}" proxmox_default_behavior: no_defaults state: "{{ 'started' if (container_active | d(true) == true) else 'stopped' }}" unprivileged: yes - name: end playbook for current host if container is set to inactive meta: end_host when: container_active | d(true) == false - name: wait until networking is avaliable command: cmd: "ping -c1 -W1 {{ ansible_host | quote }}" register: ping_result until: ping_result.rc == 0 retries: 5 delay: 2 changed_when: no delegate_to: localhost - name: preconfigure container include_tasks: preconf.yml