diff --git a/.ansible-lint b/.ansible-lint index 91295bc..bf70e95 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -11,6 +11,7 @@ skip_list: - role-name[path] - name[play] - yaml[octal-values] + - yaml[brackets] - yaml[new-line-at-end-of-file] offline: false diff --git a/.ansible-lint-ignore b/.ansible-lint-ignore index 39ab6a5..124f2a6 100644 --- a/.ansible-lint-ignore +++ b/.ansible-lint-ignore @@ -1,2 +1,8 @@ -roles/gluster/server/tasks/create-volume.yml risky-shell-pipe +roles/gluster_server/tasks/create-volume-quota.yml risky-shell-pipe +roles/gluster_server/tasks/main.yml var-naming[no-role-prefix] +roles/gluster_server/tasks/create-volume.yml var-naming[no-role-prefix] +roles/gluster_server/tasks/create-volume-quota.yml var-naming[no-role-prefix] +roles/gluster_client/tasks/main.yml var-naming[no-role-prefix] +roles/pve_virtual_machines/tasks/main.yml var-naming[no-role-prefix] +roles/pve_virtual_machines/tasks/vm.yml var-naming[no-role-prefix] playbooks/nvidia.yml name[casing] \ No newline at end of file diff --git a/README.md b/README.md index 30df3f5..da76898 100644 --- a/README.md +++ b/README.md @@ -34,38 +34,13 @@ Working with this repository requires installation of several command line tools ## Environments -- **Lab** - test environment used to develop the roles running locally inside of HyperV on a developer's workstation. +- **Lab** - test environment used to develop the roles. The environment is defined in the [lab](https://github.com/homecentr/lab) repository using Proxmox nested virtualization. Please refer to this repository on how to (re)create this environment. - **Production** - the actual deployment used by the users. -### Create a Lab environment in Hyper-V -- Make sure you are running Windows 11 because earlier versions do not support nested virtualization which is required -- Install latest version of Powershell using [this guide](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.2) -- Create VMs using `yarn lab:create` command (must be executed as administrator) -- Start the VMs and install the Proxmox VMs with following parameters - - Disk: ZFS with RAID0 - - Country: Czechia - - Timezone: Europe/Prague - - Password: any, just watch out for english keyboard layout when typing numbers and make sure **all nodes have the same password** - - E-mail: stg-pve<X>@lab.<domain> - - Hostname: stg-pve<X>.lab.<domain> - - IP Address: 10.1.8.1<X>/24 - - Gateway: 10.1.8.1 -- Create a Proxmox cluster (there's currently no way to automate this) -- Remove previous SSH keys in case you have re-created the lab using the following command -```bash -yarn lab:clear-keys -``` -- Apply Ansible playbooks which will set up ssh access using the standard admin user using the following command -```bash -yarn lab:init -``` -- Apply the rest of Ansible playbooks using the following command -```bash -yarn lab:apply site -``` - ## Applying playbooks -Simply run the following bash command (requires Linux e.g. in WSL with [Yarn](https://yarnpkg.com/) installed): +In case you are running the playbooks against freshly installed machines, make sure you first run the initialization using the `yarn lab:init` command. + +To apply a playbook simply run the following bash command (requires Linux e.g. in WSL with [Yarn](https://yarnpkg.com/) installed): ``` yarn :apply ``` @@ -73,5 +48,3 @@ yarn :apply for example `yarn lab:apply common.yml` The script automatically installs dependencies from Ansible Galaxy and runs the playbook. - -> Note that the first time applying playbooks on a clean server, you need to use whatever authentication is available (most likely a password based one). During the first run the roles configure the SSH daemon to only allow non-root user with an RSA key and/or hardware device like YubiKey you need to use for subsequent logins. diff --git a/environments/lab/group_vars/gluster_nodes/mounts.yml b/environments/lab/group_vars/gluster_nodes/mounts.yml index 5c6fd10..51e260e 100644 --- a/environments/lab/group_vars/gluster_nodes/mounts.yml +++ b/environments/lab/group_vars/gluster_nodes/mounts.yml @@ -3,5 +3,6 @@ gluster_tls_certificate_validity_days: 7300 gluster_volume_mounts: - k8s-services + - k8s-services-db - k8s-monitoring - k8s-nvr diff --git a/environments/lab/group_vars/gluster_nodes/volumes.yml b/environments/lab/group_vars/gluster_nodes/volumes.yml index 7959444..d6445b8 100644 --- a/environments/lab/group_vars/gluster_nodes/volumes.yml +++ b/environments/lab/group_vars/gluster_nodes/volumes.yml @@ -32,7 +32,7 @@ gluster_volumes: - pve3 - name: k8s-services-db - mount_path: /mnt/gfs/k8s-services + mount_path: /mnt/gfs/k8s-services-db replica_sets: - storage_bricks: - host: pve1 diff --git a/environments/lab/group_vars/pve_nodes/general.yml b/environments/lab/group_vars/pve_nodes/general.yml index 86d8cb6..97c4075 100644 --- a/environments/lab/group_vars/pve_nodes/general.yml +++ b/environments/lab/group_vars/pve_nodes/general.yml @@ -6,6 +6,7 @@ ssh_allow_root_login_trusted_clients: pve_zfs_max_arc_size_gb: 0.5 +# TODO: Move this to a common role !!! pve_domain: homecentr.one pve_nameservers: - 1.1.1.1 diff --git a/environments/lab/host_vars/pve1.yml b/environments/lab/host_vars/pve1.yml index 90aaa3f..a4ed8cc 100644 --- a/environments/lab/host_vars/pve1.yml +++ b/environments/lab/host_vars/pve1.yml @@ -3,11 +3,17 @@ ansible_host: 10.1.8.11 ansible_hostname: pve1-lab fqdn: pve1-lab.homecentr.one +network_interfaces: + ens19: + method: static + address: 192.168.7.11/24 + auto: true + # UPS ups_name: dummy-ups1 # Gluster -gluster_ip: 192.168.1.11 +gluster_ip: 192.168.7.11 gluster_hostname: gfs-pve1-lab gluster_fqdn: gfs-pve1-lab.homecentr.one gluster_mount_host: pve1 @@ -15,12 +21,6 @@ gluster_mount_host: pve1 # PVE pve_pci_passhthrough_enabled: false -pve_network_interfaces: - eth1: - method: static - address: 192.168.1.11/24 - auto: true - pve_vm_machines: - vmid: 101 name: kube1-lab @@ -30,11 +30,11 @@ pve_vm_machines: shutdown_timeout_seconds: 120 nic_bridge: vmbr0 os_storage: local-zfs - os_disk_size_gb: 32 + os_disk_size: 32G cpu_count: 1 - cpu_cores_per_cpu: 4 - min_memory: 4096 - max_memory: 4096 + cpu_cores_per_cpu: 8 + min_memory: 8192 + max_memory: 15360 nic_ipv4_address: 10.1.8.21 nic_ipv4_subnet: 255.255.255.0 nic_ipv4_gateway: 10.1.8.1 diff --git a/environments/lab/host_vars/pve2.yml b/environments/lab/host_vars/pve2.yml index 20c882d..4efe9ba 100644 --- a/environments/lab/host_vars/pve2.yml +++ b/environments/lab/host_vars/pve2.yml @@ -3,11 +3,17 @@ ansible_host: 10.1.8.12 ansible_hostname: pve2-lab fqdn: pve2-lab.homecentr.one +network_interfaces: + ens19: + method: static + address: 192.168.7.12/24 + auto: true + # UPS ups_name: dummy-ups1 # Gluster -gluster_ip: 192.168.1.12 +gluster_ip: 192.168.7.12 gluster_hostname: gfs-pve2-lab gluster_fqdn: gfs-pve2-lab.homecentr.one gluster_mount_host: pve2 @@ -15,12 +21,6 @@ gluster_mount_host: pve2 # PVE pve_pci_passhthrough_enabled: false -pve_network_interfaces: - eth1: - method: static - address: 192.168.1.12/24 - auto: true - pve_vm_machines: - vmid: 201 name: kube2-lab @@ -30,11 +30,11 @@ pve_vm_machines: shutdown_timeout_seconds: 120 nic_bridge: vmbr0 os_storage: local-zfs - os_disk_size_gb: 32 + os_disk_size: 32G cpu_count: 1 - cpu_cores_per_cpu: 4 - min_memory: 4096 - max_memory: 4096 + cpu_cores_per_cpu: 8 + min_memory: 8192 + max_memory: 15360 nic_ipv4_address: 10.1.8.22 nic_ipv4_subnet: 255.255.255.0 nic_ipv4_gateway: 10.1.8.1 diff --git a/environments/lab/host_vars/pve3.yml b/environments/lab/host_vars/pve3.yml index 8c78317..5387576 100644 --- a/environments/lab/host_vars/pve3.yml +++ b/environments/lab/host_vars/pve3.yml @@ -3,22 +3,22 @@ ansible_host: 10.1.8.13 ansible_hostname: pve3-lab fqdn: pve3-lab.homecentr.one +network_interfaces: + ens19: + method: static + address: 192.168.7.13/24 + auto: true + # UPS ups_name: dummy-ups1 # Gluster -gluster_ip: 192.168.1.13 +gluster_ip: 192.168.7.13 gluster_hostname: gfs-pve3-lab gluster_fqdn: gfs-pve3-lab.homecentr.one gluster_mount_host: pve3 # PVE -pve_network_interfaces: - eth1: - method: static - address: 192.168.1.13/24 - auto: true - pve_vm_machines: - vmid: 301 name: kube3-lab @@ -28,11 +28,11 @@ pve_vm_machines: shutdown_timeout_seconds: 120 nic_bridge: vmbr0 os_storage: local-zfs - os_disk_size_gb: 32 + os_disk_size: 32G cpu_count: 1 - cpu_cores_per_cpu: 4 - min_memory: 4096 - max_memory: 4096 + cpu_cores_per_cpu: 8 + min_memory: 8192 + max_memory: 15360 nic_ipv4_address: 10.1.8.23 nic_ipv4_subnet: 255.255.255.0 nic_ipv4_gateway: 10.1.8.1 diff --git a/environments/lab/hosts.yml b/environments/lab/hosts.yml index 0667efd..f6283cb 100644 --- a/environments/lab/hosts.yml +++ b/environments/lab/hosts.yml @@ -24,9 +24,6 @@ all: pve3: gluster_clients: hosts: - pve1: - pve2: - pve3: kube1: kube2: kube3: diff --git a/environments/prod/group_vars/k8s_nodes/argocd.sops.yml b/environments/prod/group_vars/k8s_nodes/argocd.sops.yml index ac990ab..9a7e0ce 100644 --- a/environments/prod/group_vars/k8s_nodes/argocd.sops.yml +++ b/environments/prod/group_vars/k8s_nodes/argocd.sops.yml @@ -5,7 +5,7 @@ argocd_sops: public_key: ENC[AES256_GCM,data:z2nluQHqqGFwsb1EcyIa34y8rDlYRp7aJmrsZ7ILpmGi8maNJiAPsUTa5Ev8lDsPQbeO/Xh66r0XdjUS0OY=,iv:5vTm0EuaeJqwEgEtOmpIII72/Ik3OJtunYzzi5SxlB0=,tag:gmq7VP7nP+p5Frv2KsYPpA==,type:str] private_key: ENC[AES256_GCM,data:d398ZqrSzUbmyNuRt8gdkiHmp8rMM3Jt2AhXRhzEcHmGj+qZMdwJcnVX8H0PySFaaaBNo0885jR3PawAQkDddSBgiVdni51JNCM=,iv:ypBefMkJYmEsN0pGEIgXDzH8Gu4rUWwTRGOJ0VBrQ40=,tag:uvyLZSG8c9HH9k54GhQd9Q==,type:str] argocd_github: - token: ENC[AES256_GCM,data:xjDmFkzpqgQTwKyFTLm2SD1/P67spkLJ+rHEp3HxN4UjJ8aSaZD4nYj/awV6GDGjnPY5MmtFCQT5jQ8Qmm6hv4FxPq3Topnx57ZrWFydl3qXf8GafVJ+h+Mdj4Ka,iv:PtEZDXqNS6xPmRzAOCuuqjl3SKWLKTBbeDk02flqr3s=,tag:EQUPLi84VlZxtiPWjCS7Yw==,type:str] + token: ENC[AES256_GCM,data:c6r2pzVCaRrEptbbwDW4bg4hitnQlBbw7vyq/XqM8Spw3Zo6fRCXuHbmT3qDbbgxRvc9J1TTTFI3pYBROvB2xsNgbxZ2Q+zmSGSqHtXtKf1EMRA41GIBa8a/cnZP,iv:sBxdszp4K2h9owXAfqFafGRSbr7ENUnliFmjwKqpSM4=,tag:atP8xZAZZ7XXVTr9eD9yqw==,type:str] sops: kms: [] gcp_kms: [] @@ -21,8 +21,8 @@ sops: Vm5WbkVvTU5lY1FtRnRudEpJZmxvOGMK/wHIisN0llv5njFAQMj18Sj0gLFi4jM+ 0Nh+g3hnDB8IUwmvBopFvkPQUGruqT1S/ggzp51Z0AM9q61MfFB25g== -----END AGE ENCRYPTED FILE----- - lastmodified: "2023-06-04T20:58:07Z" - mac: ENC[AES256_GCM,data:L57xIrpWf8Q4SVro96NgHNb3gquxj48q7n494QtPbwnoWP/PstGF3v3k5zZdRYSPK1I2IDjlIbcdFzpM9w/+m51xleMmfWrqNXqRu4s80Y283hxtf6L+L1dfku3tPpl+FRMpeOl3wBJ1fHZE9Y5inqJ7gBkAbm3/TDkr56lsmEM=,iv:sg9lDvezpkTnp+ovVd3HramhVAbpImMZwJfOQktQ3eo=,tag:KoMrecXPO7NaLjj/F7Reaw==,type:str] + lastmodified: "2023-08-22T13:09:59Z" + mac: ENC[AES256_GCM,data:77+mwbTt539JR9AXvBHtXj/U5hnHX0FYjdLieOsZM9bEzzn4LS0mDXefRl+lxFTEjLEy9JTTRbHIYd3W0N29FvdXXz1/ML9NN013eBemw4wlHwYh8pTx4HX7seDLCEvWyHKNZjj0ta+P9fcdeST5Pip4MmfvlHDMwVH+d6mi7gU=,iv:B/mG3bOG/McuBfjieey9aMnmIuLKMu6fFUu+I17FnHY=,tag:2ziwL3cH3NTVGn5gwM7exQ==,type:str] pgp: - created_at: "2023-06-05T09:02:01Z" enc: | diff --git a/environments/prod/host_vars/pve3.yml b/environments/prod/host_vars/pve3.yml index 6a07574..2bfc407 100644 --- a/environments/prod/host_vars/pve3.yml +++ b/environments/prod/host_vars/pve3.yml @@ -26,8 +26,8 @@ pve_vm_machines: cpu_type: "cputype=host,flags=+aes" cpu_count: 1 cpu_cores_per_cpu: 3 - min_memory: 4096 - max_memory: 4096 + min_memory: 8192 + max_memory: 8192 nic_ipv4_address: 10.1.2.23 nic_ipv4_subnet: 255.255.255.0 nic_ipv4_gateway: 10.1.2.1 diff --git a/environments/prod/hosts.yml b/environments/prod/hosts.yml index 0667efd..f6283cb 100644 --- a/environments/prod/hosts.yml +++ b/environments/prod/hosts.yml @@ -24,9 +24,6 @@ all: pve3: gluster_clients: hosts: - pve1: - pve2: - pve3: kube1: kube2: kube3: diff --git a/package.json b/package.json index b122811..7e16719 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,7 @@ "private": true, "scripts": { "lint": "ANSIBLE_CONFIG=\"./ansible.cfg\" ansible-lint", - "setup:local": "ansible-galaxy install -r ./requirements.yml && ansible-playbook ./playbooks/_local.yml", - "lab:create": "pwsh -ExecutionPolicy RemoteSigned -WorkingDirectory ./tools ./tools/lab-create.ps1", - "lab:destroy": "pwsh -ExecutionPolicy RemoteSigned -WorkingDirectory ./tools ./tools/lab-destroy.ps1", + "setup:local": "ansible-galaxy install -r ./requirements.yml --force && ansible-playbook ./playbooks/_local.yml", "lab:clear-keys": "./tools/clearkeys.sh", "lab:init": "ANSIBLE_HOST_KEY_CHECKING=False ./tools/apply.sh lab proxmox -u root -e ansible_user=root --tags init -k", "lab:apply": "./tools/apply.sh lab", diff --git a/playbooks/common.yml b/playbooks/common.yml index d4ee3e8..6144af6 100644 --- a/playbooks/common.yml +++ b/playbooks/common.yml @@ -12,7 +12,7 @@ - name: Create host records for servers ansible.builtin.import_role: - name: ../../roles/common/hosts + name: ../../roles/hosts tags: - hosts diff --git a/playbooks/gluster.yml b/playbooks/gluster.yml index 51689e2..c93b1d8 100644 --- a/playbooks/gluster.yml +++ b/playbooks/gluster.yml @@ -8,7 +8,7 @@ tasks: - name: Install and configure Gluster servers ansible.builtin.import_role: - name: ../../roles/gluster/server + name: ../../roles/gluster_server - name: Set up gluster clients hosts: gluster_clients @@ -20,4 +20,4 @@ tasks: - name: Install and configure Gluster clients ansible.builtin.import_role: - name: ../../roles/gluster/client + name: ../../roles/gluster_client diff --git a/playbooks/kubernetes.yml b/playbooks/kubernetes.yml index b2e5311..6148850 100644 --- a/playbooks/kubernetes.yml +++ b/playbooks/kubernetes.yml @@ -6,12 +6,12 @@ tasks: - name: Install and configure k3s ansible.builtin.import_role: - name: ../../roles/kubernetes/k3s-cluster + name: ../../roles/k3s_cluster tags: - k3s - name: Install and configure Argo CD ansible.builtin.import_role: - name: ../../roles/kubernetes/argo-cd + name: ../../roles/argocd tags: - argocd diff --git a/playbooks/proxmox.yml b/playbooks/proxmox.yml index 7dadd75..29f5a78 100644 --- a/playbooks/proxmox.yml +++ b/playbooks/proxmox.yml @@ -5,32 +5,76 @@ any_errors_fatal: true tasks: # Must run before users to make sure the apt repositories are configured in order to install sudo - - name: Configure Proxmox VE specific components + - name: Configure proxmox apt repositories ansible.builtin.import_role: - name: ../../roles/proxmox/pve-node - tags: - - pve-nodes - - init + name: homecentr.proxmox.pve_apt + tags: [ init, apt ] # Root's password must be set so that it can be used to communicate with Proxmox API - name: Create users ansible.builtin.import_role: name: homecentr.system.users - tags: - - users - - init + tags: [ init, users ] + + - name: Configure proxmox user and their permissions + ansible.builtin.import_role: + name: homecentr.proxmox.pve_users + tags: [ init, users ] + + - name: Configure network interfaces + ansible.builtin.import_role: + name: homecentr.system.network + tags: [ network ] + + - name: Run upgrade (only first time) + ansible.builtin.import_role: + name: homecentr.system.init_upgrade + tags: [ upgrade ] + + - name: Configure https port forwarding + ansible.builtin.import_role: + name: homecentr.proxmox.pve_https_forward + tags: [ pve-https-forward ] + + - name: Configure PCI passthrough dependencies + ansible.builtin.import_role: + name: homecentr.proxmox.pve_pci_passthrough + tags: [ pve-pci-passthrough ] + + - name: Configure SMTP + ansible.builtin.import_role: + name: homecentr.proxmox.pve_smtp + tags: [ pve-smtp ] + + - name: Configure SSO via Open ID + ansible.builtin.import_role: + name: homecentr.proxmox.pve_sso_openid + tags: [ pve-sso-openid ] + + - name: Apply corosync fix + ansible.builtin.import_role: + name: homecentr.proxmox.pve_corosync_fix + tags: [ corosync ] - name: Configure ACME ansible.builtin.import_role: - name: ../../roles/proxmox/pve-acme - tags: - - acme + name: homecentr.proxmox.pve_acme + tags: [ acme ] + + - name: Configure USB HID quirk for UPS communication + ansible.builtin.import_role: + name: homecentr.system.usbhid_quirk + tags: [ usbhid-quirk ] + + - name: Configure ZFS + ansible.builtin.import_role: + name: homecentr.system.zfs_configuration + tags: [ usbhid-quirk ] - name: Flush handlers before starting the VMs ansible.builtin.meta: flush_handlers - name: Create virtual machines ansible.builtin.import_role: - name: ../../roles/proxmox/virtual-machines - tags: - - vm + name: ../../roles/pve_virtual_machines + tags: [ vm ] diff --git a/requirements.yml b/requirements.yml index ee7a3b6..83b1d1d 100644 --- a/requirements.yml +++ b/requirements.yml @@ -18,10 +18,15 @@ collections: - name: https://github.com/homecentr/ansible-collection-system type: git version: master + - name: https://github.com/homecentr/ansible-collection-proxmox + type: git + version: master roles: - name: geerlingguy.pip + version: 2.2.0 - name: geerlingguy.security + version: 2.2.0 - name: geerlingguy.clamav - name: geerlingguy.helm - name: geerlingguy.node_exporter diff --git a/roles/kubernetes/argo-cd/defaults/main.yml b/roles/argocd/defaults/main.yml similarity index 100% rename from roles/kubernetes/argo-cd/defaults/main.yml rename to roles/argocd/defaults/main.yml diff --git a/roles/kubernetes/argo-cd/tasks/configure.yml b/roles/argocd/tasks/configure.yml similarity index 100% rename from roles/kubernetes/argo-cd/tasks/configure.yml rename to roles/argocd/tasks/configure.yml diff --git a/roles/kubernetes/argo-cd/tasks/install.yml b/roles/argocd/tasks/install.yml similarity index 100% rename from roles/kubernetes/argo-cd/tasks/install.yml rename to roles/argocd/tasks/install.yml diff --git a/roles/kubernetes/argo-cd/tasks/main.yml b/roles/argocd/tasks/main.yml similarity index 100% rename from roles/kubernetes/argo-cd/tasks/main.yml rename to roles/argocd/tasks/main.yml diff --git a/roles/kubernetes/argo-cd/templates/application.yml.j2 b/roles/argocd/templates/application.yml.j2 similarity index 100% rename from roles/kubernetes/argo-cd/templates/application.yml.j2 rename to roles/argocd/templates/application.yml.j2 diff --git a/roles/kubernetes/argo-cd/templates/keys.txt.j2 b/roles/argocd/templates/keys.txt.j2 similarity index 100% rename from roles/kubernetes/argo-cd/templates/keys.txt.j2 rename to roles/argocd/templates/keys.txt.j2 diff --git a/roles/gluster/client/tasks/hosts.yml b/roles/gluster_client/tasks/hosts.yml similarity index 100% rename from roles/gluster/client/tasks/hosts.yml rename to roles/gluster_client/tasks/hosts.yml diff --git a/roles/gluster/client/tasks/install.yml b/roles/gluster_client/tasks/install.yml similarity index 100% rename from roles/gluster/client/tasks/install.yml rename to roles/gluster_client/tasks/install.yml diff --git a/roles/gluster/client/tasks/main.yml b/roles/gluster_client/tasks/main.yml similarity index 84% rename from roles/gluster/client/tasks/main.yml rename to roles/gluster_client/tasks/main.yml index cd96266..b0056ed 100644 --- a/roles/gluster/client/tasks/main.yml +++ b/roles/gluster_client/tasks/main.yml @@ -1,6 +1,6 @@ - name: Configure apt repository ansible.builtin.include_tasks: - file: ../../shared/apt.yml + file: ../../gluster_shared/apt.yml - name: Add host entries for glusterfs servers ansible.builtin.include_tasks: @@ -12,8 +12,7 @@ - name: Configure TLS identity for the node ansible.builtin.include_tasks: - file: ../../shared/tls.yml - register: gluster_tls + file: ../../gluster_shared/tls.yml vars: gluster_node_hostname: "{{ ansible_hostname }}" gluster_node_additional_names: @@ -21,7 +20,7 @@ - name: Mount GlusterFS volumes ansible.builtin.include_tasks: - file: ../../shared/volume-mount.yml + file: ../../gluster_shared/volume-mount.yml vars: gluster_volume: "{{ gluster_volumes | selectattr('name', 'equalto', item) | first }}" when: gluster_volume_mounts is defined diff --git a/roles/gluster/server/tasks/cluster.yml b/roles/gluster_server/tasks/cluster.yml similarity index 82% rename from roles/gluster/server/tasks/cluster.yml rename to roles/gluster_server/tasks/cluster.yml index cf1cd0a..1995b73 100644 --- a/roles/gluster/server/tasks/cluster.yml +++ b/roles/gluster_server/tasks/cluster.yml @@ -1,7 +1,7 @@ - name: Probe servers run_once: true retries: 15 - delay: "{{ gluster_start.changed | ternary(10, 0) }}" + delay: "{{ gluster_server_daemon_start.changed | ternary(10, 0) }}" gluster.gluster.gluster_peer: state: present # Current node has to be removed from the list because probing self throws an error diff --git a/roles/gluster_server/tasks/create-volume-quota.yml b/roles/gluster_server/tasks/create-volume-quota.yml new file mode 100644 index 0000000..461badf --- /dev/null +++ b/roles/gluster_server/tasks/create-volume-quota.yml @@ -0,0 +1,36 @@ +- name: Check if quota is enabled + ansible.builtin.shell: + # pipefail is ignored by design - it's a valid case + cmd: gluster volume info {{ gluster_volume_config.name }} | grep 'features.quota:' | cut -d' ' -f2 + args: + executable: /bin/bash + register: gluster_volume_quota_enabled + changed_when: false + +- name: Enable quota + retries: 10 + delay: 5 + ansible.builtin.command: + cmd: "gluster volume quota {{ gluster_volume_config.name }} enable" + changed_when: "gluster_volume_quota_enabled.stdout != 'on'" + when: "gluster_volume_quota_enabled.stdout != 'on'" + +- name: Check if volume level quota is set + retries: 15 + delay: 15 + until: gluster_volume_quota_set.rc == 0 + register: gluster_volume_quota_set + throttle: 1 + changed_when: false + ansible.builtin.command: + cmd: "gluster volume quota {{ gluster_volume_config.name }} list /" + +- name: Set volume level quota + retries: 5 + delay: 5 + register: gluster_volume_quota_limit_set + until: "'Failed to start aux mount' | string not in gluster_volume_quota_limit_set.stdout" + ansible.builtin.command: + cmd: "gluster volume quota {{ gluster_volume_config.name }} limit-usage / {{ gluster_volume_config.quota }}" + changed_when: "'N/A' | string in gluster_volume_quota_set.stdout" + when: "'N/A' | string in gluster_volume_quota_set.stdout" diff --git a/roles/gluster/server/tasks/create-volume.yml b/roles/gluster_server/tasks/create-volume.yml similarity index 71% rename from roles/gluster/server/tasks/create-volume.yml rename to roles/gluster_server/tasks/create-volume.yml index 4bc34e2..0b90015 100644 --- a/roles/gluster/server/tasks/create-volume.yml +++ b/roles/gluster_server/tasks/create-volume.yml @@ -33,7 +33,7 @@ cmd: "gluster volume info {{ gluster_volume_config.name }}" failed_when: false changed_when: false - register: volume_exists + register: gluster_volume_exists - name: Create storage bricks directories if they do not exist ansible.builtin.file: @@ -45,7 +45,7 @@ loop: "{{ gluster_volume_config.replica_sets | map(attribute='storage_bricks') | flatten | selectattr('host', 'equalto', inventory_hostname) }}" loop_control: loop_var: brick - when: volume_exists.rc != 0 + when: gluster_volume_exists.rc != 0 - name: Create arbiter bricks directories if they do not exist ansible.builtin.file: @@ -57,14 +57,14 @@ loop: "{{ gluster_volume_config.replica_sets | map(attribute='arbiter_bricks') | flatten | selectattr('host', 'equalto', inventory_hostname) }}" loop_control: loop_var: brick - when: volume_exists.rc != 0 + when: gluster_volume_exists.rc != 0 - name: Create volume if does not exist run_once: true ansible.builtin.command: cmd: "{{ lookup('template', 'create-volume-command.j2') }}" - changed_when: volume_exists.rc != 0 - when: volume_exists.rc != 0 + changed_when: gluster_volume_exists.rc != 0 + when: gluster_volume_exists.rc != 0 - name: Enable server tls run_once: true @@ -102,50 +102,16 @@ args: executable: /bin/bash changed_when: false - register: volume_status + register: gluster_volume_status - name: Start the volume run_once: true ansible.builtin.command: cmd: "gluster volume start {{ gluster_volume_config.name }}" - changed_when: volume_status.stdout != "Started" - when: volume_status.stdout != "Started" + changed_when: gluster_volume_status.stdout != "Started" + when: gluster_volume_status.stdout != "Started" -- name: Check if quota is enabled - ansible.builtin.shell: - # pipefail is ignored by design - it's a valid case - cmd: gluster volume info {{ gluster_volume_config.name }} | grep 'features.quota:' | cut -d' ' -f2 - args: - executable: /bin/bash - register: volume_quota_enabled - changed_when: false - -- name: Enable quota - retries: 5 - delay: 5 - run_once: true - ansible.builtin.command: - cmd: "gluster volume quota {{ gluster_volume_config.name }} enable" - changed_when: "volume_quota_enabled.stdout != 'on'" - when: "volume_quota_enabled.stdout != 'on'" - -- name: Check if volume level quota is set - retries: 5 - delay: 10 - until: volume_quota_set.rc == 0 - register: volume_quota_set - throttle: 1 - changed_when: false - ansible.builtin.command: - cmd: "gluster volume quota {{ gluster_volume_config.name }} list /" - -- name: Set volume level quota - retries: 5 - delay: 5 - register: volume_quota_limit_set - until: "'Failed to start aux mount' | string not in volume_quota_limit_set.stdout" +- name: Configure quota run_once: true - ansible.builtin.command: - cmd: "gluster volume quota {{ gluster_volume_config.name }} limit-usage / {{ gluster_volume_config.quota }}" - changed_when: "'N/A' | string in volume_quota_set.stdout" - when: "'N/A' | string in volume_quota_set.stdout" + ansible.builtin.include_tasks: + file: create-volume-quota.yml \ No newline at end of file diff --git a/roles/gluster/server/tasks/exporter.yml b/roles/gluster_server/tasks/exporter.yml similarity index 100% rename from roles/gluster/server/tasks/exporter.yml rename to roles/gluster_server/tasks/exporter.yml diff --git a/roles/gluster/server/tasks/hosts.yml b/roles/gluster_server/tasks/hosts.yml similarity index 100% rename from roles/gluster/server/tasks/hosts.yml rename to roles/gluster_server/tasks/hosts.yml diff --git a/roles/gluster/server/tasks/install.yml b/roles/gluster_server/tasks/install.yml similarity index 74% rename from roles/gluster/server/tasks/install.yml rename to roles/gluster_server/tasks/install.yml index 82c6af7..0cb8871 100644 --- a/roles/gluster/server/tasks/install.yml +++ b/roles/gluster_server/tasks/install.yml @@ -6,8 +6,8 @@ update_cache: true - name: Start the Gluster daemon - register: gluster_start - until: gluster_start.status.ActiveState == "active" + register: gluster_server_daemon_start + until: gluster_server_daemon_start.status.ActiveState == "active" delay: 20 retries: 15 throttle: 1 diff --git a/roles/gluster/server/tasks/main.yml b/roles/gluster_server/tasks/main.yml similarity index 90% rename from roles/gluster/server/tasks/main.yml rename to roles/gluster_server/tasks/main.yml index da9fcad..ae36dad 100644 --- a/roles/gluster/server/tasks/main.yml +++ b/roles/gluster_server/tasks/main.yml @@ -1,6 +1,6 @@ - name: Configure apt repository ansible.builtin.include_tasks: - file: ../../shared/apt.yml + file: ../../gluster_shared/apt.yml - name: Add host entries for glusterfs servers ansible.builtin.include_tasks: @@ -12,8 +12,7 @@ - name: Configure TLS identity for the node ansible.builtin.include_tasks: - file: ../../shared/tls.yml - register: gluster_tls + file: ../../gluster_shared/tls.yml vars: gluster_server_restart: true gluster_node_hostname: "{{ gluster_hostname }}" # Servers must use their gluster specific identity @@ -39,7 +38,7 @@ - name: Mount Gluster volumes ansible.builtin.include_tasks: - file: ../../shared/volume-mount.yml + file: ../../gluster_shared/volume-mount.yml vars: gluster_volume: "{{ gluster_volumes | selectattr('name', 'equalto', item) | first }}" when: gluster_volume_mounts is defined diff --git a/roles/gluster/server/templates/create-volume-command.j2 b/roles/gluster_server/templates/create-volume-command.j2 similarity index 100% rename from roles/gluster/server/templates/create-volume-command.j2 rename to roles/gluster_server/templates/create-volume-command.j2 diff --git a/roles/gluster/server/templates/set-volume-clients-command.j2 b/roles/gluster_server/templates/set-volume-clients-command.j2 similarity index 100% rename from roles/gluster/server/templates/set-volume-clients-command.j2 rename to roles/gluster_server/templates/set-volume-clients-command.j2 diff --git a/roles/gluster/shared/apt.yml b/roles/gluster_shared/apt.yml similarity index 100% rename from roles/gluster/shared/apt.yml rename to roles/gluster_shared/apt.yml diff --git a/roles/gluster/shared/tls.yml b/roles/gluster_shared/tls.yml similarity index 100% rename from roles/gluster/shared/tls.yml rename to roles/gluster_shared/tls.yml diff --git a/roles/gluster/shared/volume-mount.yml b/roles/gluster_shared/volume-mount.yml similarity index 100% rename from roles/gluster/shared/volume-mount.yml rename to roles/gluster_shared/volume-mount.yml diff --git a/roles/gluster/shared/volume-subdir.yml b/roles/gluster_shared/volume-subdir.yml similarity index 100% rename from roles/gluster/shared/volume-subdir.yml rename to roles/gluster_shared/volume-subdir.yml diff --git a/roles/common/hosts/tasks/main.yml b/roles/hosts/tasks/main.yml similarity index 100% rename from roles/common/hosts/tasks/main.yml rename to roles/hosts/tasks/main.yml diff --git a/roles/kubernetes/k3s-cluster/defaults/main.yml b/roles/k3s_cluster/defaults/main.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/defaults/main.yml rename to roles/k3s_cluster/defaults/main.yml diff --git a/roles/kubernetes/k3s-cluster/handlers/main.yml b/roles/k3s_cluster/handlers/main.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/handlers/main.yml rename to roles/k3s_cluster/handlers/main.yml diff --git a/roles/kubernetes/k3s-cluster/tasks/cis-hardening-runtime.yml b/roles/k3s_cluster/tasks/cis-hardening-runtime.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/tasks/cis-hardening-runtime.yml rename to roles/k3s_cluster/tasks/cis-hardening-runtime.yml diff --git a/roles/kubernetes/k3s-cluster/tasks/kubeconfig-load.yml b/roles/k3s_cluster/tasks/kubeconfig-load.yml similarity index 51% rename from roles/kubernetes/k3s-cluster/tasks/kubeconfig-load.yml rename to roles/k3s_cluster/tasks/kubeconfig-load.yml index 1451455..f3bb64a 100644 --- a/roles/kubernetes/k3s-cluster/tasks/kubeconfig-load.yml +++ b/roles/k3s_cluster/tasks/kubeconfig-load.yml @@ -1,3 +1,3 @@ - name: Set kubeconfig path to facts ansible.builtin.set_fact: - kubeconfig_path: "/etc/rancher/k3s/k3s.yaml" + k3s_cluster_kubeconfig_path: "/etc/rancher/k3s/k3s.yaml" diff --git a/roles/kubernetes/k3s-cluster/tasks/kubeconfig-store-local.yml b/roles/k3s_cluster/tasks/kubeconfig-store-local.yml similarity index 74% rename from roles/kubernetes/k3s-cluster/tasks/kubeconfig-store-local.yml rename to roles/k3s_cluster/tasks/kubeconfig-store-local.yml index b63fb7b..a9083e2 100644 --- a/roles/kubernetes/k3s-cluster/tasks/kubeconfig-store-local.yml +++ b/roles/k3s_cluster/tasks/kubeconfig-store-local.yml @@ -1,7 +1,7 @@ - name: Load kube config ansible.builtin.slurp: - src: "{{ kubeconfig_path }}" - register: kubeconfig + src: "{{ k3s_cluster_kubeconfig_path }}" + register: k3s_cluster_kubeconfig - name: Create .kube directory become: false @@ -18,6 +18,6 @@ run_once: true ansible.builtin.copy: dest: "$HOME/.kube/config" - content: "{{ kubeconfig.content | b64decode }}" + content: "{{ k3s_cluster_kubeconfig.content | b64decode }}" mode: 0600 force: true diff --git a/roles/kubernetes/k3s-cluster/tasks/main.yml b/roles/k3s_cluster/tasks/main.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/tasks/main.yml rename to roles/k3s_cluster/tasks/main.yml diff --git a/roles/kubernetes/k3s-cluster/tasks/setup-coredns.yml b/roles/k3s_cluster/tasks/setup-coredns.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/tasks/setup-coredns.yml rename to roles/k3s_cluster/tasks/setup-coredns.yml diff --git a/roles/kubernetes/k3s-cluster/tasks/setup-helm.yml b/roles/k3s_cluster/tasks/setup-helm.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/tasks/setup-helm.yml rename to roles/k3s_cluster/tasks/setup-helm.yml diff --git a/roles/kubernetes/k3s-cluster/tasks/setup-k3s.yml b/roles/k3s_cluster/tasks/setup-k3s.yml similarity index 77% rename from roles/kubernetes/k3s-cluster/tasks/setup-k3s.yml rename to roles/k3s_cluster/tasks/setup-k3s.yml index f635c2c..91eba16 100644 --- a/roles/kubernetes/k3s-cluster/tasks/setup-k3s.yml +++ b/roles/k3s_cluster/tasks/setup-k3s.yml @@ -18,12 +18,12 @@ force: false - name: "Check k3s symlink destination" - register: k3s_symlink + register: k3s_cluster_k3s_symlink ansible.builtin.stat: path: "/usr/local/bin/k3s" - name: "Create k3s symlink" - when: "not k3s_symlink.stat.exists or k3s_symlink.stat.lnk_source != '/usr/local/bin/k3s-bins/' + k3s_cluster_version + '/k3s'" + when: "not k3s_cluster_k3s_symlink.stat.exists or k3s_cluster_k3s_symlink.stat.lnk_source != '/usr/local/bin/k3s-bins/' + k3s_cluster_version + '/k3s'" ansible.builtin.file: src: "/usr/local/bin/k3s-bins/{{ k3s_cluster_version }}/k3s" dest: "/usr/local/bin/k3s" @@ -34,7 +34,7 @@ mode: 0750 - name: Create K3s service file - register: k3s_service + register: k3s_cluster_k3s_service ansible.builtin.template: src: "k3s.service.j2" dest: "{{ k3s_cluster_systemd_dir }}/k3s.service" @@ -63,27 +63,14 @@ - name: Start the k3s service retries: 10 - until: "'status' in k3s_service and k3s_service.status.ActiveState == 'active'" - register: k3s_service + until: "'status' in k3s_cluster_k3s_service and k3s_cluster_k3s_service.status.ActiveState == 'active'" + register: k3s_cluster_k3s_service ansible.builtin.systemd: name: k3s daemon_reload: true state: started enabled: true -- name: Wait for node-token - ansible.builtin.wait_for: - path: "{{ k3s_cluster_server_location }}/server/node-token" - -- name: Read node-token from master - ansible.builtin.slurp: - path: "{{ k3s_cluster_server_location }}/server/node-token" - register: node_token - -- name: Store Master node-token - ansible.builtin.set_fact: - token: "{{ node_token.content | b64decode | regex_replace('\n', '') }}" - - name: Create kubectl symlink ansible.builtin.file: src: /usr/local/bin/k3s diff --git a/roles/kubernetes/k3s-cluster/tasks/setup-pip-modules.yml b/roles/k3s_cluster/tasks/setup-pip-modules.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/tasks/setup-pip-modules.yml rename to roles/k3s_cluster/tasks/setup-pip-modules.yml diff --git a/roles/kubernetes/k3s-cluster/tasks/setup-sysctls.yml b/roles/k3s_cluster/tasks/setup-sysctls.yml similarity index 100% rename from roles/kubernetes/k3s-cluster/tasks/setup-sysctls.yml rename to roles/k3s_cluster/tasks/setup-sysctls.yml diff --git a/roles/kubernetes/k3s-cluster/templates/audit.yml.j2 b/roles/k3s_cluster/templates/audit.yml.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/audit.yml.j2 rename to roles/k3s_cluster/templates/audit.yml.j2 diff --git a/roles/kubernetes/k3s-cluster/templates/coredns.yml.j2 b/roles/k3s_cluster/templates/coredns.yml.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/coredns.yml.j2 rename to roles/k3s_cluster/templates/coredns.yml.j2 diff --git a/roles/kubernetes/k3s-cluster/templates/k3s-config.yaml.j2 b/roles/k3s_cluster/templates/k3s-config.yaml.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/k3s-config.yaml.j2 rename to roles/k3s_cluster/templates/k3s-config.yaml.j2 diff --git a/roles/kubernetes/k3s-cluster/templates/k3s.service.j2 b/roles/k3s_cluster/templates/k3s.service.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/k3s.service.j2 rename to roles/k3s_cluster/templates/k3s.service.j2 diff --git a/roles/kubernetes/k3s-cluster/templates/kubelet.conf.j2 b/roles/k3s_cluster/templates/kubelet.conf.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/kubelet.conf.j2 rename to roles/k3s_cluster/templates/kubelet.conf.j2 diff --git a/roles/kubernetes/k3s-cluster/templates/namespace.yml.j2 b/roles/k3s_cluster/templates/namespace.yml.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/namespace.yml.j2 rename to roles/k3s_cluster/templates/namespace.yml.j2 diff --git a/roles/kubernetes/k3s-cluster/templates/network-policy-default.yml.j2 b/roles/k3s_cluster/templates/network-policy-default.yml.j2 similarity index 100% rename from roles/kubernetes/k3s-cluster/templates/network-policy-default.yml.j2 rename to roles/k3s_cluster/templates/network-policy-default.yml.j2 diff --git a/roles/proxmox/pve-acme/handlers/main.yml b/roles/proxmox/pve-acme/handlers/main.yml deleted file mode 100644 index 2c2c915..0000000 --- a/roles/proxmox/pve-acme/handlers/main.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Order ACME certificates - retries: 5 - delay: 10 - register: acme_order - until: acme_order.rc == 0 - changed_when: true # Called only when the underlying configuration changes - ansible.builtin.command: - cmd: pvenode acme cert order diff --git a/roles/proxmox/pve-acme/tasks/acme-domain.yml b/roles/proxmox/pve-acme/tasks/acme-domain.yml deleted file mode 100644 index f4fa3e8..0000000 --- a/roles/proxmox/pve-acme/tasks/acme-domain.yml +++ /dev/null @@ -1,14 +0,0 @@ -- name: Check if ACME domain is already configured - ansible.builtin.command: - cmd: "grep -Fxq \"acmedomain{{ index }}: domain={{ domain }},plugin={{ pve_acme_plugin_name }}\" /etc/pve/local/config" - register: acme_domain_list - check_mode: false - ignore_errors: true - changed_when: false - -- name: Add ACME domain configuration - ansible.builtin.command: - cmd: pvenode config set --acmedomain{{ index }} domain={{ domain }},plugin={{ pve_acme_plugin_name }} - when: acme_domain_list.rc != 0 - changed_when: true - notify: Order ACME certificates diff --git a/roles/proxmox/pve-acme/tasks/main.yml b/roles/proxmox/pve-acme/tasks/main.yml deleted file mode 100644 index 2a4aa67..0000000 --- a/roles/proxmox/pve-acme/tasks/main.yml +++ /dev/null @@ -1,71 +0,0 @@ -# Inspired by https://github.com/simoncaron/ansible-role-pve_acme/blob/master/tasks/pve-acme.yml -- name: Install required python modules - ansible.builtin.apt: - name: - - python3-pexpect - -- name: Check if default ACME account is registered - ansible.builtin.command: - cmd: pvenode acme plugin list - register: acme_plugin_list - changed_when: false - ignore_errors: true - -- name: Create config file - ansible.builtin.copy: - content: | - CF_Token={{ pve_acme_cloudflare_token }} - CF_Account_ID={{ pve_acme_cloudflare_account_id }} - dest: "/tmp/acme.data" - mode: "0600" - when: pve_acme_plugin_name | string not in acme_plugin_list.stdout - no_log: true - -- name: Add ACME plugin configuration - run_once: true - ansible.builtin.command: - cmd: "pvenode acme plugin add dns {{ pve_acme_plugin_name }} --api {{ pve_acme_plugin_api }} --data /tmp/acme.data" - when: pve_acme_plugin_name | string not in acme_plugin_list.stdout - changed_when: true - -- name: Check if default ACME account is registered - ansible.builtin.command: - cmd: pvenode acme account list - register: acme_account_list - changed_when: false - ignore_errors: true - -- name: Add ACME account configuration - run_once: true - ansible.builtin.expect: - # yamllint disable rule:line-length - command: "pvenode acme account register {{ pve_acme_account_name }} {{ pve_acme_account_email }} --directory {{ 'https://acme-staging-v02.api.letsencrypt.org/directory' if (pve_acme_use_staging | default(true)) else 'https://acme-v02.api.letsencrypt.org/directory' }}" - # yamllint enable rule:line-length - responses: - Do you agree to the above terms.*: y - when: acme_account_list.stdout | length == 0 - notify: Order ACME certificates - -- name: Check active ACME account - register: acme_account_active - changed_when: false - ansible.builtin.command: - cmd: "pvenode config get --property acme" - -- name: Set ACME account - ansible.builtin.command: - cmd: "pvenode config set --acme \"account={{ pve_acme_account_name }}\"" - when: pve_acme_account_name | string not in acme_account_active.stdout - changed_when: true - -- name: Configure ACME domains - ansible.builtin.include_tasks: - file: acme-domain.yml - vars: - index: "{{ item_index }}" - domain: "{{ item }}" - loop: - - "{{ pve_acme_proxmox_hostname }}.{{ pve_acme_root_domain }}" - - "{{ ansible_hostname }}.{{ pve_acme_root_domain }}" - loop_control: - index_var: item_index diff --git a/roles/proxmox/pve-node/files/default-domains.cfg b/roles/proxmox/pve-node/files/default-domains.cfg deleted file mode 100644 index ea39c34..0000000 --- a/roles/proxmox/pve-node/files/default-domains.cfg +++ /dev/null @@ -1,5 +0,0 @@ -pve: pve - comment Proxmox VE authentication server - -pam: pam - comment Linux PAM standard authentication \ No newline at end of file diff --git a/roles/proxmox/pve-node/handlers/main.yml b/roles/proxmox/pve-node/handlers/main.yml deleted file mode 100644 index 62ec34e..0000000 --- a/roles/proxmox/pve-node/handlers/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: Restart postfix - ansible.builtin.service: - name: postfix - state: restarted - -- name: Reload networking - ansible.builtin.command: - cmd: ifreload -a - changed_when: true - -- name: APT update - ansible.builtin.apt: - update_cache: true - -- name: Systemd reload - ansible.builtin.systemd: - daemon_reload: true - -- name: Update initamfs image - ansible.builtin.command: - cmd: update-initramfs -u -k all - changed_when: true - -- name: Reboot machine - ansible.builtin.reboot: - reboot_timeout: 500 - throttle: 1 diff --git a/roles/proxmox/pve-node/tasks/apt-repositories.yml b/roles/proxmox/pve-node/tasks/apt-repositories.yml deleted file mode 100644 index dc26d8a..0000000 --- a/roles/proxmox/pve-node/tasks/apt-repositories.yml +++ /dev/null @@ -1,30 +0,0 @@ -- name: Remove enteprise repository - notify: APT update - ansible.builtin.file: - path: /etc/apt/sources.list.d/pve-enterprise.list - state: absent - -- name: Get Debian version - ansible.builtin.shell: - cmd: | - set -o pipefail - grep 'VERSION=' /etc/os-release | grep -Eo '[a-z]+' - args: - executable: /bin/bash - register: debver - changed_when: false - -- name: Add free (no-subscription) repository - register: add_nosub - notify: APT update - ansible.builtin.copy: - dest: /etc/apt/sources.list.d/pve-no-subscription.list - owner: root - group: root - mode: 0640 - content: | - deb http://download.proxmox.com/debian/pve {{ debver.stdout }} pve-no-subscription - -- name: Run apt update - ansible.builtin.apt: - update_cache: true diff --git a/roles/proxmox/pve-node/tasks/apt-upgrade.yml b/roles/proxmox/pve-node/tasks/apt-upgrade.yml deleted file mode 100644 index ede3b67..0000000 --- a/roles/proxmox/pve-node/tasks/apt-upgrade.yml +++ /dev/null @@ -1,24 +0,0 @@ -# We want to run dist-upgrade automatically only on a fresh install -# subsequent upgrades should be run manually to ensure stability. - -- name: Check for marker file - register: apt_dist_upgrade_file - ansible.builtin.stat: - path: /etc/dist-upgrade.marker - -- name: Run initial dist-upgrade - when: not apt_dist_upgrade_file.stat.exists - notify: Reboot machine # dist-upgrade will install kernel updates when run on a fresh install - ansible.builtin.apt: - upgrade: dist - -- name: Create marker file - when: not apt_dist_upgrade_file.stat.exists - ansible.builtin.file: - path: /etc/dist-upgrade.marker - access_time: preserve - modification_time: preserve - owner: root - group: root - mode: 0600 - state: touch diff --git a/roles/proxmox/pve-node/tasks/cluster.yml b/roles/proxmox/pve-node/tasks/cluster.yml deleted file mode 100644 index c7587ce..0000000 --- a/roles/proxmox/pve-node/tasks/cluster.yml +++ /dev/null @@ -1,26 +0,0 @@ -# The task below allows the corosync service to automatically restart when it fails on start up. -# This may happen during a power outage when all nodes start booting at the same time. The first node to boot up -# then searches for the other nodes and when it finds out that none of the other nodes respond (because they haven't finished booting yet) -# it gives up and stops the corosync service which will keep the node forever in "waiting for quorum" state. -# The change below allows automatic recovery of this state. -- name: Update the corosync systemd unit file - notify: Systemd reload - ansible.builtin.lineinfile: - path: /usr/lib/systemd/system/corosync.service - regexp: "^{{ item.field }}=" - insertafter: "{{ item.after }}" - line: "{{ item.field }}={{ item.value }}" - firstmatch: true - with_items: - - field: "StartLimitBurst" - value: "10" # Retry 10 times - after: "\\[Unit\\]" - - field: "StartLimitInterval" - value: "120" # How long all retry attempts may take before giving up - after: "\\[Unit\\]" - - field: "Restart" - value: "on-failure" # To make sure it's not started when it's explicitly stopped - after: "\\[Service\\]" - - field: "RestartSec" - value: "5" # Wait 5 seconds before the next retry - after: "\\[Service\\]" diff --git a/roles/proxmox/pve-node/tasks/main.yml b/roles/proxmox/pve-node/tasks/main.yml deleted file mode 100644 index 81d1453..0000000 --- a/roles/proxmox/pve-node/tasks/main.yml +++ /dev/null @@ -1,65 +0,0 @@ -- name: Configure nameservers - ansible.builtin.include_tasks: - file: network-dns.yml - -- name: Configure network interfaces - ansible.builtin.include_tasks: - file: network-interface.yml - loop: "{{ pve_network_interfaces | dict2items }}" - loop_control: - loop_var: interface - when: pve_network_interfaces is defined - vars: - interface_name: "{{ interface.key }}" - -- name: Configure apt repositories - ansible.builtin.include_tasks: - file: apt-repositories.yml - -- name: Install required python modules - ansible.builtin.apt: - name: - - python3-passlib # Required for users' password hash computation - -- name: Upgrade - ansible.builtin.include_tasks: - file: apt-upgrade.yml - -- name: Expose Web UI on port 443 - ansible.builtin.include_tasks: - file: port-forwarding.yml - -- name: Configure SMTP for alerts - ansible.builtin.include_tasks: - file: smtp.yml - -- name: Configure ZFS - ansible.builtin.include_tasks: - file: zfs.yml - -- name: Configure USB HID - ansible.builtin.include_tasks: - file: usbhid.yml - -- name: Configure SSH - ansible.builtin.include_tasks: - file: ssh.yml - -- name: Configure SSO via OpenID - ansible.builtin.include_tasks: - file: sso-openid.yml - -- name: Configure SSO users - ansible.builtin.include_tasks: - file: users.yml - -- name: Improve PVE Cluster auto-heal - ansible.builtin.include_tasks: - file: cluster.yml - -- name: Enable PCI passthrough - ansible.builtin.include_tasks: - file: pci-passthrough.yml - -- name: Flush handlers - ansible.builtin.meta: flush_handlers # restart networking immediately if needed diff --git a/roles/proxmox/pve-node/tasks/network-dns.yml b/roles/proxmox/pve-node/tasks/network-dns.yml deleted file mode 100644 index f72dd00..0000000 --- a/roles/proxmox/pve-node/tasks/network-dns.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Configure nameservers - ansible.builtin.copy: - content: "{{ lookup('template', 'resolv.conf.j2') }}" - dest: /etc/resolv.conf - mode: 0644 - owner: root - group: root - force: true diff --git a/roles/proxmox/pve-node/tasks/network-interface.yml b/roles/proxmox/pve-node/tasks/network-interface.yml deleted file mode 100644 index e412900..0000000 --- a/roles/proxmox/pve-node/tasks/network-interface.yml +++ /dev/null @@ -1,20 +0,0 @@ -- name: Configure network interface auto - notify: Reload networking - ansible.builtin.lineinfile: - path: /etc/network/interfaces - line: "auto {{ interface_name }}" - state: "{{ 'present' if (not 'auto' in pve_network_interfaces[interface_name] or pve_network_interfaces[interface_name].auto == true) else 'absent' }}" - insertbefore: "^iface {{ interface_name }}" - -- name: Configure network interface attributes - notify: Reload networking - community.general.interfaces_file: - dest: /etc/network/interfaces - iface: "{{ interface_name }}" - option: "{{ item.key }}" - value: "{{ item.value }}" - state: present - loop: "{{ pve_network_interfaces[interface_name] | dict2items | rejectattr('key', 'equalto', 'auto') }}" - -- name: Flush handlers to apply network configuration immediately - ansible.builtin.meta: flush_handlers diff --git a/roles/proxmox/pve-node/tasks/pci-passthrough.yml b/roles/proxmox/pve-node/tasks/pci-passthrough.yml deleted file mode 100644 index 2c01d7b..0000000 --- a/roles/proxmox/pve-node/tasks/pci-passthrough.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: Add kernel boot parameters - notify: - - Update initamfs image - - Reboot machine - ansible.builtin.replace: - backup: true - dest: /etc/kernel/cmdline - regexp: '^(root=(?!.*\b{{ item }}\b).*)$' - replace: '\1 {{ item }}' - loop: - - "intel-iommu=on" - - "iommu=pt" - when: pve_pci_passhthrough_enabled is defined and pve_pci_passhthrough_enabled - -- name: Load required kernel modules - notify: - - Update initamfs image - - Reboot machine - ansible.builtin.lineinfile: - path: /etc/modules - line: "{{ item }}" - loop: - - vfio - - vfio_iommu_type1 - - vfio_pci - - vfio_virqfd - when: pve_pci_passhthrough_enabled is defined and pve_pci_passhthrough_enabled diff --git a/roles/proxmox/pve-node/tasks/port-forwarding.yml b/roles/proxmox/pve-node/tasks/port-forwarding.yml deleted file mode 100644 index e0714f9..0000000 --- a/roles/proxmox/pve-node/tasks/port-forwarding.yml +++ /dev/null @@ -1,26 +0,0 @@ -- name: "Set up port redirect (443 -> 8006)" - ansible.builtin.iptables: - table: nat - chain: PREROUTING - protocol: tcp - destination_port: 443 - to_ports: 8006 - jump: REDIRECT - comment: "Enable Proxmox admin interface on 443" - -- name: "Save iptables state to a file" - community.general.iptables_state: - ip_version: ipv4 - table: nat - state: saved - path: /etc/iptables/nat.rules.v4 - -- name: "Create iptables restore script" - ansible.builtin.copy: - dest: /etc/network/if-up.d/run-iptables - mode: 0700 - owner: root - group: root - content: | - #!/bin/sh - iptables-restore < /etc/iptables/nat.rules.v4 diff --git a/roles/proxmox/pve-node/tasks/smtp.yml b/roles/proxmox/pve-node/tasks/smtp.yml deleted file mode 100644 index e153118..0000000 --- a/roles/proxmox/pve-node/tasks/smtp.yml +++ /dev/null @@ -1,43 +0,0 @@ -- name: Configure postfix smtp relay - ansible.builtin.lineinfile: - path: /etc/postfix/main.cf - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - with_items: - - regexp: "^relayhost\\s*=" - line: "relayhost = {{ pve_smtp_host }}:{{ pve_smtp_port }}" - - regexp: "^smtp_use_tls\\s*=" - line: "smtp_use_tls = {{ 'yes' if pve_smtp_tls else 'no' }}" - - regexp: "^smtp_sasl_auth_enable\\s*=" - line: "smtp_sasl_auth_enable = {{ 'yes' if (pve_smtp_username is defined and pve_smtp_username | length) else 'no' }}" - - regexp: "^smtp_sasl_security_options\\s*=" - line: "smtp_sasl_security_options = {{ 'nonanonymous' if (pve_smtp_username is defined and pve_smtp_username | length) else '' }}" - - regexp: "^smtp_sasl_password_maps\\s*=" - line: "smtp_sasl_password_maps = /etc/postfix/sasl_passwd" - - regexp: "^smtp_tls_CAfile\\s*=" - line: "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" - notify: - - Restart postfix - -- name: Configure postfix smtp authentication # noqa no-tabs - ansible.builtin.copy: - dest: /etc/postfix/sasl_passwd.cf - force: true - owner: root - group: root - mode: 0600 - content: | - # This file is managed by Ansible. All changes will be lost. - - {{ pve_smtp_host }}:{{ pve_smtp_port }} {{ pve_smtp_username }}:{{ pve_smtp_password }} - when: pve_smtp_username is defined and pve_smtp_username | length - notify: - - Restart postfix - -- name: Remove postfix smtp authentication when not used - ansible.builtin.file: - dest: /etc/postfix/sasl_passwd.cf - state: absent - when: pve_smtp_username is not defined or not pve_smtp_username | length - notify: - - Restart postfix diff --git a/roles/proxmox/pve-node/tasks/ssh.yml b/roles/proxmox/pve-node/tasks/ssh.yml deleted file mode 100644 index 6cdd5ab..0000000 --- a/roles/proxmox/pve-node/tasks/ssh.yml +++ /dev/null @@ -1,19 +0,0 @@ -# - name: "Create known_hosts symlink" -# ansible.builtin.file: -# dest: /root/.ssh/known_hosts -# src: /etc/pve/priv/known_hosts -# owner: root -# group: root -# mode: 0640 -# follow: false -# state: link - -# - name: "Create authorized_keys symlink" -# ansible.builtin.file: -# dest: /root/.ssh/authorized_keys -# src: /etc/pve/priv/authorized_keys -# owner: root -# group: root -# mode: 0640 -# follow: false -# state: link diff --git a/roles/proxmox/pve-node/tasks/sso-openid.yml b/roles/proxmox/pve-node/tasks/sso-openid.yml deleted file mode 100644 index b6aa256..0000000 --- a/roles/proxmox/pve-node/tasks/sso-openid.yml +++ /dev/null @@ -1,32 +0,0 @@ -- name: Check if domains.cfg exists - register: domains_cfg - ansible.builtin.stat: - path: /etc/pve/domains.cfg - -- name: Create default domains.cfg if it does not exist - run_once: true # Cluster level command - when: not domains_cfg.stat.exists - changed_when: not domains_cfg.stat.exists - ansible.builtin.command: - cmd: pveum realm modify pam --default 0 - -# Note: The empty line in the template below must remain, otherwise jinja puts the last two lines on one which creates an invalid file -- name: Define PVE realm - run_once: true - no_log: true - ansible.builtin.blockinfile: - create: false - path: /etc/pve/domains.cfg - marker: "# {mark} ANSIBLE MANAGED BLOCK (OpenID {{ item.name }})" - block: | - openid: {{ item.name }} - comment {{ item.display_name }} - client-id {{ item.client_id }} - client-key {{ item.client_secret }} - issuer-url {{ item.url }} - autocreate {{ '1' if item.autocreate_users else '0' }} - default {{ '1' if pve_default_realm_name == item.name else '0' }} - {% if 'username_claim' in item %}username-claim {{ item.username_claim }}{% endif %} - - {% if 'scopes' in item %}scopes {{ item.scopes }}{% endif %} - with_items: "{{ pve_openid_realms }}" diff --git a/roles/proxmox/pve-node/tasks/usbhid.yml b/roles/proxmox/pve-node/tasks/usbhid.yml deleted file mode 100644 index b1b9834..0000000 --- a/roles/proxmox/pve-node/tasks/usbhid.yml +++ /dev/null @@ -1,12 +0,0 @@ -- name: Update USB HID quirks - notify: - - Update initamfs image - - Reboot machine - ansible.builtin.lineinfile: - path: /etc/modprobe.d/usbhid.conf - regexp: "^options usbhid quirks=(.*)$" - line: "options usbhid quirks=0x0463:0xffff:0x08" - create: true - owner: root - group: root - mode: 0644 diff --git a/roles/proxmox/pve-node/tasks/user-permissions.yml b/roles/proxmox/pve-node/tasks/user-permissions.yml deleted file mode 100644 index f150c0d..0000000 --- a/roles/proxmox/pve-node/tasks/user-permissions.yml +++ /dev/null @@ -1,11 +0,0 @@ -- name: Assign scoped roles to users - no_log: true - ansible.builtin.lineinfile: - path: /etc/pve/user.cfg - create: false - regex: "^acl:1:{{ permission.scope | default('/') }}:{{ user.username }}@{{ user.realm }}:(.*)" - line: "acl:1:{{ permission.scope | default('/') }}:{{ user.username }}@{{ user.realm }}:{{ permission.roles | join(',') }}:" - insertafter: "^user:.*" - loop: "{{ user.permissions }}" - loop_control: - loop_var: permission diff --git a/roles/proxmox/pve-node/tasks/users.yml b/roles/proxmox/pve-node/tasks/users.yml deleted file mode 100644 index b0c57e7..0000000 --- a/roles/proxmox/pve-node/tasks/users.yml +++ /dev/null @@ -1,23 +0,0 @@ -- name: Create users - ansible.builtin.lineinfile: - path: /etc/pve/user.cfg - create: false - regex: "^user:{{ item.username }}@{{ item.realm }}:(.*)" - # hardcoded 0 is expiration time, ignored by design - line: "user:{{ item.username }}@{{ item.realm }}:{{ '1' if item.enabled else '0' }}:0:{{ item.first_name }}:{{ item.last_name }}:{{ item.email }}:::" - with_items: "{{ pve_users }}" - when: pve_users is defined - -- name: Assign roles to users - ansible.builtin.include_tasks: - file: user-permissions.yml - with_items: "{{ pve_users }}" - when: pve_users is defined - vars: - user: "{{ item }}" - -- name: Remove root@pam user - ansible.builtin.lineinfile: - path: /etc/pve/user.cfg - state: absent - regex: "^user:root@pam:(.*)" diff --git a/roles/proxmox/pve-node/tasks/zfs.yml b/roles/proxmox/pve-node/tasks/zfs.yml deleted file mode 100644 index bf1963e..0000000 --- a/roles/proxmox/pve-node/tasks/zfs.yml +++ /dev/null @@ -1,12 +0,0 @@ -- name: Update ZFS ARC max size - notify: - - Update initamfs image - - Reboot machine - ansible.builtin.lineinfile: - path: /etc/modprobe.d/zfs.conf - regexp: "^options zfs zfs_arc_max=(.*)$" - line: "options zfs zfs_arc_max={{ (pve_zfs_max_arc_size_gb * 1024 * 1024 * 1024) | int }}" - create: true - owner: root - group: root - mode: 0644 diff --git a/roles/proxmox/pve-node/templates/resolv.conf.j2 b/roles/proxmox/pve-node/templates/resolv.conf.j2 deleted file mode 100644 index 5aef927..0000000 --- a/roles/proxmox/pve-node/templates/resolv.conf.j2 +++ /dev/null @@ -1,4 +0,0 @@ -search {{ pve_domain }} -{% for nameserver in pve_nameservers %} -nameserver {{ nameserver }} -{% endfor %} \ No newline at end of file diff --git a/roles/proxmox/pve-node/vars/main.yml b/roles/proxmox/pve-node/vars/main.yml deleted file mode 100644 index 2608f61..0000000 --- a/roles/proxmox/pve-node/vars/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -pve_acme_plugin_name: cloudflare -pve_acme_plugin_api: cf -pve_acme_account_name: default diff --git a/roles/proxmox/virtual-machines/tasks/images.yml b/roles/pve_virtual_machines/tasks/images.yml similarity index 100% rename from roles/proxmox/virtual-machines/tasks/images.yml rename to roles/pve_virtual_machines/tasks/images.yml diff --git a/roles/proxmox/virtual-machines/tasks/main.yml b/roles/pve_virtual_machines/tasks/main.yml similarity index 100% rename from roles/proxmox/virtual-machines/tasks/main.yml rename to roles/pve_virtual_machines/tasks/main.yml diff --git a/roles/proxmox/virtual-machines/tasks/snippets.yml b/roles/pve_virtual_machines/tasks/snippets.yml similarity index 59% rename from roles/proxmox/virtual-machines/tasks/snippets.yml rename to roles/pve_virtual_machines/tasks/snippets.yml index f1b5e6e..7f16ca0 100644 --- a/roles/proxmox/virtual-machines/tasks/snippets.yml +++ b/roles/pve_virtual_machines/tasks/snippets.yml @@ -4,21 +4,21 @@ api_password: "{{ users_root_password }}" api_host: 127.0.0.1 name: local - register: pve_local_storage + register: pve_virtual_machines_local_storage - name: Update config - when: not 'snippets' in pve_local_storage.proxmox_storages[0].content + when: not 'snippets' in pve_virtual_machines_local_storage.proxmox_storages[0].content ansible.builtin.lineinfile: path: /etc/pve/storage.cfg create: false firstmatch: true insertafter: "^\\W*dir:\\W*local$" regex: "^\\W*content\\W*(.*)$" - line: " content {{ (pve_local_storage.proxmox_storages[0].content + ['snippets']) | join(',') }}" + line: " content {{ (pve_virtual_machines_local_storage.proxmox_storages[0].content + ['snippets']) | join(',') }}" - name: Create snippets directory ansible.builtin.file: - path: "{{ pve_local_storage.proxmox_storages[0].path }}/snippets" + path: "{{ pve_virtual_machines_local_storage.proxmox_storages[0].path }}/snippets" state: directory owner: root group: root diff --git a/roles/proxmox/virtual-machines/tasks/vm.yml b/roles/pve_virtual_machines/tasks/vm.yml similarity index 93% rename from roles/proxmox/virtual-machines/tasks/vm.yml rename to roles/pve_virtual_machines/tasks/vm.yml index c19e52c..36003bb 100644 --- a/roles/proxmox/virtual-machines/tasks/vm.yml +++ b/roles/pve_virtual_machines/tasks/vm.yml @@ -1,6 +1,6 @@ - name: Create cloud-init config ansible.builtin.copy: - dest: "{{ pve_local_storage.proxmox_storages[0].path }}/snippets/{{ vm.vmid }}.yml" + dest: "{{ pve_virtual_machines_local_storage.proxmox_storages[0].path }}/snippets/{{ vm.vmid }}.yml" owner: root group: root mode: 0640 @@ -56,7 +56,7 @@ net: net0: "virtio,bridge={{ vm.nic_bridge }}" ipconfig: - ipconfig0: "ip={{ (vm.nic_ipv4_address + '/' + vm.nic_ipv4_subnet) | ansible.utils.ipaddr('host/prefix') }},gw={{ vm.nic_ipv4_gateway }}" + ipconfig0: "ip={{ (vm.nic_ipv4_address + '/' + vm.nic_ipv4_subnet) | ansible.utils.ipaddr('host/prefix') }},gw={{ vm.nic_ipv4_gateway }}" # noqa yaml[line-length] nameservers: "{{ vm.nameservers }}" efidisk0: "{{ ({'storage': vm.os_storage, 'format': 'raw', 'efitype': '4m', 'pre_enrolled_keys': false}) if (vm.bios | default('bios')) == 'efi' else none }}" # noqa yaml[line-length] scsihw: virtio-scsi-pci @@ -71,9 +71,9 @@ state: present - name: Import disk from cloud image - register: pve_vm_disk + register: vm_disk retries: 5 # transient timeouts - until: pve_vm_disk.vmid == vm.vmid + until: vm_disk.vmid == vm.vmid community.general.proxmox_disk: api_user: root@pam api_password: "{{ users_root_password }}" @@ -93,7 +93,7 @@ api_host: 127.0.0.1 vmid: "{{ vm.vmid }}" disk: scsi1 - size: 25G + size: "{{ vm.os_disk_size }}" state: resized - name: Start VM diff --git a/tools/apply.sh b/tools/apply.sh index d4a4b65..14d5e78 100755 --- a/tools/apply.sh +++ b/tools/apply.sh @@ -32,7 +32,7 @@ shift export ANSIBLE_CONFIG="./ansible.cfg" # Install Ansible dependencies (roles and collections) -ansible-galaxy install -r ./requirements.yml +ansible-galaxy install -r ./requirements.yml --force COMMAND="ansible-playbook -i $INVENTORY $PLAYBOOK ${@:1}" diff --git a/tools/lab-create.ps1 b/tools/lab-create.ps1 deleted file mode 100644 index 9b17e1c..0000000 --- a/tools/lab-create.ps1 +++ /dev/null @@ -1,152 +0,0 @@ -$ErrorActionPreference = "Stop" - -$ExternalSwitchName = "Homecentr-Lab-External" -$StorageSwitchName = "Homecentr-Lab-Storage" -$ProxmoxIsoLink = "https://enterprise.proxmox.com/iso/proxmox-ve_8.0-2.iso" -$ProxmoxIsoPath = [System.IO.Path]::Join([System.Environment]::CurrentDirectory, "./.images/Proxmox-8-0.iso") - -Function Create-ExternalSwitch() -{ - $Switch = Get-VMSwitch -Name $ExternalSwitchName -ErrorAction SilentlyContinue - - if($Switch -ne $null) - { - Write-Host "✔️ Hyper-V external switch found" - } - else - { - Write-Host "Creating external switch..." - Get-NetAdapter - - $IfIndex = Read-Host "Please enter ifIndex of the NIC you want to use for the virtual switch" - $IfDescription = (Get-NetAdapter -InterfaceIndex $IfIndex).InterfaceDescription - - New-VMSwitch -Name $ExternalSwitchName -NetAdapterInterfaceDescription $IfDescription -AllowManagementOS $true | Out-Null - - Write-Host "✔️ Hyper-V external switch created" - } -} - -Function Create-StorageSwitch() -{ - $Switch = Get-VMSwitch -Name $StorageSwitchName -ErrorAction SilentlyContinue - - if($Switch -ne $null) - { - Write-Host "✔️ Hyper-V internal switch found" - } - else - { - New-VMSwitch -Name $StorageSwitchName -SwitchType Private | Out-Null - - Write-Host "✔️ Hyper-V internal switch created" - } -} - -Function Create-VM([string]$VMName) -{ - $VM = Get-VM -Name $VMName -ErrorAction SilentlyContinue - $HypervHost = Get-VMHost - - if($VM -ne $null) - { - Write-Host "✔️ [$VMName] VM found" - } - else - { - # Note: Proxmox fails to start a VM if it has less than 4GB - - New-VM -Name $VMName ` - -Generation 2 ` - -NewVHDPath "$($HypervHost.VirtualHardDiskPath)\$($VMName)_RootDrive.vhdx" ` - -NewVHDSizeBytes 96GB ` - -MemoryStartupBytes 7GB ` - -SwitchName $ExternalSwitchName - - Add-VMNetworkAdapter -VMName $VMName -SwitchName $StorageSwitchName - - Write-Host "✔️ [$VMName] VM created" - } - - - Set-VMMemory -VMName $VMName ` - -DynamicMemoryEnabled $false # Proxmox can't work with dynamic memory properly - - $DvdDrive = Get-VMDvdDrive -VMName $VMName -ErrorAction SilentlyContinue - if($DvdDrive -ne $null) - { - Write-Host "✔️ [$VMName] DVD drive found" - } - else - { - Add-VMDvdDrive -VMName $VMName -Path $ProxmoxIsoPath - $DvdDrive = Get-VMDvdDrive -VMName $VMName - - Write-Host "✔️ [$VMName] DVD drive added" - } - - Set-VMProcessor -VMName $VMName -Count 6 - Write-Host "✔️ [$VMName] CPU cores allocated" - - Set-VMProcessor -VMName $VMName -ExposeVirtualizationExtensions $true - Write-Host "✔️ [$VMName] Nested virtualization enabled" - - $VMNetworkAdapters = Get-VMNetworkAdapter -VMName $VMName - foreach($VMNIC in $VMNetworkAdapters) - { - Set-VMNetworkAdapter -VMName $VMName -Name $VMNIC.Name -MacAddressSpoofing On | Out-Null - Write-Host "✔️ [$VMName] MAC address spoofing enabled on $($VMNIC.Name)" - } - - Set-VMFirmware -VMName $VMName -EnableSecureBoot Off | Out-Null - Write-Host "✔️ [$VMName] secure boot disabled" - - Set-VMFirmware -VMName $VMName -FirstBootDevice $DvdDrive | Out-Null - Write-Host "✔️ [$VMName] DVD set as default boot device" -} - -Function Download-InstallationImage() -{ - $IsoDir = [System.IO.Path]::GetDirectoryName($ProxmoxIsoPath) - - if((Test-Path $IsoDir) -ne $true) - { - New-Item -Path $IsoDir -ItemType Directory | Out-Null - } - - if((Test-Path $ProxmoxIsoPath) -ne $true) - { - Write-Host "Downloading Proxmox Installation image..." - Invoke-WebRequest -URI $ProxmoxIsoLink -OutFile $ProxmoxIsoPath - Write-Host "✔️ Proxmox Installation image downloaded" - } - else - { - Write-Host "✔️ Proxmox Installation image found" - } -} - -$HyperV = Get-WindowsOptionalFeature -FeatureName "Microsoft-Hyper-V-All" -Online -if($HyperV.State -eq "Enabled") -{ - Write-Host "✔️ Hyper-V is installed" -} -else -{ - Write-Host "Installing Hyper-V..." - Enable-WindowsOptionalFeature -FeatureName "Microsoft-Hyper-V-All" -Online - Write-Host "Installation complete, please restart your PC and rerun the scripts..." - return -} - -Download-InstallationImage - -Create-ExternalSwitch -Create-StorageSwitch - -$VMCount = 3 -$VMNumbers = [System.Linq.Enumerable]::Range(1, $VMCount) - -$VMNumbers | ForEach-Object { - Create-VM "Homecentr-Lab-Node$_" -} \ No newline at end of file diff --git a/tools/lab-destroy.ps1 b/tools/lab-destroy.ps1 deleted file mode 100644 index 8b3344a..0000000 --- a/tools/lab-destroy.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -$ErrorActionPreference = "Stop" - -$VMCount = 3 -$VMNumbers = [System.Linq.Enumerable]::Range(1, $VMCount) - -$VMNumbers | ForEach-Object -Parallel { - $VMName = "Homecentr-Lab-Node$_" - - $VM = Get-VM -Name $VMName -ErrorAction SilentlyContinue - - if($VM) { - Stop-VM $VMName -Force -TurnOff - Write-Host "✔️ [$VMName] Stopped" - - $VMDrives = Get-VMHardDiskDrive -VMName $VMName | ForEach-Object -Parallel { - Remove-VMHardDiskDrive -VMName $using:VMName ` - -ControllerType $_.ControllerType ` - -ControllerNumber $_.ControllerNumber ` - -ControllerLocation $_.ControllerLocation - - Write-Host "✔️ [$using:VMName] Disk $($_.ControllerType)/$($_.ControllerNumber)/$($_.ControllerLocation) removed" - - if(Test-Path $_.Path) - { - Remove-Item $_.Path -Force - Write-Host "✔️ [$using:VMName] Vhdx file $($_.Path) removed" - } - } - - Remove-VM $VMName -Force - Write-Host "✔️ [$VMName] Removed" - } - else { - Write-Host "✔️ [$VMName] Already removed" - } -} \ No newline at end of file diff --git a/tools/validations.js b/tools/validations.js index 3720bd7..7ec4ecc 100644 --- a/tools/validations.js +++ b/tools/validations.js @@ -13,7 +13,7 @@ const options = { if(fileName.match(/pve\d\.y(a)?ml/)) { return [ // Managed manually in prod due to bonded NICs - "pve_network_interfaces" + "network_interfaces" ] }