Compare commits
14 commits
779266684d
...
6e30232057
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e30232057 | |||
| 66ce16ce55 | |||
| 2fc23d9774 | |||
| b493485b90 | |||
| 8019fa9276 | |||
| bb9de502ce | |||
| a217d65640 | |||
| d8ed04f4d1 | |||
| 5f737ab4b5 | |||
| 5257525c7e | |||
| 0de79fc1d2 | |||
| e6194e35bf | |||
| 54b8404743 | |||
| 66d1032869 |
19 changed files with 319 additions and 227 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1 +1,4 @@
|
||||||
vaultpass
|
vaultpass
|
||||||
|
|
||||||
|
/.ansible
|
||||||
|
/temp/
|
||||||
|
|
|
||||||
57
README.md
57
README.md
|
|
@ -17,3 +17,60 @@ and media management applications jellyfin and audiobookshelf.
|
||||||
Media can be requested through Jellyseerr.
|
Media can be requested through Jellyseerr.
|
||||||
|
|
||||||
Served through homarr personal dashboard.
|
Served through homarr personal dashboard.
|
||||||
|
|
||||||
|
## Paperless stack
|
||||||
|
|
||||||
|
Hosts all my personal documents. This is an important stack which should be backed up accordingly.
|
||||||
|
|
||||||
|
## Grocy stack
|
||||||
|
|
||||||
|
Was an experimental stack which I may have used in my home for shopping lists, ingredient tracking,
|
||||||
|
and more.
|
||||||
|
|
||||||
|
After some consideration and experimentation, for the moment, I have decided against using grocy:
|
||||||
|
it provides comprehensive tracking but also requires comprehensive use to get the most out of it.
|
||||||
|
|
||||||
|
I get the feeling a badly implemented/maintained grocy setup is _worse_ than a simpler task-list and
|
||||||
|
e.g. Recipe KanBan board approach.
|
||||||
|
|
||||||
|
## Thoughts on organization
|
||||||
|
|
||||||
|
.
|
||||||
|
ansible
|
||||||
|
roles
|
||||||
|
system
|
||||||
|
infrastructure -> calls tofu role
|
||||||
|
arr
|
||||||
|
paperless
|
||||||
|
...
|
||||||
|
|
||||||
|
tofu
|
||||||
|
incus_machines
|
||||||
|
incus_networks?
|
||||||
|
incus_storage?
|
||||||
|
|
||||||
|
### Production IaC
|
||||||
|
|
||||||
|
- ansible:
|
||||||
|
host_roles:
|
||||||
|
system
|
||||||
|
filesystem
|
||||||
|
- terraform:
|
||||||
|
infrastructure (tofu)
|
||||||
|
- ansible:
|
||||||
|
instance_roles:
|
||||||
|
caddy
|
||||||
|
arr
|
||||||
|
paperless
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- terraform? ansible?
|
||||||
|
- create 'host' VM
|
||||||
|
- ensure connection to host vm as part of host group
|
||||||
|
- ansible:
|
||||||
|
host_roles: ...
|
||||||
|
- tf:
|
||||||
|
infra...
|
||||||
|
- ansible:
|
||||||
|
instance_roles:...
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
[defaults]
|
[defaults]
|
||||||
remote_tmp = /tmp
|
remote_tmp = /tmp
|
||||||
inventory = inventory
|
inventory = inventory
|
||||||
|
roles_path = .ansible/roles:roles
|
||||||
vault_password_file = vaultpass
|
|
||||||
|
|
|
||||||
5
justfile
Normal file
5
justfile
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
install:
|
||||||
|
ansible-galaxy install -r requirements.yaml
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
pass show hosting/ansible/bob/vault-password | ansible-playbook --vault-password-file=/bin/cat site.yaml
|
||||||
4
requirements.yaml
Normal file
4
requirements.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Install and pre-configure incus
|
||||||
|
- src: gliech.incus
|
||||||
|
# install and set up docker
|
||||||
|
- src: geerlingguy.docker
|
||||||
38
roles/filesystem/README.md
Normal file
38
roles/filesystem/README.md
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
filesystem
|
||||||
|
=========
|
||||||
|
|
||||||
|
Mounts the filesystem(s) required for bob.
|
||||||
|
Focused on correct `btrfs` layout and mounting,
|
||||||
|
but also mounts an external `ext4` HDD by default.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
This role requires a btrfs filesystem _existing_ on _any device_ that is targeted with the role (using the 'btrfs_mounts') configuration option.
|
||||||
|
Optionally, an external HDD is required if the mount toggle is true.
|
||||||
|
|
||||||
|
Role Variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`btrfs_mounts` can be used to set up the various (top-level) btrfs subvolumes, and their later mount points in the system.
|
||||||
|
Define an entry by giving the `uuid` of the targeted btrfs filesystem (or device), give the name of the `subvol` you intend to give, and define the `path` where it should ultimately be mounted by `fstab`.
|
||||||
|
You can additionally provide some `opts` which are given to `fstab` for the mount process as well.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
btrfs_mounts:
|
||||||
|
- path: "/home"
|
||||||
|
subvol: "@home"
|
||||||
|
uuid: "3204f33f-5fa7-4c11-bdd8-979c539fce91"
|
||||||
|
opts: "defaults,ssd,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
|
||||||
|
- path: "/srv/media"
|
||||||
|
subvol: "@media"
|
||||||
|
uuid: "2256bd23-7751-486a-bfc4-b216a6b0c4f4"
|
||||||
|
opts: "defaults,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`should_mount_external_hdd` can be toggled to automatically mount a USB-connected HDD on boot, or not.
|
||||||
30
roles/filesystem/defaults/main.yaml
Normal file
30
roles/filesystem/defaults/main.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
should_mount_external_hdd: true
|
||||||
|
should_reboot_machine: false
|
||||||
|
|
||||||
|
btrfs_mounts:
|
||||||
|
- path: "/"
|
||||||
|
subvol: "@rootfs"
|
||||||
|
uuid: "3204f33f-5fa7-4c11-bdd8-979c539fce91"
|
||||||
|
opts: "defaults,ssd,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
- path: "/home"
|
||||||
|
subvol: "@home"
|
||||||
|
uuid: "3204f33f-5fa7-4c11-bdd8-979c539fce91"
|
||||||
|
opts: "defaults,ssd,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
|
||||||
|
- path: "/srv/media"
|
||||||
|
subvol: "@media"
|
||||||
|
uuid: "2256bd23-7751-486a-bfc4-b216a6b0c4f4"
|
||||||
|
opts: "defaults,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
- path: "/srv/files"
|
||||||
|
subvol: "@files"
|
||||||
|
uuid: "2256bd23-7751-486a-bfc4-b216a6b0c4f4"
|
||||||
|
opts: "defaults,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
- path: "/srv/documents"
|
||||||
|
subvol: "@documents"
|
||||||
|
uuid: "2256bd23-7751-486a-bfc4-b216a6b0c4f4"
|
||||||
|
opts: "defaults,noatime,compress=zstd:3,space_cache=v2"
|
||||||
|
- path: "/srv/wolf"
|
||||||
|
subvol: "@wolf"
|
||||||
|
uuid: "2256bd23-7751-486a-bfc4-b216a6b0c4f4"
|
||||||
|
opts: "defaults,noatime,compress=zstd:1,space_cache=v2"
|
||||||
7
roles/filesystem/handlers/main.yaml
Normal file
7
roles/filesystem/handlers/main.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Reboot machine
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
connect_timeout: 600
|
||||||
|
post_reboot_delay: 10
|
||||||
|
when: "should_reboot_machine"
|
||||||
30
roles/filesystem/tasks/main.yaml
Normal file
30
roles/filesystem/tasks/main.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
- name: Ensure btrfs ROOT layout
|
||||||
|
community.general.btrfs_subvolume:
|
||||||
|
name: "/{{ item.subvol }}"
|
||||||
|
# filesystem_device: /dev/sdb1
|
||||||
|
# fileystem_label: btrfs-root # only 1 of the 3 required
|
||||||
|
filesystem_uuid: "{{ item.uuid }}"
|
||||||
|
loop: "{{ btrfs_mounts }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Ensure fstab contains btrfs mount entries
|
||||||
|
ansible.posix.mount:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
src: "UUID={{ item.uuid }}"
|
||||||
|
fstype: btrfs
|
||||||
|
opts: "{{ item.opts }},subvol={{ item.subvol }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ btrfs_mounts }}"
|
||||||
|
become: true
|
||||||
|
notify: Reboot machine
|
||||||
|
|
||||||
|
- name: Ensure external HDD is mounted
|
||||||
|
ansible.posix.mount:
|
||||||
|
path: /mnt/ext
|
||||||
|
src: "UUID=01b221f2-83a5-49e4-bdef-ee9ee9ac5310"
|
||||||
|
fstype: ext4
|
||||||
|
opts: "noatime"
|
||||||
|
state: present
|
||||||
|
become: true
|
||||||
|
when: "should_mount_external_hdd"
|
||||||
2
roles/filesystem/vars/main.yaml
Normal file
2
roles/filesystem/vars/main.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# vars file for btrfs
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
---
|
|
||||||
- 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)
|
|
||||||
ansible.builtin.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)
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: "usermod root --add-subuids 10000000-1009999999"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
|
|
||||||
|
|
||||||
- name: Set gid allocation
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
enabled: true
|
|
||||||
name: incus.socket
|
|
||||||
state: started
|
|
||||||
when: "install_deb.changed or install_rpm.changed"
|
|
||||||
|
|
||||||
- name: Enable incus service unit
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
enabled: true
|
|
||||||
name: incus.service
|
|
||||||
state: started
|
|
||||||
when: "install_deb.changed or install_rpm.changed"
|
|
||||||
|
|
||||||
- name: Enable incus startup unit
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
enabled: true
|
|
||||||
name: incus-startup.service
|
|
||||||
state: started
|
|
||||||
when: "install_deb.changed or install_rpm.changed"
|
|
||||||
|
|
||||||
- name: Set client listen address
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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] }}"
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.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
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
name: incus.service
|
|
||||||
state: restarted
|
|
||||||
70
roles/incus-install/tasks/install.yaml
Normal file
70
roles/incus-install/tasks/install.yaml
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
# required by gliech.incus role
|
||||||
|
- name: Ensure lxc conf directory exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: /etc/lxc
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install incus
|
||||||
|
ansible.builtin.import_role:
|
||||||
|
name: gliech.incus
|
||||||
|
vars:
|
||||||
|
incus_config:
|
||||||
|
config:
|
||||||
|
core.https_address: "[::]:8443"
|
||||||
|
networks:
|
||||||
|
- config:
|
||||||
|
ipv4.address: 10.172.89.1/24
|
||||||
|
ipv4.firewall: "true"
|
||||||
|
ipv4.nat: "true"
|
||||||
|
ipv6.address: fd42:c9d2:6e9f:be57::1/64
|
||||||
|
ipv6.nat: "true"
|
||||||
|
description: ""
|
||||||
|
name: incusbr0
|
||||||
|
type: bridge
|
||||||
|
project: default
|
||||||
|
storage_pools:
|
||||||
|
- config:
|
||||||
|
source: /var/lib/incus/storage-pools/default
|
||||||
|
volatile.initial_source: /var/lib/incus/storage-pools/default
|
||||||
|
description: ""
|
||||||
|
name: default
|
||||||
|
driver: btrfs
|
||||||
|
- config:
|
||||||
|
size: 50GiB
|
||||||
|
source: /var/lib/incus/disks/docker_store.img
|
||||||
|
description: ""
|
||||||
|
name: docker_store
|
||||||
|
driver: btrfs
|
||||||
|
storage_volumes: []
|
||||||
|
profiles:
|
||||||
|
- config: {}
|
||||||
|
description: Default Incus profile
|
||||||
|
devices:
|
||||||
|
eth0:
|
||||||
|
name: eth0
|
||||||
|
network: incusbr0
|
||||||
|
type: nic
|
||||||
|
root:
|
||||||
|
path: /
|
||||||
|
pool: default
|
||||||
|
type: disk
|
||||||
|
name: default
|
||||||
|
project: ""
|
||||||
|
projects:
|
||||||
|
- config:
|
||||||
|
features.images: "true"
|
||||||
|
features.networks: "true"
|
||||||
|
features.networks.zones: "true"
|
||||||
|
features.profiles: "true"
|
||||||
|
features.storage.buckets: "true"
|
||||||
|
features.storage.volumes: "true"
|
||||||
|
restricted: "false"
|
||||||
|
description: NAS
|
||||||
|
name: default
|
||||||
|
certificates: []
|
||||||
|
cluster_groups: []
|
||||||
|
# # TODO: Should presumably be split
|
||||||
|
# - name: "Install and bootstrap incus"
|
||||||
|
# ansible.builtin.include_tasks: bootstrap.yaml
|
||||||
|
# when: ansible_distribution == "Debian" and ansible_distribution_release == "bookworm"
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
---
|
---
|
||||||
- name: "Add incus repository to system"
|
## for bookworm only
|
||||||
|
- name: "Add incus repository to bookworm system"
|
||||||
ansible.builtin.include_tasks: add-repo.yaml
|
ansible.builtin.include_tasks: add-repo.yaml
|
||||||
|
when: ansible_distribution == "Debian" and ansible_distribution_release == "bookworm"
|
||||||
|
|
||||||
# TODO: Should presumably be split
|
# TODO: there might be remaining issues on other OSes like centos, etc
|
||||||
- name: "Install and bootstrap incus"
|
- name: Install incus
|
||||||
ansible.builtin.include_tasks: bootstrap.yaml
|
ansible.builtin.include_tasks: install.yaml
|
||||||
|
|
|
||||||
16
roles/system/defaults/main.yaml
Normal file
16
roles/system/defaults/main.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
system_timezone: "Europe/Berlin"
|
||||||
|
system_users:
|
||||||
|
- name: marty
|
||||||
|
groups:
|
||||||
|
- marty
|
||||||
|
- data
|
||||||
|
- incus-admin
|
||||||
|
authorized_keys:
|
||||||
|
- "{{ lookup('file', '~/.ssh/keys/bob.pub') }}"
|
||||||
|
- name: data
|
||||||
|
groups:
|
||||||
|
- data
|
||||||
|
create_home: false
|
||||||
|
shell: /sbin/nologin
|
||||||
|
|
@ -36,3 +36,38 @@
|
||||||
- packages
|
- packages
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
|
- name: Set correct timezone
|
||||||
|
community.general.timezone:
|
||||||
|
name: "{{ system_timezone }}"
|
||||||
|
when: "system_timezone"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create necessary groups
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ system_users | map(attribute='groups') | flatten | unique }}"
|
||||||
|
when: "system_users"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Set up system users
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
groups: "{{ item.groups }}"
|
||||||
|
append: "{{ item.append | default(true) }}"
|
||||||
|
create_home: "{{ item.create_home | default(false) }}"
|
||||||
|
shell: "{{ item.shell | default('/bin/bash') }}"
|
||||||
|
loop: "{{ system_users }}"
|
||||||
|
when: "system_users"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Add authorized SSH keys
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ item.name }}"
|
||||||
|
state: present
|
||||||
|
key: "{{ item.authorized_keys }}"
|
||||||
|
loop: "{{ system_users }}"
|
||||||
|
when: system_users is defined and item.authorized_keys is defined
|
||||||
|
tags:
|
||||||
|
- ssh
|
||||||
|
become: true
|
||||||
|
|
|
||||||
16
site.yaml
16
site.yaml
|
|
@ -15,16 +15,30 @@
|
||||||
register: pythoncheck
|
register: pythoncheck
|
||||||
- name: install debian python
|
- name: install debian python
|
||||||
ansible.builtin.raw: apt-get update && apt-get install python3 -y
|
ansible.builtin.raw: apt-get update && apt-get install python3 -y
|
||||||
when: pythoncheck.rc == 127
|
when: not ansible_check_mode and pythoncheck.rc == 127
|
||||||
|
- name: pretend installing debian python for check mode
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: Pretending to install python...
|
||||||
|
when: ansible_check_mode
|
||||||
|
|
||||||
- name: Prepare incus server host
|
- name: Prepare incus server host
|
||||||
hosts: host_system
|
hosts: host_system
|
||||||
tasks:
|
tasks:
|
||||||
|
- name: Prepare host filesystems
|
||||||
|
ansible.builtin.import_role:
|
||||||
|
name: filesystem
|
||||||
|
tags: filesystem
|
||||||
|
|
||||||
- name: Prepare system
|
- name: Prepare system
|
||||||
ansible.builtin.import_role:
|
ansible.builtin.import_role:
|
||||||
name: system
|
name: system
|
||||||
tags: system
|
tags: system
|
||||||
|
|
||||||
|
- name: Set up incus
|
||||||
|
ansible.builtin.import_role:
|
||||||
|
name: incus-install
|
||||||
|
tags: incus
|
||||||
|
|
||||||
- name: Set up nfs shares
|
- name: Set up nfs shares
|
||||||
ansible.builtin.import_role:
|
ansible.builtin.import_role:
|
||||||
name: nfs
|
name: nfs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue