summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.yml1
-rw-r--r--host_vars/pve.local.ymlbin737 -> 822 bytes
-rw-r--r--host_vars/pve.local.yml.example8
-rw-r--r--molecule/proxmox/converge.yml1
-rw-r--r--roles/pve-network/defaults/main.yml2
-rw-r--r--roles/pve-network/handlers/main.yml16
-rw-r--r--roles/pve-network/meta/argument_specs.yml32
-rw-r--r--roles/pve-network/meta/main.yml13
-rw-r--r--roles/pve-network/tasks/main.yml36
-rw-r--r--roles/pve-network/templates/ethernet.nmconnection.j216
-rw-r--r--roles/pve-network/templates/vmbr0.nmconnection.j229
-rw-r--r--roles/pve/defaults/main.yml2
-rw-r--r--roles/pve/meta/argument_specs.yml8
-rw-r--r--roles/pve/tasks/main.yml20
14 files changed, 170 insertions, 14 deletions
diff --git a/configure.yml b/configure.yml
index db599780..466103c0 100644
--- a/configure.yml
+++ b/configure.yml
@@ -103,6 +103,7 @@
- pve.local
roles:
- role: "pve"
+ - role: "pve-network"
- role: "locales"
- role: "timezone"
- role: "bash"
diff --git a/host_vars/pve.local.yml b/host_vars/pve.local.yml
index ce9097fc..a0465c97 100644
--- a/host_vars/pve.local.yml
+++ b/host_vars/pve.local.yml
Binary files differ
diff --git a/host_vars/pve.local.yml.example b/host_vars/pve.local.yml.example
index def72e3b..f804ba67 100644
--- a/host_vars/pve.local.yml.example
+++ b/host_vars/pve.local.yml.example
@@ -9,10 +9,14 @@ network_ipv4_address: "10.0.0.253"
network_ipv4_gateway: "10.0.0.254"
network_ipv4_dns: "10.0.0.254"
-restic_version: "0.19.0"
+pve_network_interface: "enp0s25"
pve_admin_user: "admin"
pve_admin_password: "changeme"
+pve_lvm_device: "/dev/sda4"
+pve_lvm_vg_name: "pve"
+
+restic_version: "0.19.0"
-ethtool_wol_interface: "eth0"
+ethtool_wol_interface: "enp0s25"
ethtool_lid_ac_action: "ignore"
diff --git a/molecule/proxmox/converge.yml b/molecule/proxmox/converge.yml
index c383777a..46ae7f76 100644
--- a/molecule/proxmox/converge.yml
+++ b/molecule/proxmox/converge.yml
@@ -49,6 +49,7 @@
ansible_facts: "{{ ansible_facts | combine({'is_chroot': false}) }}"
roles:
- role: "pve"
+ - role: "pve-network"
- role: "locales"
- role: "timezone"
- role: "bash"
diff --git a/roles/pve-network/defaults/main.yml b/roles/pve-network/defaults/main.yml
new file mode 100644
index 00000000..f56c943e
--- /dev/null
+++ b/roles/pve-network/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+pve_network_interface: "eth0"
diff --git a/roles/pve-network/handlers/main.yml b/roles/pve-network/handlers/main.yml
new file mode 100644
index 00000000..7a4ce4c0
--- /dev/null
+++ b/roles/pve-network/handlers/main.yml
@@ -0,0 +1,16 @@
+---
+- name: "Restart NetworkManager"
+ become: true
+ ansible.builtin.systemd_service:
+ name: "NetworkManager"
+ state: "restarted"
+ async: 10
+ poll: 0
+
+- name: "Restart pveproxy"
+ become: true
+ ansible.builtin.systemd_service:
+ name: "pveproxy"
+ state: "restarted"
+ tags:
+ - "molecule-notest"
diff --git a/roles/pve-network/meta/argument_specs.yml b/roles/pve-network/meta/argument_specs.yml
new file mode 100644
index 00000000..6f93a13b
--- /dev/null
+++ b/roles/pve-network/meta/argument_specs.yml
@@ -0,0 +1,32 @@
+---
+argument_specs:
+ main:
+ options:
+ pve_network_interface:
+ type: "str"
+ description: "Physical ethernet interface to add as bridge port"
+ default: "enp0s25"
+ network_ipv4_address:
+ type: "str"
+ description: "Static IPv4 address for vmbr0"
+ required: true
+ network_ipv4_prefix:
+ type: "int"
+ description: "IPv4 prefix length"
+ default: 24
+ network_ipv4_gateway:
+ type: "str"
+ description: "IPv4 default gateway"
+ required: true
+ network_ipv4_dns:
+ type: "str"
+ description: "IPv4 DNS server"
+ network_ipv6_address:
+ type: "str"
+ description: "Static IPv6 address for vmbr0 (optional)"
+ network_ipv6_gateway:
+ type: "str"
+ description: "IPv6 default gateway (required if network_ipv6_address is set)"
+ network_ipv6_dns:
+ type: "str"
+ description: "IPv6 DNS server"
diff --git a/roles/pve-network/meta/main.yml b/roles/pve-network/meta/main.yml
new file mode 100644
index 00000000..e7c9c044
--- /dev/null
+++ b/roles/pve-network/meta/main.yml
@@ -0,0 +1,13 @@
+---
+dependencies:
+ - role: "network"
+ - role: "pve"
+galaxy_info:
+ author: "a14m"
+ description: "Configure vmbr0 bridge on Proxmox VE via NetworkManager"
+ license: "MIT"
+ min_ansible_version: "2.18"
+ platforms:
+ - name: "Debian"
+ versions:
+ - "bookworm"
diff --git a/roles/pve-network/tasks/main.yml b/roles/pve-network/tasks/main.yml
new file mode 100644
index 00000000..dcaf0638
--- /dev/null
+++ b/roles/pve-network/tasks/main.yml
@@ -0,0 +1,36 @@
+---
+- name: "Set management IP in /etc/hosts for PVE cert generation"
+ become: true
+ ansible.builtin.lineinfile:
+ path: "/etc/hosts"
+ regexp: "^{{ network_ipv4_address }}"
+ line: "{{ network_ipv4_address }} {{ ansible_facts['hostname'] }}"
+ state: present
+ notify: "Restart pveproxy"
+ tags:
+ - "molecule-notest"
+
+- name: "Deploy bridge master connection"
+ become: true
+ ansible.builtin.template:
+ src: "vmbr0.nmconnection.j2"
+ dest: "/etc/NetworkManager/system-connections/vmbr0.nmconnection"
+ owner: "root"
+ group: "root"
+ mode: "0600"
+ notify: "Restart NetworkManager"
+
+- name: "Override ethernet connection as bridge port"
+ become: true
+ ansible.builtin.template:
+ src: "ethernet.nmconnection.j2"
+ dest: "/etc/NetworkManager/system-connections/ethernet.nmconnection"
+ owner: "root"
+ group: "root"
+ mode: "0600"
+ notify: "Restart NetworkManager"
+
+- name: "Wait for connection to recover after bridge reconfiguration"
+ ansible.builtin.wait_for_connection:
+ delay: 5
+ timeout: 30
diff --git a/roles/pve-network/templates/ethernet.nmconnection.j2 b/roles/pve-network/templates/ethernet.nmconnection.j2
new file mode 100644
index 00000000..2aaa85b0
--- /dev/null
+++ b/roles/pve-network/templates/ethernet.nmconnection.j2
@@ -0,0 +1,16 @@
+[connection]
+id={{ pve_network_interface }}-bridge-port
+type=ethernet
+interface-name={{ pve_network_interface }}
+autoconnect=true
+controller=vmbr0
+port-type=bridge
+
+[ethernet]
+cloned-mac-address=permanent
+
+[ipv4]
+method=disabled
+
+[ipv6]
+method=disabled
diff --git a/roles/pve-network/templates/vmbr0.nmconnection.j2 b/roles/pve-network/templates/vmbr0.nmconnection.j2
new file mode 100644
index 00000000..013acd6a
--- /dev/null
+++ b/roles/pve-network/templates/vmbr0.nmconnection.j2
@@ -0,0 +1,29 @@
+[connection]
+id=vmbr0
+type=bridge
+interface-name=vmbr0
+autoconnect=true
+
+[bridge]
+stp=false
+
+[ipv4]
+method=manual
+addresses={{ network_ipv4_address }}/{{ network_ipv4_prefix | default(24) }}
+gateway={{ network_ipv4_gateway }}
+{% if network_ipv4_dns is defined %}
+dns={{ network_ipv4_dns }}
+{% endif %}
+
+[ipv6]
+addr-gen-mode=default
+{% if network_ipv6_address is defined %}
+method=manual
+addresses={{ network_ipv6_address }}
+gateway={{ network_ipv6_gateway }}
+{% if network_ipv6_dns is defined %}
+dns={{ network_ipv6_dns }}
+{% endif %}
+{% else %}
+method=disabled
+{% endif %}
diff --git a/roles/pve/defaults/main.yml b/roles/pve/defaults/main.yml
index c9047655..c2bca151 100644
--- a/roles/pve/defaults/main.yml
+++ b/roles/pve/defaults/main.yml
@@ -2,3 +2,5 @@
pve_repo: "no-subscription"
pve_admin_user: "admin"
pve_admin_password: "changeme"
+pve_lvm_device: "/dev/sda4"
+pve_lvm_vg_name: "pve"
diff --git a/roles/pve/meta/argument_specs.yml b/roles/pve/meta/argument_specs.yml
index 195ca146..ab9f22c6 100644
--- a/roles/pve/meta/argument_specs.yml
+++ b/roles/pve/meta/argument_specs.yml
@@ -17,3 +17,11 @@ argument_specs:
type: "str"
description: "PVE realm admin password"
default: "changeme"
+ pve_lvm_device:
+ type: "str"
+ description: "Block device for PVE LVM volume group (e.g. /dev/sda4)"
+ default: "/dev/sda4"
+ pve_lvm_vg_name:
+ type: "str"
+ description: "LVM volume group name — PVE auto-detects VG named 'pve' as local-lvm storage"
+ default: "pve"
diff --git a/roles/pve/tasks/main.yml b/roles/pve/tasks/main.yml
index 39998cb7..7a314325 100644
--- a/roles/pve/tasks/main.yml
+++ b/roles/pve/tasks/main.yml
@@ -34,18 +34,6 @@
tags:
- molecule-notest
-- name: "Set management IP in /etc/hosts for PVE cert generation"
- become: true
- ansible.builtin.lineinfile:
- path: "/etc/hosts"
- regexp: "^{{ network_ipv4_address }}"
- line: "{{ network_ipv4_address }} {{ ansible_facts['hostname'] }}"
- state: present
- notify: "Restart pveproxy"
- tags:
- # Since container doesn't have network ip address, skipping this test
- - "molecule-notest"
-
- name: "Create PVE admin user"
become: true
ansible.builtin.command:
@@ -73,6 +61,14 @@
tags:
- "molecule-notest"
+- name: "Create LVM volume group for PVE storage"
+ become: true
+ ansible.builtin.command:
+ cmd: "vgcreate {{ pve_lvm_vg_name }} {{ pve_lvm_device }}"
+ creates: "/dev/{{ pve_lvm_vg_name }}"
+ tags:
+ - "molecule-notest"
+
- name: "Enable and start Proxmox VE services"
become: true
ansible.builtin.systemd_service: