# k8s/talos-ci-cd/argocd-values.yaml # Argo CD — single-replica homelab install (fits the 4-CPU / 32 GB RAM budget). # Deployed via helmfile (name=argocd) so it sits alongside Authentik, MinIO, etc. # # UI is exposed via the cluster Ingress (k8s/ingress/ingress.yaml, # argocd.riotpiao.com) over the WireGuard/LAN-only nginx ingress — # never as a LoadBalancer, since argocd-server holds cluster-admin # credentials and that Ingress isn't reachable from the WAN. # # OIDC + RBAC declared in configs.cm / configs.rbac below — applied by Helm directly. # Requires: oidc-secret K8s secret (created by helmfile argocd presync hook from env vars). # CA trust for Forgejo repo clones injected into argocd-tls-certs-cm by postsync hook. global: domain: argocd.riotpiao.com configs: params: server.insecure: false # keep TLS on argocd-server even behind the ingress cm: # Must match the Ingress host above and the redirect URI registered in # Authentik (provision_oidc.py argocd_url) exactly — ArgoCD builds its # OIDC redirect_uri as "{url}/auth/callback", so any mismatch here is # what Authentik's "Invalid redirect URL" error means. url: "https://argocd.riotpiao.com" oidc.config: | name: Authentik issuer: https://authentik.riotpiao.com/application/o/argocd/ clientID: $oidc-secret:client-id clientSecret: $oidc-secret:client-secret requestedScopes: [openid, profile, email, groups] rootCA: | -----BEGIN CERTIFICATE----- MIIBbTCCARSgAwIBAgIUNa409I6cGHye4YqeiphmWDaCEXUwCgYIKoZIzj0EAwIw FTETMBEGA1UEAxMKaG9tZWxhYi1jYTAeFw0yNjA2MTcxNjUzMjVaFw0zNjA2MTQx NjUzMjVaMBUxEzARBgNVBAMTCmhvbWVsYWItY2EwWTATBgcqhkjOPQIBBggqhkjO PQMBBwNCAARwkubJPPdhgKcqr+3AEO2tr5I7MhC3zzeAqpmv8glngsweiGznaDhi Dbf8JFfilbrLEJBSuwHZQPuoNx+3fbvYo0IwQDAOBgNVHQ8BAf8EBAMCAqQwDwYD VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUod8iYq0+QyetnxfKDprIf3XbWkEwCgYI KoZIzj0EAwIDRwAwRAIgQ4HOLs5DOqcfAMv8NSImxoYN7TyebnlQAQXSARnIqBMC IB9RycFvG/rpJuz/LIKi4rf6RARjLcHM/zqhXQJvBw53 -----END CERTIFICATE----- rbac: policy.csv: | g, homelab-admins, role:admin policy.default: role:readonly server: replicas: 1 deploymentStrategy: type: Recreate resources: requests: cpu: 100m memory: 256Mi limits: cpu: 500m memory: 512Mi tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule # No Service of type LoadBalancer — port-forward only service: type: ClusterIP podAnnotations: secret.reloader.stakater.com/reload: "oidc-secret" configmap.reloader.stakater.com/reload: "argocd-tls-certs-cm,argocd-cm" metrics: enabled: true serviceMonitor: enabled: true repoServer: replicas: 1 resources: requests: cpu: 100m memory: 512Mi limits: cpu: 500m # 512Mi OOM-killed the container under CMP + Helm rendering of ~30 apps, # causing chronic restarts → not-ready → dropped Cilium backend → every # app's manifest comparison failed with "no route to host". 1Gi headroom. memory: 1Gi tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule metrics: enabled: true serviceMonitor: enabled: true # ── SOPS ConfigManagementPlugin ───────────────────────────────────────────── # initContainer fetches sops+yq into a shared volume; the sidecar runs # argocd-cmp-server with the plugin.yaml from the sops-cmp-plugin ConfigMap and # decrypts *.enc.yaml with the age key from the sops-age Secret. initContainers: - name: install-sops-tools image: alpine:3.20 command: [sh, -c] args: - | set -e apk add --no-cache curl curl -sSfL https://github.com/getsops/sops/releases/download/v3.9.0/sops-v3.9.0.linux.amd64 -o /custom-tools/sops curl -sSfL https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64 -o /custom-tools/yq chmod +x /custom-tools/sops /custom-tools/yq volumeMounts: - name: custom-tools mountPath: /custom-tools extraContainers: - name: sops-cmp image: quay.io/argoproj/argocd:v3.4.5 command: [/var/run/argocd/argocd-cmp-server] env: - name: PATH value: /custom-tools:/usr/local/bin:/usr/bin:/bin securityContext: runAsNonRoot: true runAsUser: 999 allowPrivilegeEscalation: false capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault volumeMounts: - mountPath: /var/run/argocd name: var-files - mountPath: /home/argocd/cmp-server/plugins name: plugins - mountPath: /home/argocd/cmp-server/config/plugin.yaml subPath: plugin.yaml name: sops-cmp-plugin - mountPath: /home/argocd/plugins/generate.sh subPath: generate.sh name: sops-cmp-plugin - mountPath: /custom-tools name: custom-tools - mountPath: /sops-age name: sops-age - mountPath: /tmp name: cmp-tmp volumes: - name: custom-tools emptyDir: {} - name: cmp-tmp emptyDir: {} - name: sops-cmp-plugin configMap: name: sops-cmp-plugin defaultMode: 0555 - name: sops-age secret: secretName: sops-age applicationSet: replicas: 1 resources: requests: cpu: 50m memory: 128Mi limits: cpu: 200m memory: 256Mi tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule controller: resources: requests: cpu: 100m memory: 256Mi limits: cpu: 1000m memory: 1Gi tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule metrics: enabled: true serviceMonitor: enabled: true redis: resources: requests: cpu: 50m memory: 64Mi limits: cpu: 200m memory: 128Mi tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule notifications: enabled: false # add back later if alert routing is needed