- name: specify connection parameters set_fact: pm_api_host: "{{ hostvars[selected_node]['ansible_host'] | mandatory }}" pm_api_user: "{{ hostvars[selected_node]['api_user'] | d('root@pam') }}" pm_api_password: "{{ hostvars[selected_node]['api_password'] | d(hostvars[selected_node]['ansible_password']) }}" pm_lxc_storage: "{{ 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) or (container_password 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 pip3 is installed on local node package: name: py3-pip 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: 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: "{{ hardware.cores }}" cpus: "{{ hardware.cpus }}" cpuunits: "{{ hardware.cpuunits }}" disk: "{{ hardware.disk | string }}" memory: "{{ hardware.memory }}" swap: "{{ hardware.swap }}" description: "{{ container_description | d(omit) }}" hostname: "{{ inventory_hostname }}" pool: "{{ container_pool | d(omit) }}" vmid: "{{ container_id }}" password: "{{ container_password }}" pubkey: "{{ (container_key | d({})).public_key | d(omit) }}" ostemplate: "local:vztmpl/{{ container_template[container_distro] }}" netif: "{\"net0\":\ \"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=vmbr0,\ firewall=0,\ tag={{ networks[container_network].tag }},\ type=veth,\ mtu={{ container_mtu | d(hostvars[selected_node]['container_mtu'] | d(1500)) }}\"}" 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 container_default_nameserver is defined -%}\ {{ container_default_nameserver }}\ {%- else -%}\ {{ omit }}\ {%- endif -%}" onboot: yes proxmox_default_behavior: no_defaults storage: "{{ pm_lxc_storage }}" unprivileged: yes timeout: 240 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" 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" regexp: "^{{ item.name }}:(\\s*).*$" line: "{{ item.name | mandatory }}:\\g<1>{{ item.value | mandatory }}" backrefs: yes loop: - { name: cpus, value: "{{ hardware.cpus }}" } - { name: cores, value: "{{ [hardware.cores, hostvars[selected_node]['max_cores'] | d(hardware.cores)] | min }}" } - { name: cpuunits, value: "{{ hardware.cpuunits }}" } - { name: memory, value: "{{ hardware.memory }}" } - { name: swap, value: "{{ 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" regexp: '^startup:.*$' line: "startup: {{ 'order=' ~ (container_order | d(role_dependency[host_primary_role] | d('0'))) ~ ((',up=' ~ container_startup_delay) if container_startup_delay is defined else '') }}" insertbefore: '^[^\#]' firstmatch: yes when: (container_order is defined) or (role_dependency[host_primary_role] is defined) or (container_startup_delay is defined) - name: ensure that cpulimit is not set lineinfile: path: "/etc/pve/lxc/{{ container_id }}.conf" 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' }}" - 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: 127.0.0.1 - name: preconfigure container include_tasks: preconf.yml