--- # Playbook for eom.dev - name: Initialize workstations hosts: workstations become: true vars_files: - ../secrets.yaml roles: - role: ericomeehan.debian - role: ericomeehan.ericomeehan - role: ericomeehan.nvidia_driver when: nvidia_driver_needed == true - role: geerlingguy.docker when: docker_needed == true - name: Initialize hypervisors hosts: hypervisors become: true vars_files: - ../secrets.yaml roles: - role: ericomeehan.debian - role: ericomeehan.ericomeehan - role: ericomeehan.nvidia_driver when: nvidia_driver_needed == true - name: Initialize Network File Systems hosts: poweredge-t640 become: true roles: - role: geerlingguy.nfs tasks: - name: Create NFS directories file: path: "{{ item }}" state: directory loop: - /data/alpha - /data/beta - /data/gamma - /data/eric - name: Prepare virtualization environments hosts: hypervisors become: true tasks: - name: Install packages for virtualization apt: update_cache: yes name: - bridge-utils - genisoimage - qemu-utils - qemu-system-x86 - libvirt-daemon-system - python3-libvirt - python3-lxml state: present - name: Enable IPv4 packet forwarding lineinfile: path: /etc/sysctl.conf line: 'net.ipv4.ip_forward = 1' state: present - name: Enable IPv6 packet forwarding lineinfile: path: /etc/sysctl.conf line: 'net.ipv6.conf.all.forwarding = 1' state: present - name: Copy interfaces template template: src: interfaces.j2 dest: /etc/network/interfaces - name: Reload sysctl configuration command: sysctl --system - name: Reload network service service: name: networking state: restarted - name: Deploy virtual machines hosts: hypervisors become: true vars_files: - ../secrets.yaml tasks: - name: Define libvirt networks community.libvirt.virt_net: name: "{{ item.name }}" command: define xml: "{{ lookup('template', 'libvirt-network.xml.j2') }}" loop: "{{ libvirt_networks }}" - name: Create libvirt networks community.libvirt.virt_net: name: "{{ item.name }}" command: create loop: "{{ libvirt_networks }}" - name: Autostart libvirt networks community.libvirt.virt_net: name: "{{ item.name }}" autostart: true loop: "{{ libvirt_networks }}" - name: Download base image get_url: url: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2 dest: /var/lib/libvirt/images/debian-12-generic-amd64.qcow2 force: true - name: Copy base image copy: src: /var/lib/libvirt/images/debian-12-generic-amd64.qcow2 remote_src: true dest: "/var/lib/libvirt/images/{{ item }}.qcow2" force: true loop: "{{ libvirt_guests }}" - name: Resize images command: "qemu-img resize -f qcow2 /var/lib/libvirt/images/{{ item }}.qcow2 16G" loop: "{{ libvirt_guests }}" - name: Create cloud-config directory file: path: "/tmp/{{ item }}" state: directory loop: "{{ libvirt_guests }}" - name: Copy cloud-config user-data template template: src: user-data.j2 dest: "/tmp/{{ domain.name }}/user-data" force: true loop: "{{ libvirt_guests }}" vars: domain: "{{ hostvars[item] }}" - name: Copy cloud-config meta-data template template: src: meta-data.j2 dest: "/tmp/{{ domain.name }}/meta-data" force: true loop: "{{ libvirt_guests }}" vars: domain: "{{ hostvars[item] }}" - name: Generate iso command: "genisoimage -output /var/lib/libvirt/images/{{ item }}.iso -volid cidata -joliet -rock /tmp/{{ item }}/user-data /tmp/{{ item }}/meta-data" loop: "{{ libvirt_guests }}" - name: Define libvirt virtual machine community.libvirt.virt: command: define xml: "{{ lookup('template', 'libvirt-vm.xml.j2') }}" loop: "{{ libvirt_guests }}" vars: domain: "{{ hostvars[item] }}" - name: Create libvirt virtual machine community.libvirt.virt: name: "{{ item }}" command: create loop: "{{ libvirt_guests }}" - name: Autostart libvirt virtual machines community.libvirt.virt: name: "{{ item }}" autostart: true loop: "{{ libvirt_guests }}" - name: Wait for guest initialization wait_for: timeout: 300 - name: Reset libvirt virtual machines for filesystem resize command: "virsh reset {{ item }}" loop: "{{ libvirt_guests }}" - name: Wait for manual tasks hosts: localhost tasks: - name: Trust SSH identities pause: prompt: "Press Enter to continue..." - name: Initialize virtual machines hosts: vms become: true vars_files: - ../secrets.yaml roles: - role: ericomeehan.ericomeehan - name: Initialize Kubernetes clusters hosts: clusters become: true pre_tasks: - name: Enable IPv4 packet forwarding lineinfile: path: /etc/sysctl.conf line: 'net.ipv4.ip_forward = 1' state: present - name: Enable IPv6 packet forwarding lineinfile: path: /etc/sysctl.conf line: 'net.ipv6.conf.all.forwarding = 1' state: present - name: Reload sysctl configuration command: sysctl --system - name: Enable br_netfilter kernel module command: modprobe br_netfilter - name: Add the module to a configuration file for persistence lineinfile: path: /etc/modules-load.d/modules.conf line: "br_netfilter" - name: Install kubernetes library apt: name: python3-kubernetes state: present roles: - role: geerlingguy.containerd - name: Alpha Cluster hosts: alpha become: true roles: - role: geerlingguy.kubernetes - name: Beta Cluster hosts: beta become: true roles: - role: geerlingguy.kubernetes - name: Gamma Cluster hosts: gamma become: true roles: - role: geerlingguy.kubernetes - name: Install Helm hosts: control_planes become: true roles: - role: geerlingguy.helm - name: Deploy base Kubernetes resources hosts: control_planes become: true tasks: - name: Add NFS Provisioner repository kubernetes.core.helm_repository: name: nfs-subdir-external-provisioner repo_url: https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ - name: Add MetalLB repository kubernetes.core.helm_repository: name: metallb repo_url: https://metallb.github.io/metallb - name: Add Ingress Nginx repository kubernetes.core.helm_repository: name: ingress-nginx repo_url: https://kubernetes.github.io/ingress-nginx - name: Add cert-manager repository kubernetes.core.helm_repository: name: jetstack repo_url: https://charts.jetstack.io - name: Update Helm repos command: helm repo update - name: Deploy NFS Provisioner kubernetes.core.helm: name: nfs-subdir-external-provisioner chart_ref: nfs-subdir-external-provisioner/nfs-subdir-external-provisioner release_namespace: nfs-provisioner create_namespace: true values: nfs: server: poweredge-t640 path: "/data/{{ cluster_name }}" storageClass: defaultClass: true - name: Deploy MetalLB kubernetes.core.helm: name: metallb chart_ref: metallb/metallb release_namespace: metallb create_namespace: true - name: Wait for MetalLB to initialize wait_for: timeout: 120 - name: Deploy BGP Peer k8s: state: present definition: apiVersion: metallb.io/v1beta2 kind: BGPPeer metadata: name: bgp-peer namespace: metallb spec: myASN: "{{ metallb_asn }}" peerASN: 6500 peerAddress: 192.168.1.1 - name: Deploy address pool k8s: state: present definition: apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: pool0 namespace: metallb spec: addresses: "{{ metallb_addresses }}" - name: Deploy BGP Advertisement k8s: state: present definition: apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: bgp-advertisement namespace: metallb spec: ipAddressPools: - pool0 - name: Deploy Ingress Nginx kubernetes.core.helm: name: ingress-nginx chart_ref: ingress-nginx/ingress-nginx release_namespace: ingress-nginx create_namespace: true values: controller: annotations: acme.cert-manager.io/http01-edit-in-place: 'true' extraArgs: update-status: "false" - name: Deploy cert-manager kubernetes.core.helm: name: cert-manager chart_ref: jetstack/cert-manager release_namespace: cert-manager create_namespace: true values: crds: enabled: true - name: Deploy Cluster Issuer k8s: state: present definition: apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: ca-issuer spec: acme: server: "{{ letsencrypt_url }}" email: eric@eom.dev privateKeySecretRef: name: letsencrypt-issuer-key solvers: - http01: ingress: ingressClassName: nginx - name: Port forward HTTP(S) to Ingress Controllers hosts: localhost tasks: - name: Wait for manual tasks pause: prompt: "Press Enter to continue..."