Skip to content

Commit 2e448cf

Browse files
committed
up
1 parent 2f306b9 commit 2e448cf

19 files changed

Lines changed: 285 additions & 688 deletions

README.md

Lines changed: 33 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -33,65 +33,31 @@ A GitOps-driven Kubernetes cluster using **Talos OS** (secure, immutable Linux f
3333

3434
```mermaid
3535
graph TD;
36-
subgraph "Git Repository"
37-
Bootstrap["argocd-app.yaml<br/>(Bootstrap Application)"]
38-
39-
InfraAppSet["infrastructure/root-appset.yaml<br/>(Infrastructure ApplicationSet)"]
40-
MonAppSet["monitoring/monitoring-components-appset.yaml<br/>(Monitoring ApplicationSet)"]
41-
AppsAppSet["my-apps/myapplications-appset.yaml<br/>(Applications ApplicationSet)"]
42-
43-
InfraDirs["infrastructure/*/*<br/>(e.g., controllers/argocd)"]
44-
MonDirs["monitoring/*/*<br/>(e.g., prometheus-stack)"]
45-
AppDirs["my-apps/*/*<br/>(e.g., media/plex)"]
46-
47-
InfraAppSet -- "scans" --> InfraDirs
48-
MonAppSet -- "scans" --> MonDirs
49-
AppsAppSet -- "scans" --> AppDirs
36+
subgraph "Bootstrap Process (Manual)"
37+
User(["👨‍💻 User"]) -- "kubectl apply -k" --> Kustomization["infrastructure/controllers/argocd/kustomization.yaml"];
38+
Kustomization -- "Deploys" --> ArgoCD["ArgoCD<br/>(from Helm Chart)"];
39+
Kustomization -- "Deploys" --> RootApp["Root Application<br/>(root.yaml)"];
5040
end
5141
52-
subgraph "ArgoCD Self-Management"
53-
ArgoCD["ArgoCD Controller"] -- "Deploys itself via" --> Bootstrap
54-
55-
subgraph "Self-Managed ApplicationSets"
56-
InfraAS["Infrastructure ApplicationSet"]
57-
MonAS["Monitoring ApplicationSet"]
58-
AppsAS["Applications ApplicationSet"]
59-
end
60-
61-
Bootstrap -- "Creates & Manages" --> InfraAS
62-
Bootstrap -- "Creates & Manages" --> MonAS
63-
Bootstrap -- "Creates & Manages" --> AppsAS
64-
65-
subgraph "Generated Applications"
66-
InfraApps["infra-argocd<br/>infra-cilium<br/>infra-longhorn<br/>..."]
67-
MonApps["monitoring-prometheus-stack<br/>monitoring-loki-stack<br/>..."]
68-
UserApps["media-plex<br/>ai-ollama<br/>home-frigate<br/>..."]
69-
end
70-
71-
InfraAS -- "Generates" --> InfraApps
72-
MonAS -- "Generates" --> MonApps
73-
AppsAS -- "Generates" --> UserApps
42+
subgraph "GitOps Self-Management Loop (Automatic)"
43+
ArgoCD -- "1. Syncs" --> RootApp;
44+
RootApp -- "2. Points to<br/>.../argocd/apps/" --> ArgoConfigDir["ArgoCD Config<br/>(Projects & AppSets)"];
45+
ArgoCD -- "3. Deploys" --> AppSets["ApplicationSets"];
46+
AppSets -- "4. Scan Repo for<br/>argo-app.yaml" --> AppManifests["Application Manifests<br/>(e.g., my-apps/nginx/*)"];
47+
ArgoCD -- "5. Deploys" --> ClusterResources["Cluster Resources<br/>(Nginx, Prometheus, etc.)"];
7448
end
75-
76-
subgraph "Kubernetes Cluster"
77-
InfraRes["Infrastructure Resources<br/>(ArgoCD, Cilium, Storage)"]
78-
MonRes["Monitoring Resources<br/>(Prometheus, Grafana, Loki)"]
79-
AppRes["Application Resources<br/>(Plex, Ollama, Frigate)"]
80-
end
81-
82-
InfraApps -- "deploys" --> InfraRes
83-
MonApps -- "deploys" --> MonRes
84-
UserApps -- "deploys" --> AppRes
8549
86-
style Bootstrap fill:#f9f,stroke:#333,stroke-width:2px
87-
style ArgoCD fill:#9cf,stroke:#333,stroke-width:2px
50+
style User fill:#a2d5c6,stroke:#333
51+
style Kustomization fill:#5bc0de,stroke:#333
52+
style RootApp fill:#f0ad4e,stroke:#333
53+
style ArgoCD fill:#d9534f,stroke:#333
8854
```
8955

9056
### Key Features
91-
- **Enterprise GitOps Pattern**: Three separate ApplicationSets for clear separation of concerns
92-
- **Self-Managing ArgoCD**: ArgoCD manages its own installation, upgrades, and ApplicationSets
93-
- **Simple Directory Discovery**: No complex patterns - easy to understand and maintain
94-
- **Production Ready**: Proper error handling, retries, and monitoring integration
57+
- **Enterprise GitOps Pattern**: ApplicationSets provide clean separation of concerns.
58+
- **Self-Managing ArgoCD**: ArgoCD manages its own installation, upgrades, and ApplicationSets from a co-located `apps` directory.
59+
- **Simple Metadata Discovery**: Applications are discovered via a simple `argo-app.yaml` marker file. No complex pathing needed.
60+
- **Production Ready**: Proper error handling, retries, and monitoring integration.
9561
- **GPU Integration**: Full NVIDIA GPU support via Talos system extensions and GPU Operator
9662
- **Zero SSH**: All node management via Talosctl API
9763

@@ -180,30 +146,27 @@ This cluster uses [1Password Connect](https://developer.1password.com/docs/conne
180146
```
181147

182148
### 6. Bootstrap ArgoCD & Deploy The Stack
183-
This final step uses a carefully ordered process to install ArgoCD and then deploy every other component.
149+
This final step uses our "App of Apps" pattern to bootstrap the entire cluster from a single command.
184150

185151
```bash
186-
# 1. Install ArgoCD Components & CRDs
187-
# This uses kustomize to build the official Helm chart and apply the manifests.
152+
# 1. Apply the ArgoCD Bootstrap Manifests
153+
# This single command does everything:
154+
# - Deploys the ArgoCD Helm chart, including its CRDs.
155+
# - Deploys the 'root' Application, which points to our self-managing configuration.
188156
kustomize build infrastructure/controllers/argocd --enable-helm | kubectl apply -f -
189157
190158
# 2. Wait for ArgoCD to be ready (2-5 minutes)
159+
# This ensures the ArgoCD server is running before you try to access its UI or API.
191160
kubectl wait --for=condition=Available deployment/argocd-server -n argocd --timeout=300s
192-
193-
# 3. Bootstrap ArgoCD to Manage Itself and Create Projects
194-
# Now that ArgoCD is running, we apply the Application resource that tells
195-
# ArgoCD to manage its own installation from Git. We also apply the projects.
196-
kubectl apply -f infrastructure/controllers/argocd/projects.yaml
197-
kubectl apply -f infrastructure/argocd-app.yaml
198-
199-
# 4. Deploy the ApplicationSets
200-
# With ArgoCD managing itself, we can now deploy the ApplicationSets,
201-
# which will discover and sync all other applications.
202-
kubectl apply -f infrastructure/infrastructure-components-appset.yaml
203-
kubectl apply -f monitoring/monitoring-components-appset.yaml
204-
kubectl apply -f my-apps/myapplications-appset.yaml
205161
```
206-
**That's it!** ArgoCD will now build the entire cluster state from the Git repository.
162+
**That's it!** You have successfully bootstrapped the cluster.
163+
164+
### What Happens Next Automatically?
165+
166+
1. **ArgoCD Syncs Itself**: The `root` Application tells ArgoCD to sync the contents of `infrastructure/controllers/argocd/apps/`.
167+
2. **Projects & AppSets Created**: ArgoCD creates the `AppProject`s and the three `ApplicationSet`s (`infrastructure`, `monitoring`, `my-apps`).
168+
3. **Applications Discovered**: The `ApplicationSet`s scan the repository for any directory containing an `argo-app.yaml` file and create the corresponding ArgoCD `Application` resources.
169+
4. **Cluster Reconciliation**: ArgoCD syncs all discovered applications, building the entire cluster state declaratively from Git.
207170
208171
## 🔍 Verification
209172
After the final step, you can monitor the deployment and verify that everything is working correctly.
@@ -404,7 +367,7 @@ kubectl get applicationsets -n argocd -o name | xargs -I{} kubectl patch {} -n a
404367
kubectl delete applicationsets --all -n argocd
405368
406369
# Bootstrap with the new enterprise pattern
407-
kubectl apply -f infrastructure/argocd-app.yaml
370+
kustomize build infrastructure/controllers/argocd --enable-helm | kubectl apply -f -
408371
```
409372
410373
## 🚀 Taking to Production

infrastructure/argocd-app.yaml

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
apiVersion: argoproj.io/v1alpha1
2+
kind: ApplicationSet
3+
metadata:
4+
name: infrastructure
5+
namespace: argocd
6+
spec:
7+
preserveResourcesOnDeletion: true
8+
generators:
9+
- git:
10+
repoURL: https://github.com/mitchross/k3s-argocd-proxmox.git # TODO: Replace with your repo URL
11+
revision: HEAD
12+
# Discover any 'argo-app.yaml' file within the infrastructure directory.
13+
files:
14+
- path: "infrastructure/**/argo-app.yaml"
15+
template:
16+
metadata:
17+
name: '{{name}}'
18+
namespace: argocd
19+
finalizers:
20+
- resources-finalizer.argocd.argoproj.io
21+
spec:
22+
project: infrastructure
23+
source:
24+
repoURL: https://github.com/mitchross/k3s-argocd-proxmox.git # TODO: Replace with your repo URL
25+
targetRevision: HEAD
26+
# The path points directly to the directory containing the argo-app.yaml file.
27+
path: '{{path.directory}}'
28+
destination:
29+
server: https://kubernetes.default.svc
30+
namespace: '{{namespace}}'
31+
syncPolicy:
32+
automated:
33+
prune: true
34+
selfHeal: true
35+
syncOptions:
36+
- CreateNamespace=true
37+
- RespectIgnoreDifferences=true
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
apiVersion: argoproj.io/v1alpha1
2+
kind: ApplicationSet
3+
metadata:
4+
name: monitoring
5+
namespace: argocd
6+
spec:
7+
preserveResourcesOnDeletion: true
8+
generators:
9+
- git:
10+
repoURL: https://github.com/mitchross/k3s-argocd-proxmox.git # TODO: Replace with your repo URL
11+
revision: HEAD
12+
# Discover any 'argo-app.yaml' file within the monitoring directory.
13+
files:
14+
- path: "monitoring/**/argo-app.yaml"
15+
template:
16+
metadata:
17+
name: '{{name}}'
18+
namespace: argocd
19+
finalizers:
20+
- resources-finalizer.argocd.argoproj.io
21+
spec:
22+
project: monitoring
23+
source:
24+
repoURL: https://github.com/mitchross/k3s-argocd-proxmox.git # TODO: Replace with your repo URL
25+
targetRevision: HEAD
26+
# The path points directly to the directory containing the argo-app.yaml file.
27+
path: '{{path.directory}}'
28+
destination:
29+
server: https://kubernetes.default.svc
30+
namespace: '{{namespace}}'
31+
syncPolicy:
32+
automated:
33+
prune: true
34+
selfHeal: true
35+
syncOptions:
36+
- CreateNamespace=true
37+
- RespectIgnoreDifferences=true
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
apiVersion: argoproj.io/v1alpha1
2+
kind: ApplicationSet
3+
metadata:
4+
name: my-apps
5+
namespace: argocd
6+
spec:
7+
preserveResourcesOnDeletion: true
8+
generators:
9+
- git:
10+
repoURL: https://github.com/mitchross/k3s-argocd-proxmox.git # TODO: Replace with your repo URL
11+
revision: HEAD
12+
# Discover any 'argo-app.yaml' file within the my-apps directory.
13+
files:
14+
- path: "my-apps/**/argo-app.yaml"
15+
template:
16+
metadata:
17+
# The name is dynamically set from the 'name' field in each argo-app.yaml
18+
name: '{{name}}'
19+
namespace: argocd
20+
finalizers:
21+
- resources-finalizer.argocd.argoproj.io
22+
spec:
23+
project: my-apps
24+
source:
25+
repoURL: https://github.com/mitchross/k3s-argocd-proxmox.git # TODO: Replace with your repo URL
26+
targetRevision: HEAD
27+
# The path points directly to the directory containing the argo-app.yaml file.
28+
path: '{{path.directory}}'
29+
destination:
30+
server: https://kubernetes.default.svc
31+
# The namespace is dynamically set from the 'namespace' field in each argo-app.yaml
32+
namespace: '{{namespace}}'
33+
syncPolicy:
34+
automated:
35+
prune: true
36+
selfHeal: true
37+
syncOptions:
38+
- CreateNamespace=true
39+
- RespectIgnoreDifferences=true
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: kustomize.config.k8s.io/v1beta1
2+
kind: Kustomization
3+
resources:
4+
- projects.yaml
5+
- appsets/infrastructure-appset.yaml
6+
- appsets/my-apps-appset.yaml
7+
- appsets/monitoring-appset.yaml
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
apiVersion: argoproj.io/v1alpha1
2+
kind: AppProject
3+
metadata:
4+
name: infrastructure
5+
namespace: argocd
6+
# Add a finalizer to ensure that the project is deleted from ArgoCD if this file is ever removed.
7+
finalizers:
8+
- resources-finalizer.argocd.argoproj.io
9+
spec:
10+
description: "Infrastructure components like controllers, networking, and storage."
11+
sourceRepos:
12+
- '*' # For simplicity, but in production, you should lock this down to your specific Git repository URL.
13+
destinations:
14+
- namespace: '*'
15+
server: https://kubernetes.default.svc
16+
clusterResourceWhitelist:
17+
- group: '*'
18+
kind: '*'
19+
---
20+
apiVersion: argoproj.io/v1alpha1
21+
kind: AppProject
22+
metadata:
23+
name: my-apps
24+
namespace: argocd
25+
finalizers:
26+
- resources-finalizer.argocd.argoproj.io
27+
spec:
28+
description: "User-facing applications."
29+
sourceRepos:
30+
- '*'
31+
destinations:
32+
- namespace: '*'
33+
server: https://kubernetes.default.svc
34+
clusterResourceWhitelist:
35+
- group: '*'
36+
kind: '*'
37+
---
38+
apiVersion: argoproj.io/v1alpha1
39+
kind: AppProject
40+
metadata:
41+
name: monitoring
42+
namespace: argocd
43+
finalizers:
44+
- resources-finalizer.argocd.argoproj.io
45+
spec:
46+
description: "Monitoring and observability stack (Prometheus, Grafana, Loki)."
47+
sourceRepos:
48+
- '*'
49+
destinations:
50+
- namespace: '*'
51+
server: https://kubernetes.default.svc
52+
clusterResourceWhitelist:
53+
- group: '*'
54+
kind: '*'
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# This file provides the metadata for the ApplicationSet generator.
2+
# It tells ArgoCD how to create the Application for this component.
3+
name: infra-argocd
4+
namespace: argocd
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
apiVersion: kustomize.config.k8s.io/v1beta1
22
kind: Kustomization
3+
namespace: argocd
34
resources:
45
- ns.yaml
56
- http-route.yaml
7+
# This is the root application that manages our AppProjects and ApplicationSets.
8+
# By including it here, the ArgoCD installation will immediately start managing
9+
# the rest of the applications in the repository.
10+
- root.yaml
611
helmCharts:
712
- name: argo-cd
813
repo: https://argoproj.github.io/argo-helm
9-
version: 8.1.2
10-
releaseName: "argocd"
14+
version: "6.7.13" # It's good practice to pin the chart version
15+
releaseName: argocd
1116
namespace: argocd
1217
valuesFile: values.yaml
18+
includeCRDs: true

0 commit comments

Comments
 (0)