Add incus server prep ansible stack

This commit is contained in:
Marty Oehme 2025-02-14 19:46:01 +01:00 committed by Marty Oehme
parent 6b96d0032a
commit 9e94dfbc52
6 changed files with 382 additions and 0 deletions

324
ansible/playbook.yaml Normal file
View file

@ -0,0 +1,324 @@
---
- name: Update system
hosts: all
tasks:
- name: Ensure aptitude installed
apt:
name: "aptitude"
state: present
tags:
- apt
become: true
- name: Ensure OS upgraded
apt:
upgrade: dist
tags:
- apt
- update
- os
become: true
- name: Check if reboot is necessary
register: reboot_required_file
stat:
path: /var/run/reboot-required
get_checksum: false
tags:
- os
- reboot
notify: reboot host
- name: All packages updated
apt:
name: "*"
state: latest # noqa 403
tags:
- apt
- update
- packages
become: true
handlers:
- name: Reboot host
reboot:
msg: "Reboot initiated by Ansible"
connect_timeout: 5
reboot_timeout: 600
pre_reboot_delay: 0
post_reboot_delay: 30
test_command: whoami
become: true
when: reboot_required_file.stat.exists
- name: Incus - Add package repository (apt)
hosts: all
gather_facts: true
gather_subset:
- "distribution_release"
vars:
task_release: "{{ incus_release | default('stable') }}"
task_roles: "{{ incus_roles | default(['standalone', 'ui']) }}"
any_errors_fatal: true
tasks:
- name: Check if distribution is supported
meta: end_play
when: 'ansible_distribution not in ("Ubuntu", "Debian")'
- name: Create apt keyring path
file:
path: /etc/apt/keyrings/
mode: 0755
state: directory
when: 'task_roles|length > 0 and task_release != "distro"'
- name: Add Zabbly repository key
copy:
src: files/zabbly-key.asc
dest: /etc/apt/keyrings/ansible-zabbly.asc
notify: Update apt
become: true
when: 'task_roles|length > 0 and task_release != "distro"'
- name: Get DPKG architecture
shell: dpkg --print-architecture
register: dpkg_architecture
changed_when: false
check_mode: no
when: 'task_roles|length > 0 and task_release != "distro"'
- name: Add Zabbly package source
template:
src: files/incus.sources.tpl
dest: /etc/apt/sources.list.d/ansible-zabbly-incus-{{ task_release }}.sources
notify: Update apt
become: true
when: 'task_roles|length > 0 and task_release != "distro"'
handlers:
- name: Update apt
apt:
force_apt_get: yes
update_cache: yes
cache_valid_time: 0
become: true
- name: Incus - Install packages and bootstrap
hosts: all
gather_facts: true
gather_subset:
- "default_ipv4"
- "default_ipv6"
- "distribution_release"
vars:
task_init: "{{ incus_init | default('{}') }}"
task_ip_address: "{{ incus_ip_address | default(ansible_default_ipv6['address'] | default(ansible_default_ipv4['address'])) }}"
task_name: "{{ incus_name | default('') }}"
task_roles: "{{ incus_roles | default(['ui', 'standalone']) }}"
task_ovn_northbound: "{{ lookup('template', '../files/ovn/ovn-central.servers.tpl') | from_yaml | map('regex_replace', '^(.*)$', 'ssl:[\\1]:6641') | join(',') }}"
task_servers: "{{ lookup('template', 'files/incus.servers.tpl') | from_yaml | sort }}"
any_errors_fatal: true
become: true
tasks:
- name: Install the Incus package (deb)
apt:
name:
- incus
install_recommends: no
state: present
register: install_deb
when: 'ansible_distribution in ("Debian", "Ubuntu") and task_roles | length > 0'
- name: Install the Incus package (rpm)
ansible.builtin.package:
name:
- incus
state: present
register: install_rpm
when: 'ansible_distribution == "CentOS" and task_roles | length > 0'
- name: Install the Incus UI package (deb)
apt:
name:
- incus-ui-canonical
install_recommends: no
state: present
when: 'ansible_distribution in ("Debian", "Ubuntu") and "ui" in task_roles'
# - name: Install btrfs tools
# ansible.builtin.package:
# name:
# - btrfs-progs
# state: present
# when: "task_roles | length > 0 and 'btrfs' in task_init['storage'] | dict2items | json_query('[].value.driver')"
#
# - name: Install ceph tools
# ansible.builtin.package:
# name:
# - ceph-common
# state: present
# when: "task_roles | length > 0 and 'ceph' in task_init['storage'] | dict2items | json_query('[].value.driver')"
#
# - name: Install LVM tools
# ansible.builtin.package:
# name:
# - lvm2
# state: present
# when: "task_roles | length > 0 and 'lvm' in task_init['storage'] | dict2items | json_query('[].value.driver')"
#
# - name: Install ZFS dependencies
# ansible.builtin.package:
# name:
# - zfs-dkms
# state: present
# when: "task_roles | length > 0 and 'zfs' in task_init['storage'] | dict2items | json_query('[].value.driver') and ansible_distribution == 'Debian'"
#
# - name: Install ZFS tools
# ansible.builtin.package:
# name:
# - zfsutils-linux
# state: present
# when: "task_roles | length > 0 and 'zfs' in task_init['storage'] | dict2items | json_query('[].value.driver')"
- name: Set uid allocation
shell:
cmd: "usermod root --add-subuids 10000000-1009999999"
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
- name: Set gid allocation
shell:
cmd: "usermod root --add-subgids 10000000-1009999999"
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
- name: Enable incus socket unit
systemd:
enabled: true
name: incus.socket
state: started
when: 'install_deb.changed or install_rpm.changed'
- name: Enable incus service unit
systemd:
enabled: true
name: incus.service
state: started
when: 'install_deb.changed or install_rpm.changed'
- name: Enable incus startup unit
systemd:
enabled: true
name: incus-startup.service
state: started
when: 'install_deb.changed or install_rpm.changed'
- name: Set client listen address
shell:
cmd: "incus --force-local config set core.https_address {{ task_ip_address }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Set cluster listen address
shell:
cmd: "incus --force-local config set cluster.https_address {{ task_ip_address }}"
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] == inventory_hostname'
# - name: Set OVN NorthBound database
# shell:
# cmd: "incus --force-local config set network.ovn.northbound_connection={{ task_ovn_northbound }} network.ovn.client_cert=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/'+inventory_hostname+'.crt') }}\" network.ovn.client_key=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/'+inventory_hostname+'.key') }}\" network.ovn.ca_cert=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/ca.crt') }}\""
# notify: Restart Incus
# when: '(install_deb.changed or install_rpm.changed) and task_ovn_northbound and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Add networks
shell:
cmd: "incus network create {{ item.key }} --type={{ item.value.type }}{% for k in item.value.local_config | default([]) %} {{ k }}={{ item.value.local_config[k] }}{% endfor %}{% for k in item.value.config | default([]) %} {{ k }}={{ item.value.config[k] }}{% endfor %}"
loop: "{{ task_init['network'] | dict2items }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Set network description
shell:
cmd: "incus network set --property {{ item.key }} description=\"{{ item.value.description }}\""
loop: "{{ task_init['network'] | dict2items }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname)) and item.value.description | default(None)'
- name: Add storage pools
shell:
cmd: "incus storage create {{ item.key }} {{ item.value.driver }}{% for k in item.value.local_config | default([]) %} {{ k }}={{ item.value.local_config[k] }}{% endfor %}{% for k in item.value.config | default([]) %} {{ k }}={{ item.value.config[k] }}{% endfor %}"
loop: "{{ task_init['storage'] | dict2items }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Set storage pool description
shell:
cmd: "incus storage set --property {{ item.key }} description=\"{{ item.value.description }}\""
loop: "{{ task_init['storage'] | dict2items }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname)) and item.value.description | default(None)'
- name: Add storage pool to default profile
shell:
cmd: "incus profile device add default root disk path=/ pool={{ item }}"
loop: "{{ task_init['storage'] | dict2items | json_query('[?value.default].key') }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Add network to default profile
shell:
cmd: "incus profile device add default eth0 nic network={{ item }} name=eth0"
loop: "{{ task_init['network'] | dict2items | json_query('[?value.default].key') }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Bootstrap the cluster
shell:
cmd: "incus --force-local cluster enable {{ inventory_hostname }}"
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] == inventory_hostname'
- name: Create join tokens
delegate_to: "{{ task_servers[0] }}"
shell:
cmd: "incus --force-local --quiet cluster add {{ inventory_hostname }}"
register: cluster_add
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] != inventory_hostname'
- name: Wait 5s to avoid token use before valid
ansible.builtin.wait_for:
timeout: 5
delegate_to: localhost
when: 'cluster_add.changed'
- name: Join the cluster
throttle: 1
shell:
cmd: "incus --force-local admin init --preseed"
stdin: |-
cluster:
enabled: true
cluster_address: "{{ task_ip_address }}"
cluster_token: "{{ cluster_add.stdout }}"
server_address: "{{ task_ip_address }}"
member_config: {% for pool in task_init.storage %}{% for key in task_init.storage[pool].local_config | default([]) %}
- entity: storage-pool
name: {{ pool }}
key: {{ key }}
value: {{ task_init.storage[pool].local_config[key] }}{% endfor %}{% endfor %}{% for network in task_init.network %}{% for key in task_init.network[network].local_config | default([]) %}
- entity: network
name: {{ network }}
key: {{ key }}
value: {{ task_init.network[network].local_config[key] }}{% endfor %}{% endfor %}
when: 'cluster_add.changed'
- name: Apply additional configuration
shell:
cmd: "incus config set {{ item.key }}=\"{{ item.value }}\""
loop: "{{ task_init['config'] | default({}) | dict2items }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
- name: Load client certificates
shell:
cmd: "incus config trust add-certificate --name \"{{ item.key }}\" --type={{ item.value.type | default('client') }} -"
stdin: "{{ item.value.certificate }}"
loop: "{{ task_init['clients'] | default({}) | dict2items }}"
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
handlers:
- name: Restart Incus
systemd:
name: incus.service
state: restarted