You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
7.2 KiB
201 lines
7.2 KiB
- 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: "{{ 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
|
|
|