diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index b2daf0c..0311de1 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -225,6 +225,7 @@ jobs: ansible-playbook site.yml \ -e "hcloud_token=${{ secrets.HCLOUD_TOKEN }}" \ -e "tailscale_auth_key=${{ secrets.TAILSCALE_AUTH_KEY }}" \ + -e "tailscale_tailnet=${{ secrets.TAILSCALE_TAILNET }}" \ -e "cluster_name=k8s-cluster" env: ANSIBLE_HOST_KEY_CHECKING: "False" diff --git a/README.md b/README.md index c120619..33b41c8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Production-ready Kubernetes cluster on Hetzner Cloud using Terraform and Ansible | **Workers** | 4x CX33 | | **Total Cost** | €28.93/mo | | **K8s** | k3s (latest, HA) | -| **Addons** | Hetzner CCM (load balancers) | +| **Addons** | Hetzner CCM + CSI | | **Access** | SSH/API restricted to Tailnet | | **Bootstrap** | Terraform + Ansible | @@ -143,6 +143,8 @@ export KUBECONFIG=$(pwd)/outputs/kubeconfig kubectl get nodes ``` +Kubeconfig endpoint is rewritten to the primary control-plane tailnet hostname (`k8s-cluster-cp-1.`). + ## Gitea CI/CD This repository includes Gitea workflows for: @@ -189,7 +191,8 @@ Set these in your Gitea repository settings (**Settings** → **Secrets** → ** │ │ ├── common/ │ │ ├── k3s-server/ │ │ ├── k3s-agent/ -│ │ └── ccm/ +│ │ ├── ccm/ +│ │ └── csi/ │ └── ansible.cfg ├── .gitea/ │ └── workflows/ diff --git a/ansible/roles/csi/defaults/main.yml b/ansible/roles/csi/defaults/main.yml new file mode 100644 index 0000000..bae3050 --- /dev/null +++ b/ansible/roles/csi/defaults/main.yml @@ -0,0 +1,4 @@ +--- +hcloud_token: "" +cluster_name: "k8s-cluster" +csi_manifest_url: "https://raw.githubusercontent.com/hetznercloud/csi-driver/v2.12.0/deploy/kubernetes/hcloud-csi.yml" diff --git a/ansible/roles/csi/tasks/main.yml b/ansible/roles/csi/tasks/main.yml new file mode 100644 index 0000000..1ab0798 --- /dev/null +++ b/ansible/roles/csi/tasks/main.yml @@ -0,0 +1,30 @@ +--- +- name: Create Hetzner CSI secret + shell: | + kubectl -n kube-system create secret generic hcloud-csi \ + --from-literal=token='{{ hcloud_token }}' \ + --from-literal=network='{{ cluster_name }}-network' \ + --dry-run=client -o yaml | kubectl apply -f - + no_log: true + when: hcloud_token is defined + changed_when: true + +- name: Deploy Hetzner CSI + command: kubectl apply -f {{ csi_manifest_url }} + changed_when: true + +- name: Wait for CSI controller rollout + command: kubectl rollout status deployment/hcloud-csi-controller -n kube-system + register: csi_controller_rollout + until: csi_controller_rollout.rc == 0 + retries: 30 + delay: 10 + changed_when: false + +- name: Wait for CSI node daemonset rollout + command: kubectl rollout status daemonset/hcloud-csi-node -n kube-system + register: csi_node_rollout + until: csi_node_rollout.rc == 0 + retries: 30 + delay: 10 + changed_when: false diff --git a/ansible/site.yml b/ansible/site.yml index 89281e1..ded1dbf 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -82,13 +82,20 @@ roles: - ccm +- name: Deploy Hetzner CSI + hosts: control_plane[0] + become: true + + roles: + - csi + - name: Finalize hosts: localhost connection: local tasks: - name: Update kubeconfig server address command: | - sed -i 's/127.0.0.1/{{ hostvars[groups["control_plane"][0]]["k3s_primary_public_ip"] }}/g' ../outputs/kubeconfig + sed -i 's/127.0.0.1/{{ groups["control_plane"][0] }}.{{ tailscale_tailnet }}/g' ../outputs/kubeconfig changed_when: true - name: Display success message