move archive

This commit is contained in:
2026-05-18 15:15:36 -05:00
parent 1f7318f1c3
commit 8601ad9cd9
17 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
# ------------------------------------------------------------------------------
# Platform: ArgoCD Configuration (post-bootstrap)
# Wave 2 — after ESO (wave 1), needs 1Password for Authentik client secret
#
# This is NOT the ArgoCD install (that's a manual bootstrap step).
# This Application manages ArgoCD's own configuration declaratively:
# - argocd-cm (URL, Dex/OIDC config, repo credentials)
# - argocd-rbac-cm (RBAC policies mapped from Authentik groups)
# - argocd-secret (Authentik client secret via ESO)
#
# ArgoCD managing its own config is intentional and works cleanly —
# it's the "self-managed ArgoCD" pattern.
# ------------------------------------------------------------------------------
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd-config
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
project: default
source:
repoURL: https://gitea.mk-labs.cloud/rblundon/homelab.git
targetRevision: main
path: cluster/platform/argocd
directory:
exclude: "application.yaml"
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: false
selfHeal: true
syncOptions:
- ServerSideApply=true
ignoreDifferences:
# ArgoCD mutates its own secret — ignore those fields
- group: ""
kind: Secret
name: argocd-secret
jsonPointers:
- /data/admin.password
- /data/admin.passwordMtime
- /data/server.secretkey

View File

@@ -0,0 +1,69 @@
# ------------------------------------------------------------------------------
# argocd-cm — ArgoCD Core Configuration
#
# Configures:
# - ArgoCD public URL (used in Dex redirect URIs)
# - Dex connector to Authentik OIDC
# - Gitea repo credentials reference
#
# Authentik side setup (manual — do this in guest-relations before bootstrapping):
# 1. Admin UI → Applications → Create New Application
# 2. Provider type: OAuth2/OpenID Connect
# 3. Name: argocd
# 4. Authorization flow: default-provider-authorization-explicit-consent
# 5. Client type: Confidential
# 6. Strict redirect URIs:
# https://argocd.local.mk-labs.cloud/api/dex/callback
# http://localhost:8085/auth/callback (ArgoCD CLI)
# 7. Scopes: openid, profile, email, groups
# 8. Note the Client ID and Client Secret → store in 1Password as:
# Item: "argocd-oidc"
# Fields: client-id, client-secret
# 9. Create two groups in Authentik:
# - argocd-admins (add your user)
# - argocd-viewers (read-only users)
# ------------------------------------------------------------------------------
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
# Public URL — must match the HTTPRoute hostname
url: https://argocd.local.mk-labs.cloud
# Dex connector to Authentik
# Using Dex (not native OIDC) to preserve ArgoCD CLI functionality
dex.config: |
connectors:
- type: oidc
id: authentik
name: Authentik
config:
# Authentik OIDC issuer — slug must match the Application slug in Authentik
# Slug is auto-generated from the app name, usually lowercase with hyphens
issuer: https://authentik.local.mk-labs.cloud/application/o/argocd/
clientID: $dex.authentik.clientID
clientSecret: $dex.authentik.clientSecret
redirectURI: https://argocd.local.mk-labs.cloud/api/dex/callback
scopes:
- openid
- profile
- email
- groups
insecureEnableGroups: true
groupsKey: groups
userIDKey: sub
userNameKey: preferred_username
emailKey: email
# Gitea repo — ArgoCD needs credentials to pull from your private repo
# Credentials are stored as a Repository secret (see repository-secret.yaml)
# This tells ArgoCD to use SSH for the repo
repositories: |
- url: git@gitea.mk-labs.cloud:rblundon/homelab.git
type: git
name: homelab
# Resource tracking via annotation (recommended over label tracking)
application.resourceTrackingMethod: annotation

View File

@@ -0,0 +1,11 @@
# ------------------------------------------------------------------------------
# ArgoCD Server Parameters
# Sets server.insecure=true so TLS is terminated at ingress, not argocd-server
# ------------------------------------------------------------------------------
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
namespace: argocd
data:
server.insecure: "true"

View File

@@ -0,0 +1,30 @@
# ------------------------------------------------------------------------------
# argocd-rbac-cm — RBAC Policy
#
# Maps Authentik groups to ArgoCD roles.
# Groups must exist in Authentik and be assigned to users there.
#
# Roles:
# role:admin — full access, all operations
# role:readonly — read-only, can view but not sync/modify
#
# Single-user homelab: your user should be in argocd-admins in Authentik.
# Add argocd-viewers later when you have guests/collaborators.
# ------------------------------------------------------------------------------
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
# Default policy for any authenticated user not in a mapped group
# readonly is safe — they can see but not touch
policy.default: role:readonly
policy.csv: |
# Authentik group → ArgoCD role mappings
g, argocd-admins, role:admin
g, argocd-viewers, role:readonly
# Tell ArgoCD which OIDC claims to use for group mapping
scopes: '[groups, email]'

View File

@@ -0,0 +1,41 @@
# ------------------------------------------------------------------------------
# Certificate — ArgoCD TLS
# Issued by cert-manager via letsencrypt-prod + Cloudflare DNS-01
#
# The secret produced (argocd-tls) is referenced by the Gateway listener
# in cluster/platform/gateway-api/gateway.yaml via ReferenceGrant.
#
# Per the thematic naming convention: argocd.local.mk-labs.cloud is the
# service DNS name. No VM hostname alias needed here.
# ------------------------------------------------------------------------------
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: argocd-tls
namespace: argocd
spec:
secretName: argocd-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- argocd.local.mk-labs.cloud
---
# ReferenceGrant — allows the Gateway in gateway-system to reference
# the TLS secret in the argocd namespace
# Without this, cross-namespace secret references are denied
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: argocd-tls-grant
namespace: argocd
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: gateway-system
to:
- group: ""
kind: Secret
name: argocd-tls

View File

@@ -0,0 +1,49 @@
# ------------------------------------------------------------------------------
# ExternalSecret — ArgoCD Secrets
#
# Pulls two secrets from 1Password:
# 1. Authentik OIDC client ID + secret (for Dex connector)
# 2. Gitea personal access token (for repo access)
#
# In 1Password (mk-labs vault), create:
# Item: "argocd-oidc"
# Field: client-id → Authentik OAuth2 client ID
# Field: client-secret → Authentik OAuth2 client secret
#
# Item: "gitea-argocd-token"
# Field: token → Gitea personal access token with repo read permissions
# (Create in Gitea: Settings → Applications → Generate Token)
#
# These materialize into argocd-secret, which ArgoCD reads natively.
# The $dex.authentik.clientID / $dex.authentik.clientSecret references
# in argocd-cm.yaml are resolved by ArgoCD from this secret automatically.
# ------------------------------------------------------------------------------
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: argocd-secrets
namespace: argocd
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword-connect
refreshInterval: "1h"
target:
# Must be named argocd-secret — ArgoCD reads this specific secret name
name: argocd-secret
creationPolicy: Merge # Merge into existing argocd-secret, don't replace it
data:
# Authentik OIDC credentials — referenced as $dex.authentik.* in argocd-cm
- secretKey: dex.authentik.clientID
remoteRef:
key: argocd-oidc
property: client-id
- secretKey: dex.authentik.clientSecret
remoteRef:
key: argocd-oidc
property: client-secret
# Gitea token — used by the Repository credential below
- secretKey: sshPrivateKey
remoteRef:
key: gitea-argocd-ssh
property: private-key

View File

@@ -0,0 +1,31 @@
# ------------------------------------------------------------------------------
# Ingress — ArgoCD via ingress-nginx
# Temporary until Cilium Gateway API is stable
# TLS terminated at ingress, argocd-server runs in insecure mode
# ------------------------------------------------------------------------------
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "false"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- argocd.local.mk-labs.cloud
secretName: argocd-tls
rules:
- host: argocd.local.mk-labs.cloud
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80

View File

@@ -0,0 +1,27 @@
# ------------------------------------------------------------------------------
# Repository Credential Secret — Gitea homelab repo
#
# ArgoCD discovers repository credentials via secrets with the label
# argocd.argoproj.io/secret-type: repository
#
# The actual token value is injected by the ExternalSecret (externalsecret.yaml)
# which merges into argocd-secret. This secret references that value.
#
# NOTE: The token field here uses a placeholder. The ExternalSecret populates
# argocd-secret with gitea.token, and ArgoCD resolves it via the
# stringData reference below.
# ------------------------------------------------------------------------------
apiVersion: v1
kind: Secret
metadata:
name: repo-homelab-gitea
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: git@gitea.mk-labs.cloud:rblundon/homelab.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
# populated by ESO
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,43 @@
# ------------------------------------------------------------------------------
# Platform: Cilium — Helm upgrade + LB IPAM + Gateway API
# Wave 4 — no dependencies, Cilium is pre-installed via Talos bootstrap
#
# This Application does two things:
# 1. Manages Cilium itself via Helm (enables Gateway API, keeps config in git)
# 2. Applies LB pool and L2 announcement manifests from repo
#
# IP Allocation:
# 10.1.71.80-.89 — ingress-nginx LB pool
# 10.1.71.90-.99 — Cilium Gateway LB pool
# ------------------------------------------------------------------------------
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cilium-config
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "4"
spec:
project: default
sources:
# Source 1: Cilium Helm chart — manages Cilium itself
- repoURL: https://helm.cilium.io
chart: cilium
targetRevision: 1.17.4
helm:
valueFiles:
- $values/cluster/platform/cilium-config/values.yaml
# Source 2: Repo — values ref + lb-pool.yaml + GatewayClass manifests
- repoURL: https://gitea.mk-labs.cloud/rblundon/homelab.git
targetRevision: main
path: cluster/platform/cilium-config/manifests
ref: values
destination:
server: https://kubernetes.default.svc
namespace: kube-system
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- ServerSideApply=true

View File

@@ -0,0 +1,41 @@
# Pool for ingress-nginx
apiVersion: cilium.io/v2
kind: CiliumLoadBalancerIPPool
metadata:
name: ingress-nginx-pool
namespace: kube-system
spec:
blocks:
- start: 10.1.71.80
stop: 10.1.71.89
serviceSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
---
# Pool for Cilium Gateway API
apiVersion: cilium.io/v2
kind: CiliumLoadBalancerIPPool
metadata:
name: cilium-gateway-pool
namespace: kube-system
spec:
blocks:
- start: 10.1.71.90
stop: 10.1.71.99
serviceSelector:
matchExpressions:
- key: io.cilium.gateway/owning-gateway
operator: Exists
---
# L2 Announcement Policy
apiVersion: cilium.io/v2alpha1
kind: CiliumL2AnnouncementPolicy
metadata:
name: fastpass-l2-policy
namespace: kube-system
spec:
loadBalancerIPs: true
interfaces:
- ^eth[0-9]+

View File

@@ -0,0 +1,41 @@
# ------------------------------------------------------------------------------
# Cilium Helm Values — fastpass cluster
# Chart: https://helm.cilium.io
# Version: 1.17.4
# ------------------------------------------------------------------------------
# Bootstrap values
kubeProxyReplacement: true
k8sServiceHost: 10.1.71.65
k8sServicePort: 6443
ipam:
mode: kubernetes
# Routing mode — replaces deprecated tunnel value
routingMode: tunnel
tunnelProtocol: vxlan
# L2 announcements
l2announcements:
enabled: true
k8sClientRateLimit:
qps: 20
burst: 40
externalIPs:
enabled: true
# Hubble observability
hubble:
enabled: true
relay:
enabled: true
ui:
enabled: true
# Prometheus metrics
prometheus:
enabled: true
serviceMonitor:
enabled: false

View File

@@ -0,0 +1,40 @@
# ------------------------------------------------------------------------------
# Platform: Gateway API CRDs
# Wave 3.5 — must exist before cilium-config (wave 4) enables gatewayAPI
#
# The Gateway API CRDs are maintained separately from any implementation.
# We install the standard channel CRDs from the upstream sig-network repo.
# Cilium requires these CRDs to exist before gatewayAPI.enabled=true works.
#
# Standard channel includes: GatewayClass, Gateway, HTTPRoute, GRPCRoute,
# ReferenceGrant
# Experimental channel adds: TCPRoute, TLSRoute, UDPRoute (added below)
# ------------------------------------------------------------------------------
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gateway-api-crds
namespace: argocd
annotations:
# Wave 3.5 — after cert-manager (3), before cilium-config (4)
# ArgoCD sync waves are integers, so we use 3 here and rely on
# sync ordering within the wave. Add a sync-wave of 3 to cert-manager
# and this will naturally sequence correctly.
argocd.argoproj.io/sync-wave: "3"
spec:
project: default
source:
repoURL: https://gitea.mk-labs.cloud/rblundon/homelab.git
targetRevision: main
path: cluster/platform/gateway-api/manifests
destination:
server: https://kubernetes.default.svc
namespace: gateway-api
syncPolicy:
automated:
prune: false # Never prune CRDs — too dangerous
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
- Replace=true # CRDs require Replace not Patch for updates

View File

@@ -0,0 +1,40 @@
# ------------------------------------------------------------------------------
# Gateway API CRDs — Standard + Experimental Channel
# Version: v1.2.1 (latest stable as of May 2026)
#
# We reference upstream CRD manifests directly. ArgoCD will apply them
# from the upstream GitHub URL via the source config in application.yaml.
#
# To upgrade Gateway API CRDs:
# 1. Update the version tag in the URLs below
# 2. Commit and push — ArgoCD applies automatically
#
# Standard channel CRDs (stable, production-ready):
# - GatewayClass
# - Gateway
# - HTTPRoute
# - GRPCRoute
# - ReferenceGrant
#
# Experimental channel additions (used for TCPRoute for non-HTTP services):
# - TLSRoute
# - TCPRoute
#
# Source: https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.2.1
# ------------------------------------------------------------------------------
# NOTE: ArgoCD applies these from the upstream URL. This file documents
# the versions in use. The actual application.yaml points ArgoCD at this
# directory, so place the CRD manifests here by running:
#
# curl -L https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml \
# -o cluster/platform/gateway-api/manifests/standard-install.yaml
#
# curl -L https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/experimental-install.yaml \
# -o cluster/platform/gateway-api/manifests/experimental-install.yaml
#
# Commit both files. ArgoCD will apply them on next sync.
#
# The commands above should be run from city-hall or your workstation
# and the resulting files committed to git. We vendor them rather than
# fetching at runtime so the exact CRD versions are pinned in git.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
# ------------------------------------------------------------------------------
# GatewayClass — tells Kubernetes that Cilium handles Gateway resources
# Defined here alongside the Gateway it enables
# ------------------------------------------------------------------------------
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: cilium
spec:
controllerName: io.cilium/gateway-controller
description: Cilium Gateway API implementation (eBPF-native)
---
# ------------------------------------------------------------------------------
# Gateway — fastpass-gateway
#
# This is the central Gateway that all HTTPRoute resources attach to.
# Cilium operator creates a LoadBalancer service for this Gateway automatically,
# which will receive an IP from the cilium-gateway-pool (10.1.71.90-.99).
#
# Usage: Applications create HTTPRoute resources that reference this Gateway:
#
# spec:
# parentRefs:
# - name: fastpass-gateway
# namespace: gateway-system
# ------------------------------------------------------------------------------
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: fastpass-gateway
namespace: gateway-system
annotations:
io.cilium/lb-ipam-ips: "10.1.71.90"
spec:
gatewayClassName: cilium
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- name: https
protocol: HTTPS
port: 443
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- name: argocd-tls
namespace: argocd

View File

@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: gateway-system
labels:
kubernetes.io/metadata.name: gateway-system

File diff suppressed because it is too large Load Diff