OneLab Kubernetes GitOps (Argo CD)

- Helm charts: onelab app + observability (Loki/Promtail/Grafana)
- Values under gitops/values/ with public-safe placeholders
- Argo CD Application (spec.sources, 2.6+)

Made-with: Cursor
This commit is contained in:
timotheereausanofi
2026-03-20 12:27:45 +01:00
commit 68f9745c06
44 changed files with 2466 additions and 0 deletions

31
gitops/values/README.md Normal file
View File

@@ -0,0 +1,31 @@
# GitOps values (operator entry point)
All environment-specific Helm input for the Argo CD `Application` should live here (plus `repoURL` / `targetRevision` in [`../argocd/application.yaml`](../argocd/application.yaml)).
## Files
| File | Purpose |
|------|---------|
| [`env-example.yaml`](env-example.yaml) | Tracked example for OneLab chart: ingress, persistence, registry pull secret wiring, **placeholder** secrets. Fork and edit hostnames/TLS names, then replace placeholders or overlay `secrets.local.yaml`. |
| [`observability.yaml`](observability.yaml) | Loki / Promtail / Grafana: retention, Promtail host paths, Grafana ingress host, **placeholder** admin password. Edit hosts/TLS together with `grafana.ini.server`. |
| [`secrets.example.yaml`](secrets.example.yaml) | Template of secret-shaped keys only — copy to `*.local.yaml` (gitignored) and reference from Argo. |
| [`instance-overrides.example.yaml`](instance-overrides.example.yaml) | Optional features (compliance, LDAP) — merge or add as another value file. |
## Argo `helm.valueFiles` (path rules)
Paths are **relative to each sources `path`** in the Application:
- Source `gitops/charts/onelab` → e.g. `../../values/env-example.yaml`, then optionally `../../values/secrets.local.yaml`.
- Source `gitops/observability` → e.g. `../../values/observability.yaml`, then optionally `../../values/observability.local.yaml`.
Later files in the list **override** earlier ones.
## Private secrets without committing them
1. Copy `secrets.example.yaml` to `secrets.local.yaml` (ignored by `*.local.yaml` at repo root).
2. Fill in real registry password, Postgres password, app tokens, Intercom, etc.
3. Add `- ../../values/secrets.local.yaml` under the onelab sources `helm.valueFiles` in your **local** Application manifest or a private overlay — or keep that change only on a private branch.
For Grafana, set `grafana.adminPassword` in a gitignored file merged with [`observability.yaml`](observability.yaml), or edit `observability.yaml` in a private fork.
See the full bootstrap narrative in [`../README.md`](../README.md).

View File

@@ -0,0 +1,48 @@
# Example environment overrides — copy patterns to a gitignored file (e.g. secrets.local.yaml)
# and add it to Argo helm.valueFiles after this file so secrets stay out of Git.
# See gitops/values/README.md and gitops/values/secrets.example.yaml.
registry:
createPullSecret: true
pullSecretName: hub-andrewalliance
server: hub.andrewalliance.com
username: public
password: "REPLACE_REGISTRY_PASSWORD"
imagePullSecrets:
- name: hub-andrewalliance
persistence:
mode: hostPath
hostPath:
data: /opt/onelab/data
logs: /opt/onelab/logs
postgresql:
auth:
password: "REPLACE_POSTGRES_PASSWORD"
onelab:
domain: "https://onelab.example.com"
secrets:
authTokenKey: "REPLACE_AUTH_TOKEN_KEY"
monitoringToken: "REPLACE_MONITORING_TOKEN"
rabbitToken: "REPLACE_RABBIT_TOKEN"
intercom:
appid: "REPLACE_INTERCOM_APP_ID"
secret: "REPLACE_INTERCOM_SECRET"
revproxy:
serviceType: ClusterIP
ingress:
enabled: true
className: traefik
host: onelab.example.com
path: /
pathType: Prefix
tls: true
tlsSecretName: onelab-tls
certManager:
clusterIssuer: letsencrypt-prod
annotations: {}

View File

@@ -0,0 +1,38 @@
# Copy to a private file (e.g. gitops/values/overrides.local.yaml, gitignored) or merge into gitops/values/env-example.yaml.
#
# Argo CD: under spec.sources, for the source with path gitops/charts/onelab, add another path to helm.valueFiles
# (paths are relative to that chart directory), e.g.:
# - ../../values/env-example.yaml
# - ../../values/secrets.local.yaml
# - ../../values/overrides.local.yaml
onelab:
compliance:
enabled: true
# Optional tweaks (defaults match chart values.yaml):
# requireElectronicSignature: true
# executionOperatorRestrictionPolicy: "reviewed"
# executionAdminExpertRestrictionPolicy: "reviewed"
# preventCsvImport: true
# preventManualMetadataEdit: true
# deviceRestart: true
ldap:
enabled: true
# timeout: 30
# encryption: "start_tls"
# policy: "your-policy"
# verifyCertificates: true
# Paths inside the ldap-worker container (mount certs via extraVolumes if needed):
# tlsCaPath: "/ldap/ca.crt"
# tlsCertPath: "/ldap/client.crt"
# tlsKeyPath: "/ldap/client.key"
# tlsCiphers: ""
# tlsSslVersion: ""
# Alternative: supply the full YAML yourself (bypasses chart templates in configurations.gotmpl for those keys).
# 1. kubectl create secret generic onelab-configurations-custom -n onelab \
# --from-file=configurations.yml=./my-configurations.yml
# 2. Set in values:
# configuration:
# existingSecretName: onelab-configurations-custom

View File

@@ -0,0 +1,144 @@
# Umbrella chart: Loki (SingleBinary + filesystem) + Promtail + Grafana.
# Keep promtail hostPath below in sync with persistence.hostPath.logs in gitops/values/env-example.yaml.
loki:
deploymentMode: SingleBinary
loki:
auth_enabled: false
commonConfig:
replication_factor: 1
storage:
type: filesystem
schemaConfig:
configs:
- from: "2024-04-01"
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: loki_index_
period: 24h
limits_config:
retention_period: 168h
ingestion_rate_mb: 16
ingestion_burst_size_mb: 32
singleBinary:
replicas: 1
persistence:
enabled: true
size: 10Gi
backend:
replicas: 0
read:
replicas: 0
write:
replicas: 0
ingester:
replicas: 0
querier:
replicas: 0
queryFrontend:
replicas: 0
queryScheduler:
replicas: 0
distributor:
replicas: 0
compactor:
replicas: 0
indexGateway:
replicas: 0
bloomCompactor:
replicas: 0
bloomGateway:
replicas: 0
ruler:
replicas: 0
minio:
enabled: false
lokiCanary:
enabled: false
test:
enabled: false
chunksCache:
enabled: false
resultsCache:
enabled: false
promtail:
config:
clients:
- url: http://{{ .Release.Name }}-loki-gateway.{{ .Release.Namespace }}.svc.cluster.local/loki/api/v1/push
snippets:
extraRelabelConfigs:
- action: keep
source_labels:
- __meta_kubernetes_namespace
regex: onelab
extraScrapeConfigs: |
- job_name: onelab-host-log-files
static_configs:
- targets:
- localhost
labels:
job: onelab-files
namespace: onelab
component: host-logs
__path__: /onelab-host-logs/**/*
extraVolumes:
- name: onelab-host-logs
hostPath:
path: /opt/onelab/logs
type: DirectoryOrCreate
extraVolumeMounts:
- name: onelab-host-logs
mountPath: /onelab-host-logs
readOnly: true
grafanaOnelabIngress:
enabled: true
className: traefik
host: grafana.onelab.example.com
tls: true
tlsSecretName: grafana-onelab-tls
clusterIssuer: letsencrypt-prod
servicePort: 80
annotations: {}
grafana:
adminUser: admin
adminPassword: "REPLACE_GRAFANA_ADMIN_PASSWORD"
initChownData:
enabled: false
sidecar:
dashboards:
enabled: true
label: grafana_dashboard
folder: /tmp/dashboards
provider:
foldersFromFilesStructure: false
allowUiUpdates: true
datasources:
enabled: false
persistence:
enabled: true
size: 2Gi
service:
type: ClusterIP
grafana.ini:
server:
domain: grafana.onelab.example.com
root_url: https://grafana.onelab.example.com/
ingress:
enabled: false
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Loki
type: loki
uid: loki
url: http://{{ .Release.Name }}-loki-gateway.{{ .Release.Namespace }}.svc.cluster.local
access: proxy
isDefault: true
jsonData:
maxLines: 1000

View File

@@ -0,0 +1,26 @@
# Copy to a gitignored file (e.g. gitops/values/secrets.local.yaml — match *.local.yaml in repo .gitignore).
# Add it as the LAST entry in spec.sources[].helm.valueFiles for the onelab chart so these values win.
#
# Do not commit real values.
registry:
username: public
password: "YOUR_REGISTRY_PASSWORD"
postgresql:
auth:
password: "YOUR_POSTGRES_PASSWORD"
onelab:
secrets:
authTokenKey: "YOUR_AUTH_TOKEN_KEY"
monitoringToken: "YOUR_MONITORING_TOKEN"
rabbitToken: "YOUR_RABBIT_TOKEN"
intercom:
appid: "YOUR_INTERCOM_APP_ID"
secret: "YOUR_INTERCOM_SECRET"
# Optional: Grafana admin password is normally set in gitops/values/observability.yaml;
# override there or add a second gitignored value file for the observability source.
# grafana:
# adminPassword: "YOUR_GRAFANA_PASSWORD"