๐Ÿ“— Ansible playbooks and roles for building an idempotent, interconnected and scalable infrastructure
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.
 
 
ansible-playbooks/roles/container/tasks/main.yml

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: "{{ 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