--- - name: Bootstrap K3s and ArgoCD hosts: vps become: yes vars: # URL of the official ArgoCD manifest argocd_manifest_url: "https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml" # Local path to the root-app.yaml manifest (at the root of the repository) root_app_path: "../root-app.yaml" # Tailscale secrets are retrieved from environment variables tailscale_client_id: "{{ lookup('ansible.builtin.env', 'TAILSCALE_CLIENT_ID') | default('', true) }}" tailscale_client_secret: "{{ lookup('ansible.builtin.env', 'TAILSCALE_CLIENT_SECRET') | default('', true) }}" tasks: # ========================================================================= # INITIAL NODE CONFIGURATION # ========================================================================= - name: Initial Node Configuration block: - name: Install prerequisites ansible.builtin.apt: name: - curl - git - ca-certificates - python3-kubernetes state: present update_cache: yes # ========================================================================= # K3S INSTALLATION AND CONFIGURATION # ========================================================================= - name: K3s Installation and Configuration block: - name: Check if K3s is already installed ansible.builtin.stat: path: /usr/local/bin/k3s register: k3s_bin - name: Install K3s (default configuration) ansible.builtin.shell: | curl -sfL https://get.k3s.io | sh - when: not k3s_bin.stat.exists - name: Ensure ~/.kube directory exists ansible.builtin.file: path: ~/.kube state: directory mode: '0700' - name: Copy K3s kubeconfig to default root config ansible.builtin.copy: src: /etc/rancher/k3s/k3s.yaml dest: ~/.kube/config remote_src: yes owner: root group: root mode: '0600' - name: Also configure kubeconfig for the ansible_user block: - name: Ensure non-root user ~/.kube directory exists ansible.builtin.file: path: "/home/{{ ansible_user }}/.kube" state: directory owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: '0700' - name: Copy K3s kubeconfig to non-root user config ansible.builtin.copy: src: /etc/rancher/k3s/k3s.yaml dest: "/home/{{ ansible_user }}/.kube/config" remote_src: yes owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: '0600' when: ansible_user is defined and ansible_user != 'root' - name: Wait for K3s node to be ready ansible.builtin.shell: | kubectl get nodes | grep -q -w "Ready" register: node_status until: node_status.rc == 0 retries: 30 delay: 5 changed_when: false - name: Create tailscale namespace kubernetes.core.k8s: definition: apiVersion: v1 kind: Namespace metadata: name: tailscale state: present - name: Create tailscale-auth secret if credentials are provided kubernetes.core.k8s: definition: apiVersion: v1 kind: Secret metadata: name: tailscale-auth namespace: tailscale type: Opaque stringData: client-id: "{{ tailscale_client_id }}" client-secret: "{{ tailscale_client_secret }}" state: present when: tailscale_client_id != "" and tailscale_client_secret != "" # ========================================================================= # ARGOCD INSTALLATION # ========================================================================= - name: ArgoCD Installation block: - name: Create ArgoCD namespace kubernetes.core.k8s: definition: apiVersion: v1 kind: Namespace metadata: name: argocd state: present - name: Install ArgoCD (Server-Side Apply) kubernetes.core.k8s: src: "{{ argocd_manifest_url }}" namespace: argocd state: present apply: true server_side_apply: field_manager: ansible force_conflicts: true - name: Wait for ArgoCD Server deployment to be operational ansible.builtin.shell: | kubectl rollout status deployment/argocd-server -n argocd --timeout=300s changed_when: false # ========================================================================= # SYSTEM BOOTSTRAP (Cert-Manager, ClusterIssuer, Forgejo) # ========================================================================= - name: System Bootstrap (Cert-Manager, ClusterIssuer, Forgejo) block: - name: Install Cert-Manager (from official manifest) kubernetes.core.k8s: src: "https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml" state: present apply: true server_side_apply: field_manager: ansible force_conflicts: true - name: Wait for Cert-Manager webhook to be ready ansible.builtin.shell: | kubectl rollout status deployment/cert-manager-webhook -n cert-manager --timeout=300s changed_when: false - name: Deploy Let's Encrypt ClusterIssuer kubernetes.core.k8s: definition: "{{ lookup('file', '../platform/cluster/lets-encrypt.yaml') }}" state: present - name: Deploy Forgejo Namespace kubernetes.core.k8s: definition: "{{ lookup('file', '../platform/forgejo/namespace.yaml') }}" state: present - name: Deploy Forgejo Instance resources kubernetes.core.k8s: definition: "{{ lookup('file', '../platform/forgejo/instance/' ~ item) }}" state: present loop: - registry-secret.yaml - pvc.yaml - service.yaml - deployment.yaml - ingress.yaml - name: Deploy Forgejo Runner resources kubernetes.core.k8s: definition: "{{ lookup('file', '../platform/forgejo/runner/' ~ item) }}" state: present loop: - secret.yaml - pvc.yaml - configmap.yaml - deployment.yaml