Refactor Argo CD application management by removing the obsolete root-application.yaml and updating the bootstrap-root-application.yaml to include optional add-on Application manifests from clusters/noble/apps. Adjust documentation to clarify the deployment order and resource ownership, ensuring a streamlined GitOps process with Ansible and Argo CD.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
**Narrative walkthrough (Proxmox → Talos → platform → Argo):** [`docs/ansible-getting-started.md`](../docs/ansible-getting-started.md).
|
||||
|
||||
Automates [`talos/CLUSTER-BUILD.md`](../talos/CLUSTER-BUILD.md): optional **Talos Phase A** (genconfig → apply → bootstrap → kubeconfig), then **Phase B+** (CNI → add-ons → ingress → Argo CD → Kyverno → observability, etc.). **Trivy Operator** is installed via Argo (**`noble-trivy-operator`** app-of-apps), not **`noble.yml`**. **Argo CD** does not reconcile core charts — optional GitOps starts from an empty [`clusters/noble/apps/kustomization.yaml`](../clusters/noble/apps/kustomization.yaml).
|
||||
Automates [`talos/CLUSTER-BUILD.md`](../talos/CLUSTER-BUILD.md): optional **Talos Phase A** (genconfig → apply → bootstrap → kubeconfig), then **Phase B+** (CNI → add-ons → ingress → Argo CD → Kyverno → observability, etc.). **Trivy Operator** is installed via Argo (**`noble-trivy-operator`** app-of-apps), not **`noble.yml`**. **Argo CD** does not reconcile core charts first — optional add-on **`Application`** manifests live under [`clusters/noble/apps/`](../clusters/noble/apps/) and are included when **`noble_platform`** runs **`kubectl apply -k clusters/noble/bootstrap`** (see [`clusters/noble/apps/README.md`](../clusters/noble/apps/README.md)).
|
||||
|
||||
## Order of operations
|
||||
|
||||
@@ -82,7 +82,7 @@ ansible-playbook playbooks/noble.yml --tags authentik -e noble_authentik_install
|
||||
|
||||
### Variables — `inventory/group_vars/` and role defaults
|
||||
|
||||
- **`inventory/group_vars/all.yml`:** **`noble_newt_install`**, **`noble_velero_install`**, **`noble_authentik_install`**, **`noble_cert_manager_require_cloudflare_secret`**, **`noble_argocd_apply_root_application`**, **`noble_argocd_apply_bootstrap_root_application`**, **`noble_k8s_api_server_override`**, **`noble_k8s_api_server_auto_fallback`**, **`noble_k8s_api_server_fallback`**, **`noble_skip_k8s_health_check`**
|
||||
- **`inventory/group_vars/all.yml`:** **`noble_newt_install`**, **`noble_velero_install`**, **`noble_authentik_install`**, **`noble_cert_manager_require_cloudflare_secret`**, **`noble_argocd_apply_bootstrap_root_application`**, **`noble_k8s_api_server_override`**, **`noble_k8s_api_server_auto_fallback`**, **`noble_k8s_api_server_fallback`**, **`noble_skip_k8s_health_check`**
|
||||
- **`roles/noble_platform/defaults/main.yml`:** **`noble_apply_sops_secrets`**, **`noble_sops_age_key_file`**, **`noble_platform_loki_helm_wait_timeout`**, **`noble_platform_wait_longhorn_csi_before_loki`**, **`noble_platform_longhorn_csi_rollout_timeout`**
|
||||
|
||||
## Roles
|
||||
@@ -157,7 +157,7 @@ ansible-playbook -i inventory/proxmox.yml playbooks/proxmox_ops.yml
|
||||
|
||||
```bash
|
||||
kubectl delete application -n argocd noble-platform noble-kyverno noble-kyverno-policies --ignore-not-found
|
||||
kubectl apply -f clusters/noble/bootstrap/argocd/root-application.yaml
|
||||
kubectl apply -f clusters/noble/bootstrap/argocd/bootstrap-root-application.yaml
|
||||
```
|
||||
|
||||
Then run `playbooks/noble.yml` so Helm state matches git values.
|
||||
|
||||
@@ -22,9 +22,7 @@ noble_cert_manager_require_cloudflare_secret: true
|
||||
# Velero — set **noble_velero_install: true** plus S3 bucket/URL (and credentials — see clusters/noble/bootstrap/velero/README.md)
|
||||
noble_velero_install: false
|
||||
|
||||
# Argo CD — apply app-of-apps root Application (clusters/noble/bootstrap/argocd/root-application.yaml). Set false to skip.
|
||||
noble_argocd_apply_root_application: true
|
||||
# Bootstrap kustomize in Argo (**noble-bootstrap-root** → **clusters/noble/bootstrap**). Applied with manual sync; enable automation after **noble.yml** (see **clusters/noble/bootstrap/argocd/README.md** §5).
|
||||
# Bootstrap kustomize in Argo (**noble-bootstrap-root** → **clusters/noble/bootstrap**, includes **clusters/noble/apps**). Applied with manual sync; enable automation after **noble.yml** (see **clusters/noble/bootstrap/argocd/README.md** §5).
|
||||
noble_argocd_apply_bootstrap_root_application: true
|
||||
|
||||
# Authentik (OIDC IdP) + oauth2-proxy ForwardAuth — set **true** after **.env** has NOBLE_AUTHENTIK_* (see ansible/roles/noble_authentik/README.md).
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
---
|
||||
# When true, applies clusters/noble/bootstrap/argocd/root-application.yaml (app-of-apps).
|
||||
# Edit spec.source.repoURL in that file if your Git remote differs.
|
||||
noble_argocd_apply_root_application: false
|
||||
# When true, applies clusters/noble/bootstrap/argocd/bootstrap-root-application.yaml (noble-bootstrap-root; manual sync until README §5).
|
||||
noble_argocd_apply_bootstrap_root_application: true
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
# Run from **ansible/playbooks/noble.yml** *after* roles **noble_platform**, **noble_authentik**, **noble_velero**
|
||||
# (see play **tasks:**). Leaf **Application** CRs must not be reconciled before Ansible Helm finishes, or
|
||||
# **argocd-controller** can SSA resources without Helm release metadata (e.g. chart-owned ServiceAccounts).
|
||||
- name: Apply Argo CD root Application (app-of-apps)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/bootstrap/argocd/root-application.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
when: noble_argocd_apply_root_application | default(false) | bool
|
||||
changed_when: true
|
||||
|
||||
- name: Apply Argo CD bootstrap root Application
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
Private key: age-key.txt at repo root (gitignored). See clusters/noble/secrets/README.md
|
||||
and .sops.yaml. noble.yml decrypt-applies these when age-key.txt exists.
|
||||
|
||||
- name: Argo CD optional root Application (empty app-of-apps)
|
||||
- name: Argo CD bootstrap root and leaf Applications
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
App-of-apps: at the **end** of **noble.yml** (after **noble_platform**, **noble_authentik**,
|
||||
**noble_velero**), **noble_argocd** `applications_post_platform.yml` runs: root-application.yaml when
|
||||
noble_argocd_apply_root_application is true; bootstrap-root + **kubectl apply -k argocd/app-of-apps**
|
||||
when noble_argocd_apply_bootstrap_root_application is true (inventory/group_vars/all.yml).
|
||||
noble-bootstrap-root uses manual sync until you enable automation after the playbook —
|
||||
**noble_velero**), **noble_argocd** `applications_post_platform.yml` applies **bootstrap-root-application.yaml**
|
||||
and **kubectl apply -k argocd/app-of-apps** when **noble_argocd_apply_bootstrap_root_application** is true
|
||||
(inventory/group_vars/all.yml).
|
||||
**noble-bootstrap-root** syncs **clusters/noble/bootstrap** (which includes **clusters/noble/apps**); manual sync until you enable automation after the playbook —
|
||||
clusters/noble/bootstrap/argocd/README.md §5. See clusters/noble/apps/README.md and that README.
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
**Base cluster configuration** (CNI, MetalLB, ingress, cert-manager, storage, observability stack, policy, SOPS secrets path, etc.) is installed by **`ansible/playbooks/noble.yml`** from **`clusters/noble/bootstrap/`** — not from here.
|
||||
|
||||
**`noble-root`** (`clusters/noble/bootstrap/argocd/root-application.yaml`) points at **`clusters/noble/apps`**. Add **`Application`** manifests (and optional **`AppProject`** definitions) under this directory only for workloads that are additive and do not subsume the core platform.
|
||||
**`clusters/noble/apps`** is included by **`clusters/noble/bootstrap/kustomization.yaml`** (`resources: - ../apps`), so **`kubectl apply -k clusters/noble/bootstrap`** (Ansible **`noble_platform`**) and Argo **`noble-bootstrap-root`** apply optional **`Application`** / namespace manifests from this tree together with bootstrap static YAML.
|
||||
|
||||
Bootstrap kustomize (namespaces, static YAML, leaf **`Application`**s) lives in **`clusters/noble/bootstrap/`** and is tracked by **`noble-bootstrap-root`** — enable automated sync for that app only after **`noble.yml`** completes (**`clusters/noble/bootstrap/argocd/README.md`** §5). Put Helm **`Application`** migrations under **`clusters/noble/bootstrap/argocd/app-of-apps/`**.
|
||||
## Layout
|
||||
|
||||
- **`kustomization.yaml`** — lists only **subdirectories** that contain their own **`kustomization.yaml`** (add **`yourapp/`** + **`yourapp/kustomization.yaml`** instead of editing a long flat resource list).
|
||||
- **`*/application.yaml`** — Argo **`Application`** CRs; Helm **`values.yaml`** files stay in the same directory but are **not** kustomize resources (the Application references them via **`$values`** paths in the repo).
|
||||
|
||||
Put Helm **`Application`** definitions for core charts under **`clusters/noble/bootstrap/argocd/app-of-apps/`** (Ansible applies that directory after Helm roles). Use **`clusters/noble/apps`** only for workloads that are additive and do not subsume the core platform.
|
||||
|
||||
5
clusters/noble/apps/homepage/kustomization.yaml
Normal file
5
clusters/noble/apps/homepage/kustomization.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
# Helm values live alongside but are not kustomize resources — Argo loads them via **$values** in **application.yaml**.
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- application.yaml
|
||||
@@ -1,10 +1,8 @@
|
||||
# Argo CD **noble-root** syncs this directory. Add **Application** / **AppProject** manifests only for
|
||||
# optional workloads that do not replace Ansible bootstrap (CNI, ingress, storage, core observability, etc.).
|
||||
# Helm value files for those apps can live in subdirectories here (for example **./homepage/values.yaml**).
|
||||
# Optional add-on **Application** CRs and namespaces — composed only of sub-kustomizations (add a directory + **kustomization.yaml**).
|
||||
# Included from **clusters/noble/bootstrap/kustomization.yaml** so **kubectl apply -k clusters/noble/bootstrap** and
|
||||
# Argo **noble-bootstrap-root** apply this tree with the rest of bootstrap static YAML.
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- homepage/application.yaml
|
||||
- trivy/namespace.yaml
|
||||
- trivy/values.yaml
|
||||
- trivy/dashboard-values.yaml
|
||||
- homepage
|
||||
- trivy
|
||||
|
||||
5
clusters/noble/apps/trivy/kustomization.yaml
Normal file
5
clusters/noble/apps/trivy/kustomization.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
# Operator chart values are referenced from **bootstrap/argocd/app-of-apps** Applications (**$values** paths).
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
@@ -52,20 +52,19 @@ Use **Settings → Repositories** in the UI, or `argocd repo add` / a `Secret` o
|
||||
|
||||
## 4. App-of-apps (GitOps)
|
||||
|
||||
**Ansible** (`ansible/playbooks/noble.yml`) runs **`kubectl apply -k clusters/noble/bootstrap`** from **`noble_platform`**, then Helm for the platform stack, **then** **`noble_authentik`**, **`noble_velero`**, and **only then** (play **`tasks:`**) **`noble_argocd`** `applications_post_platform.yml` applies **`root-application.yaml`**, **`bootstrap-root-application.yaml`**, and **`kubectl apply -k clusters/noble/bootstrap/argocd/app-of-apps`**. **Trivy Operator** is **not** installed by Ansible; sync the **`noble-trivy-operator`** leaf app (or enable automation) after **`noble.yml`**. That order keeps **Ansible Helm first** and lets Argo **take ownership** when you sync or enable automation (no premature SSA vs Helm).
|
||||
**Ansible** (`ansible/playbooks/noble.yml`) runs **`kubectl apply -k clusters/noble/bootstrap`** from **`noble_platform`**, then Helm for the platform stack, **then** **`noble_authentik`**, **`noble_velero`**, and **only then** (play **`tasks:`**) **`noble_argocd`** `applications_post_platform.yml` applies **`bootstrap-root-application.yaml`**, and **`kubectl apply -k clusters/noble/bootstrap/argocd/app-of-apps`**. **Trivy Operator** is **not** installed by Ansible; sync the **`noble-trivy-operator`** leaf app (or enable automation) after **`noble.yml`**. That order keeps **Ansible Helm first** and lets Argo **take ownership** when you sync or enable automation (no premature SSA vs Helm).
|
||||
|
||||
1. Edit **`root-application.yaml`** and **`bootstrap-root-application.yaml`**: set **`repoURL`** and **`targetRevision`**. The **`resources-finalizer.argocd.argoproj.io/background`** finalizer uses Argo’s path-qualified form so **`kubectl apply`** does not warn about finalizer names.
|
||||
2. Optional add-on apps: add **`Application`** manifests under **`clusters/noble/apps/`** (see **`clusters/noble/apps/README.md`**).
|
||||
3. **Bootstrap kustomize** (namespaces, datasource, etc.): **`noble-bootstrap-root`** syncs **`clusters/noble/bootstrap`** (no **`argocd/app-of-apps/`** in that kustomization). Leaf **`Application`** manifests live under **`argocd/app-of-apps/`**; Ansible applies that directory **after** all **`noble_*`** Helm roles in **`noble.yml`** (see §4) so Argo does not SSA charts before Helm. The root app uses **manual** sync; each leaf app is **manual** until you enable automation (see **§5**).
|
||||
1. Edit **`bootstrap-root-application.yaml`**: set **`repoURL`** and **`targetRevision`**. The **`resources-finalizer.argocd.argoproj.io/background`** finalizer uses Argo’s path-qualified form so **`kubectl apply`** does not warn about finalizer names.
|
||||
2. Optional add-on apps: add a subdirectory under **`clusters/noble/apps/`** with its own **`kustomization.yaml`** (see **`clusters/noble/apps/README.md`**). The bootstrap kustomization includes **`../apps`**, so **`noble-bootstrap-root`** applies them with the rest of bootstrap static YAML.
|
||||
3. **Bootstrap kustomize** (namespaces, datasource, optional **`clusters/noble/apps`**, etc.): **`noble-bootstrap-root`** syncs **`clusters/noble/bootstrap`**. Leaf chart **`Application`** manifests for core charts live under **`argocd/app-of-apps/`**; Ansible applies that directory **after** all **`noble_*`** Helm roles in **`noble.yml`** (see §4) so Argo does not SSA charts before Helm. The bootstrap root app uses **manual** sync; each leaf app is **manual** until you enable automation (see **§5**).
|
||||
|
||||
**`ansible/playbooks/noble.yml`**: roles **`noble_argocd`** (Argo Helm only), **`noble_platform`**, **`noble_authentik`**, **`noble_velero`**, then play **`tasks`** run **`applications_post_platform`** when **`noble_argocd_apply_*`** flags are set in **`ansible/inventory/group_vars/all.yml`**. Trivy is deployed only via Argo (**`noble-trivy-operator`**).
|
||||
**`ansible/playbooks/noble.yml`**: roles **`noble_argocd`** (Argo Helm only), **`noble_platform`**, **`noble_authentik`**, **`noble_velero`**, then play **`tasks`** run **`applications_post_platform`** when **`noble_argocd_apply_bootstrap_root_application`** is set in **`ansible/inventory/group_vars/all.yml`**. Trivy is deployed only via Argo (**`noble-trivy-operator`**).
|
||||
|
||||
```bash
|
||||
kubectl apply -f clusters/noble/bootstrap/argocd/root-application.yaml
|
||||
kubectl apply -f clusters/noble/bootstrap/argocd/bootstrap-root-application.yaml
|
||||
```
|
||||
|
||||
If you migrated from older GitOps **`Application`** names, delete stale **`Application`** objects on the cluster (see **`clusters/noble/apps/README.md`**) then re-apply the roots.
|
||||
If you migrated from older GitOps **`Application`** names, delete stale **`Application`** objects on the cluster (see **`clusters/noble/apps/README.md`**) then re-apply the bootstrap root.
|
||||
|
||||
**Trivy (`noble-trivy-operator`):** If an older install left an orphan **`ServiceMonitor`** named **`trivy-operator`** in **`monitoring`** (missing `meta.helm.sh/release-*` annotations), Helm/Argo will refuse to adopt it. Delete once, then sync **`noble-trivy-operator`**:
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# **noble-bootstrap-root** — Kustomize for **clusters/noble/bootstrap** (namespaces, Grafana datasource,
|
||||
# VolumeSnapshotClass, etc.). Leaf **Application** CRs under **argocd/app-of-apps/** are **not** in this
|
||||
# path; Ansible applies them after all **noble.yml** Helm roles (see play **tasks:** → **applications_post_platform.yml**).
|
||||
# VolumeSnapshotClass, etc.) plus **clusters/noble/apps** (optional leaf **Application** / namespace YAML),
|
||||
# included via **bootstrap/kustomization.yaml** → **../apps**. Leaf chart **Application** CRs under
|
||||
# **argocd/app-of-apps/** are **not** in this path; Ansible applies them after all **noble.yml** Helm roles
|
||||
# (see play **tasks:** → **applications_post_platform.yml**).
|
||||
#
|
||||
# **Initial deploy:** Ansible is the only writer; **automated sync is off** so Argo does not reconcile
|
||||
# during **noble.yml**. **After** the playbook finishes, enable automated sync (see **README.md** §5)
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# App-of-apps root — apply after Argo CD is running (optional).
|
||||
#
|
||||
# 1. Set spec.source.repoURL (and targetRevision — **HEAD** tracks the remote default branch) to this repo.
|
||||
# 2. kubectl apply -f clusters/noble/bootstrap/argocd/root-application.yaml
|
||||
#
|
||||
# **clusters/noble/apps** holds optional **Application** manifests. **noble_platform** applies
|
||||
# **clusters/noble/bootstrap/kustomization.yaml** (namespaces + static YAML), Helm installs, then
|
||||
# **applications_post_platform.yml** applies **bootstrap-root-application.yaml** and **argocd/app-of-apps/**.
|
||||
# **noble-bootstrap-root** tracks bootstrap kustomize (**manual** sync until README §5).
|
||||
#
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: noble-root
|
||||
namespace: argocd
|
||||
# Path suffix satisfies Kubernetes’ domain-qualified finalizer guidance (avoids kubectl warning).
|
||||
# Background cascade: Application deletes after resources are removed asynchronously.
|
||||
# See: https://argo-cd.readthedocs.io/en/stable/user-guide/app_deletion/#about-the-deletion-finalizer
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io/background
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://gitea.pcenicni.ca/gsdavidp/home-server.git
|
||||
targetRevision: HEAD
|
||||
path: clusters/noble/apps
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: argocd
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# Initial admin password: kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
|
||||
#
|
||||
# Optional: kubectl apply -f clusters/noble/bootstrap/argocd/root-application.yaml
|
||||
# Optional: kubectl apply -f clusters/noble/bootstrap/argocd/bootstrap-root-application.yaml
|
||||
|
||||
global:
|
||||
domain: argo.apps.noble.lab.pcenicni.dev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Ansible **noble_platform**: `kubectl apply -k` this directory (namespaces + static YAML only).
|
||||
# Ansible **noble_platform**: `kubectl apply -k` this directory (namespaces + static YAML + **../apps** optional Argo leaf Applications).
|
||||
# Leaf Argo **Application** manifests live under **argocd/app-of-apps/** and are applied at the **end**
|
||||
# of **ansible/playbooks/noble.yml** (play **tasks:** → **noble_argocd** `applications_post_platform.yml`) so
|
||||
# **argocd-controller** does not SSA chart resources before **helm upgrade** (platform, authentik, velero, …).
|
||||
@@ -19,4 +19,5 @@ resources:
|
||||
- velero/namespace.yaml
|
||||
- velero/longhorn-volumesnapshotclass.yaml
|
||||
- headlamp/namespace.yaml
|
||||
- ../apps
|
||||
- grafana-loki-datasource/loki-datasource.yaml
|
||||
|
||||
@@ -10,7 +10,7 @@ Three **Application** resources (sync waves **0 → 1 → 2**):
|
||||
|
||||
**Prerequisites (cluster):** **cert-manager** + **Traefik** (noble bootstrap). **DNS:** `che.apps.noble.lab.pcenicni.dev` → Traefik LB (edit **`checluster.yaml`** if your domain differs).
|
||||
|
||||
**First sync:** Wave ordering applies to **Application** CRs under **noble-root**; if the operator starts before DevWorkspace is ready, **Refresh**/**Sync** the child apps once. See [Eclipse Che on Kubernetes](https://eclipse.dev/che/docs/stable/administration-guide/installing-che-on-kubernetes/).
|
||||
**First sync:** Wave ordering applies to **Application** CRs under **`clusters/noble/apps/`** (included in **noble-bootstrap-root**); if the operator starts before DevWorkspace is ready, **Refresh**/**Sync** the child apps once. See [Eclipse Che on Kubernetes](https://eclipse.dev/che/docs/stable/administration-guide/installing-che-on-kubernetes/).
|
||||
|
||||
**URL:** `kubectl get checluster eclipse-che -n eclipse-che -o jsonpath='{.status.cheURL}{"\n"}'` after **Phase** is **Active`.
|
||||
|
||||
|
||||
@@ -182,22 +182,20 @@ ansible-playbook playbooks/deploy.yml
|
||||
|
||||
Important mental model from [`clusters/noble/apps/README.md`](../clusters/noble/apps/README.md) and [`clusters/noble/bootstrap/argocd/README.md`](../clusters/noble/bootstrap/argocd/README.md):
|
||||
|
||||
- **Core platform** (CNI, storage, ingress, cert-manager, observability stack, Kyverno, etc.) is installed by **`noble.yml`** from **`clusters/noble/bootstrap/`** via Helm and kubectl — **Argo CD does not reconcile those charts by default** in the “empty apps folder” layout.
|
||||
- **`noble-root`** tracks **`clusters/noble/apps/`** for **optional** add-on `Application` manifests.
|
||||
- **`noble-bootstrap-root`** tracks **`clusters/noble/bootstrap/`** for GitOps alignment with bootstrap kustomize — enable **automated** sync only **after** Ansible has finished so Argo does not fight Helm mid-play.
|
||||
- **Core platform** (CNI, storage, ingress, cert-manager, observability stack, Kyverno, etc.) is installed by **`noble.yml`** from **`clusters/noble/bootstrap/`** via Helm and kubectl — **Argo CD does not reconcile those core Helm charts by default** (those leaves live under **`argocd/app-of-apps/`** and are applied after Ansible Helm).
|
||||
- **`noble-bootstrap-root`** tracks **`clusters/noble/bootstrap/`** (which **kustomize-includes** **`clusters/noble/apps/`**) for GitOps alignment with bootstrap kustomize and optional add-on **`Application`** manifests — enable **automated** sync only **after** Ansible has finished so Argo does not fight Helm mid-play.
|
||||
|
||||
### 4.1 What Ansible already does for Argo
|
||||
|
||||
At the **end** of **`noble.yml`**, after all Ansible Helm roles (**`noble_platform`**, **`noble_authentik`**, **`noble_velero`** when enabled), the play runs **`noble_argocd`** task file **`applications_post_platform.yml`**, which applies:
|
||||
|
||||
- **`clusters/noble/bootstrap/argocd/root-application.yaml`** when **`noble_argocd_apply_root_application`** is true.
|
||||
- **`bootstrap-root-application.yaml`** and **`kubectl apply -k clusters/noble/bootstrap/argocd/app-of-apps`** when **`noble_argocd_apply_bootstrap_root_application`** is true.
|
||||
|
||||
So the **root Application CRs** and **leaf Application** registrations typically already exist on the cluster after a successful **`noble.yml`**. They are created **last** on purpose so `argocd-application-controller` does not adopt resources before Helm installs them.
|
||||
So the **bootstrap root Application CR** and **leaf Application** registrations typically already exist on the cluster after a successful **`noble.yml`**. They are created **last** on purpose so `argocd-application-controller` does not adopt resources before Helm installs them.
|
||||
|
||||
### 4.2 Before you enable GitOps automation
|
||||
|
||||
1. **Edit Git URLs** in **`root-application.yaml`** and **`bootstrap-root-application.yaml`**: set **`repoURL`** and **`targetRevision`** to your real remote and branch.
|
||||
1. **Edit Git URLs** in **`bootstrap-root-application.yaml`**: set **`repoURL`** and **`targetRevision`** to your real remote and branch.
|
||||
2. **Register the repository** in Argo CD (UI, `argocd repo add`, or a repository `Secret`) if it is private.
|
||||
3. Leave **`noble-bootstrap-root`** on **manual** sync until Helm and the cluster match git (see **§5** in [`clusters/noble/bootstrap/argocd/README.md`](../clusters/noble/bootstrap/argocd/README.md)).
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ See [`talos/CLUSTER-BUILD.md`](../talos/CLUSTER-BUILD.md) for the authoritative
|
||||
|
||||
## Narrative
|
||||
|
||||
The **noble** environment is a **Talos** lab cluster on **`192.168.50.0/24`** with **three control plane nodes and one worker**, schedulable workloads on control planes enabled, and the Kubernetes API exposed through **kube-vip** at **`192.168.50.230`**. **Cilium** provides the CNI after Talos bootstrap with **`cni: none`**; **MetalLB** advertises **`192.168.50.210`–`192.168.50.229`**, pinning **Argo CD** to **`192.168.50.210`** and **Traefik** to **`192.168.50.211`** for **`*.apps.noble.lab.pcenicni.dev`**. **cert-manager** issues certificates for Traefik Ingresses; **GitOps** is **Ansible** for the **initial** platform install (**`clusters/noble/bootstrap/`**), then **Argo CD** for the kustomize tree (**`noble-bootstrap-root`** → **`clusters/noble/bootstrap`**) and optional apps (**`noble-root`** → **`clusters/noble/apps/`**) once automated sync is enabled after **`noble.yml`** (see **`clusters/noble/bootstrap/argocd/README.md`** §5). **Observability** uses **kube-prometheus-stack** in **`monitoring`**, **Loki** and **Fluent Bit** with Grafana wired via a **ConfigMap** datasource, with **Longhorn** PVCs for Prometheus, Grafana, Alertmanager, and Loki. **Secrets** in git use **SOPS** + **age** under **`clusters/noble/secrets/`**; **Kyverno** enforces **Pod Security Standards baseline** in **Audit**. **Public** access uses **Newt** to **Pangolin** with **CNAME** and Integration API steps as documented—not generic in-cluster public DNS.
|
||||
The **noble** environment is a **Talos** lab cluster on **`192.168.50.0/24`** with **three control plane nodes and one worker**, schedulable workloads on control planes enabled, and the Kubernetes API exposed through **kube-vip** at **`192.168.50.230`**. **Cilium** provides the CNI after Talos bootstrap with **`cni: none`**; **MetalLB** advertises **`192.168.50.210`–`192.168.50.229`**, pinning **Argo CD** to **`192.168.50.210`** and **Traefik** to **`192.168.50.211`** for **`*.apps.noble.lab.pcenicni.dev`**. **cert-manager** issues certificates for Traefik Ingresses; **GitOps** is **Ansible** for the **initial** platform install (**`clusters/noble/bootstrap/`**), then **Argo CD** for the kustomize tree (**`noble-bootstrap-root`** → **`clusters/noble/bootstrap`**, which includes **`clusters/noble/apps/`** for optional add-on **`Application`** manifests) once automated sync is enabled after **`noble.yml`** (see **`clusters/noble/bootstrap/argocd/README.md`** §5). **Observability** uses **kube-prometheus-stack** in **`monitoring`**, **Loki** and **Fluent Bit** with Grafana wired via a **ConfigMap** datasource, with **Longhorn** PVCs for Prometheus, Grafana, Alertmanager, and Loki. **Secrets** in git use **SOPS** + **age** under **`clusters/noble/secrets/`**; **Kyverno** enforces **Pod Security Standards baseline** in **Audit**. **Public** access uses **Newt** to **Pangolin** with **CNAME** and Integration API steps as documented—not generic in-cluster public DNS.
|
||||
|
||||
---
|
||||
|
||||
@@ -230,7 +230,7 @@ The **noble** environment is a **Talos** lab cluster on **`192.168.50.0/24`** wi
|
||||
|
||||
- **Split horizon:** Confirm whether only LAN DNS resolves `*.apps.noble.lab.pcenicni.dev` to **`192.168.50.211`** or whether public resolvers also point at that address.
|
||||
- **Velero / S3:** optional **Ansible** install (**`noble_velero_install`**) from **`clusters/noble/bootstrap/velero/`** once an S3-compatible backend and credentials exist (see **`talos/CLUSTER-BUILD.md`** Phase F).
|
||||
- **Argo CD:** Confirm **`repoURL`** in `root-application.yaml` and what is actually applied on-cluster.
|
||||
- **Argo CD:** Confirm **`repoURL`** in **`bootstrap-root-application.yaml`** and what is actually applied on-cluster.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Lab stack is **up** on-cluster through **Phase D**–**F** and **Phase G** (**`t
|
||||
- **Traefik** Helm **39.0.6** / app **v3.6.11** — `clusters/noble/bootstrap/traefik/`; **`Service`** **`LoadBalancer`** **`EXTERNAL-IP` `192.168.50.211`**; **`IngressClass`** **`traefik`** (default). Point **`*.apps.noble.lab.pcenicni.dev`** at **`192.168.50.211`**. MetalLB pool verification was done before replacing the temporary nginx test with Traefik.
|
||||
- **cert-manager** Helm **v1.20.0** / app **v1.20.0** — `clusters/noble/bootstrap/cert-manager/`; **`ClusterIssuer`** **`letsencrypt-staging`** and **`letsencrypt-prod`** (**DNS-01** via **Cloudflare** for **`pcenicni.dev`**, Secret **`cloudflare-dns-api-token`** in **`cert-manager`**); ACME email **`certificates@noble.lab.pcenicni.dev`** (edit in manifests if you want a different mailbox).
|
||||
- **Newt** Helm **1.2.0** / app **1.10.1** — `clusters/noble/bootstrap/newt/` (**fossorial/newt**); Pangolin site tunnel — **`newt-pangolin-auth`** Secret (**`PANGOLIN_ENDPOINT`**, **`NEWT_ID`**, **`NEWT_SECRET`**). Store credentials in git with **SOPS** (`clusters/noble/secrets/newt-pangolin-auth.secret.yaml`, **`age-key.txt`**, **`.sops.yaml`**) — see **`clusters/noble/secrets/README.md`**. **Public DNS** is **not** automated with ExternalDNS: **CNAME** records at your DNS host per Pangolin’s domain instructions, plus **Integration API** for HTTP resources/targets — see **`clusters/noble/bootstrap/newt/README.md`**. LAN access to Traefik can still use **`*.apps.noble.lab.pcenicni.dev`** → **`192.168.50.211`** (split horizon / local resolver).
|
||||
- **Argo CD** Helm **9.4.17** / app **v3.3.6** — `clusters/noble/bootstrap/argocd/`; **`argocd-server`** **`LoadBalancer`** **`192.168.50.210`**; **`noble-root`** → **`clusters/noble/apps/`**; **`noble-bootstrap-root`** → **`clusters/noble/bootstrap`** (manual sync until **`argocd/README.md`** §5 after **`noble.yml`**). Edit **`repoURL`** in both root **`Application`** files before applying.
|
||||
- **Argo CD** Helm **9.4.17** / app **v3.3.6** — `clusters/noble/bootstrap/argocd/`; **`argocd-server`** **`LoadBalancer`** **`192.168.50.210`**; **`noble-bootstrap-root`** → **`clusters/noble/bootstrap`** (kustomize includes **`clusters/noble/apps/`** for optional leaf **`Application`** manifests; manual sync until **`argocd/README.md`** §5 after **`noble.yml`**). Edit **`repoURL`** in **`bootstrap-root-application.yaml`** before applying.
|
||||
- **kube-prometheus-stack** — Helm chart **82.15.1** — `clusters/noble/bootstrap/kube-prometheus-stack/` (**namespace** `monitoring`, PSA **privileged** — **node-exporter** needs host mounts); **Longhorn** PVCs for Prometheus, Grafana, Alertmanager; **node-exporter** DaemonSet **4/4**. **Grafana Ingress:** **`https://grafana.apps.noble.lab.pcenicni.dev`** (Traefik **`ingressClassName: traefik`**, **`cert-manager.io/cluster-issuer: letsencrypt-prod`**). **Loki** datasource in Grafana: ConfigMap **`clusters/noble/bootstrap/grafana-loki-datasource/loki-datasource.yaml`** (sidecar label **`grafana_datasource: "1"`**) — not via **`grafana.additionalDataSources`** in the chart. **`helm upgrade --install` with `--wait` is silent until done** — use **`--timeout 30m`**; Grafana admin: Secret **`kube-prometheus-grafana`**, keys **`admin-user`** / **`admin-password`**.
|
||||
- **Loki** + **Fluent Bit** — **`grafana/loki` 6.55.0** SingleBinary + **filesystem** on **Longhorn** (`clusters/noble/bootstrap/loki/`); **`loki.auth_enabled: false`**; **`chunksCache.enabled: false`** (no memcached chunk cache). **`fluent/fluent-bit` 0.56.0** → **`loki-gateway.loki.svc:80`** (`clusters/noble/bootstrap/fluent-bit/`); **`logging`** PSA **privileged**. **Grafana Explore:** **`kubectl apply -f clusters/noble/bootstrap/grafana-loki-datasource/loki-datasource.yaml`** then **Explore → Loki** (e.g. `{job="fluent-bit"}`).
|
||||
- **SOPS** — cluster **`Secret`** manifests under **`clusters/noble/secrets/`** encrypted with **age** (see **`.sops.yaml`**, **`age-key.txt`** gitignored); **`noble.yml`** decrypt-applies when the private key is present.
|
||||
@@ -86,7 +86,7 @@ Lab stack is **up** on-cluster through **Phase D**–**F** and **Phase G** (**`t
|
||||
| Traefik (Helm values) | `clusters/noble/bootstrap/traefik/` — `values.yaml`, `namespace.yaml`, `README.md` |
|
||||
| cert-manager (Helm + ClusterIssuers) | `clusters/noble/bootstrap/cert-manager/` — `values.yaml`, `namespace.yaml`, `kustomization.yaml`, `README.md` |
|
||||
| Newt / Pangolin tunnel (Helm) | `clusters/noble/bootstrap/newt/` — `values.yaml`, `namespace.yaml`, `README.md` |
|
||||
| Argo CD (Helm) + app-of-apps | `clusters/noble/bootstrap/argocd/` — `values.yaml`, `root-application.yaml`, `bootstrap-root-application.yaml`, `app-of-apps/`, `README.md`; **`noble-root`** syncs **`clusters/noble/apps/`**; **`noble-bootstrap-root`** syncs **`clusters/noble/bootstrap`** (enable automation after **`noble.yml`**) |
|
||||
| Argo CD (Helm) + app-of-apps | `clusters/noble/bootstrap/argocd/` — `values.yaml`, `bootstrap-root-application.yaml`, `app-of-apps/`, `README.md`; **`noble-bootstrap-root`** syncs **`clusters/noble/bootstrap`** (includes **`clusters/noble/apps/`** via bootstrap **`kustomization.yaml`**) — enable automation after **`noble.yml`** |
|
||||
| kube-prometheus-stack (Helm values) | `clusters/noble/bootstrap/kube-prometheus-stack/` — `values.yaml`, `namespace.yaml` |
|
||||
| Grafana Loki datasource (ConfigMap; no chart change) | `clusters/noble/bootstrap/grafana-loki-datasource/loki-datasource.yaml` |
|
||||
| Loki (Helm values) | `clusters/noble/bootstrap/loki/` — `values.yaml`, `namespace.yaml` |
|
||||
@@ -151,7 +151,7 @@ Lab stack is **up** on-cluster through **Phase D**–**F** and **Phase G** (**`t
|
||||
|
||||
- [x] **Argo CD** bootstrap — `clusters/noble/bootstrap/argocd/` (`helm upgrade --install argocd …`) — also covered by **`ansible/playbooks/noble.yml`** (role **`noble_argocd`**)
|
||||
- [x] Argo CD server **LoadBalancer** — **`192.168.50.210`** (see `values.yaml`)
|
||||
- [x] **App-of-apps** — optional; **`clusters/noble/apps/kustomization.yaml`** is **empty** (core stack is **Ansible**-managed from **`clusters/noble/bootstrap/`**, not Argo). Set **`repoURL`** in **`root-application.yaml`** and add **`Application`** manifests only for optional GitOps workloads — see **`clusters/noble/apps/README.md`**
|
||||
- [x] **App-of-apps** — optional add-ons live under **`clusters/noble/apps/`** (each app is a subdirectory with its own **`kustomization.yaml`**); the tree is included from **`clusters/noble/bootstrap/kustomization.yaml`**. Core charts remain **Ansible**-managed from **`clusters/noble/bootstrap/`** with leaf **`Application`** CRs under **`argocd/app-of-apps/`**. Set **`repoURL`** in **`bootstrap-root-application.yaml`** — see **`clusters/noble/apps/README.md`**
|
||||
- [x] **Renovate** — **`renovate.json`** at repo root ([Renovate](https://docs.renovatebot.com/) — **Kubernetes** manager for **`clusters/noble/**/*.yaml`** image pins; grouped minor/patch PRs). **Activate PRs:** install **[Mend Renovate](https://github.com/apps/renovate)** on the Git repo (**Option A**), or **Option B:** self-hosted chart per [Helm charts](https://docs.renovatebot.com/helm-charts/) + token from **SOPS** or a one-off Secret. Helm **chart** versions pinned only in comments still need manual bumps or extra **regex** `customManagers` — extend **`renovate.json`** as needed.
|
||||
- [ ] SSO — later
|
||||
|
||||
|
||||
Reference in New Issue
Block a user