Skip to content

mmastersvz/gitops-k8s-platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gitops-k8s-platform

A production-style GitOps platform running on Kubernetes, demonstrating end-to-end automated delivery using ArgoCD, Helm, and GitHub Actions.

CI Release


What This Demonstrates

Skill Implementation
GitOps ArgoCD self-managed via App-of-Apps pattern; git is the single source of truth
Helm Wrapper charts for all platform components; app chart with ingress, probes, resource limits
ArgoCD Self-management, Application CRs, automated sync with prune/selfHeal, RBAC, GitHub OAuth via Dex
Secret Management Bitnami Sealed Secrets — encrypted at rest in git, decrypted only inside the cluster
TLS / DNS cert-manager with Let's Encrypt DNS-01 (Cloudflare); external-dns for automatic record creation
Ingress Traefik on k3d with TLS termination and cert-manager annotations
CI/CD GitHub Actions — build, Trivy scan, push to GHCR; blocked on CRITICAL/HIGH CVEs
Local Kubernetes k3d cluster with full production parity (Traefik on 80/443)
Release Management Semantic versioning with git-cliff for automated CHANGELOG generation

Architecture

flowchart LR
    dev([Developer]) -->|git push| gh[GitHub]

    subgraph CI ["GitHub Actions (CI)"]
        build[Build image] --> scan[Trivy scan\nCRITICAL/HIGH] --> push[Push to GHCR]
    end

    gh --> CI

    subgraph cluster ["Kubernetes (k3d / k3s)"]
        direction TB
        argocd[ArgoCD] -->|sync| sealed[Sealed Secrets]
        argocd -->|sync| cm[cert-manager]
        argocd -->|sync| edns[external-dns]
        argocd -->|sync| app[demo-app\nHelm chart]
        sealed -->|decrypt| secrets[(Secrets)]
        cm -->|DNS-01 via Cloudflare| tls[(TLS certs)]
        edns -->|A record| cf[Cloudflare DNS]
        traefik[Traefik Ingress] -->|routes| app
        traefik --- tls
    end

    gh -->|poll every 3m| argocd
    push -->|image tag| app
Loading

Repository Layout

.
├── app/                    # Python Flask demo application + Dockerfile
├── helm/
│   └── demo-app/           # Helm chart — Deployment, Service, Ingress
├── argocd/
│   ├── Makefile            # All cluster lifecycle and operational commands
│   ├── k3d-config.yaml     # Local cluster definition
│   └── charts/
│       ├── argocd/         # ArgoCD wrapper chart + all Application CRs (App-of-Apps)
│       ├── argocd-secrets/ # SealedSecrets for repo/Helm credentials and OAuth
│       ├── sealed-secrets/ # Bitnami sealed-secrets controller wrapper
│       ├── cert-manager/   # cert-manager wrapper + ClusterIssuers (Cloudflare DNS-01)
│       └── external-dns/   # external-dns wrapper (Cloudflare provider)
├── terraform/              # Infrastructure-as-code (in progress)
└── .github/workflows/
    ├── ci.yaml             # Build → Scan → Push
    ├── release.yml         # Semantic version tagging + GitHub Release
    └── update-changelog.yml# Auto-generate CHANGELOG.md on every merge

Quick Start (Local)

Requires: k3d, helm, kubectl, argocd, kubeseal

# 1. Create the cluster (Traefik on 80/443)
make -C argocd cluster-up

# 2. Install sealed-secrets controller (must precede ArgoCD)
make -C argocd sealed-secrets

# 3. Bootstrap ArgoCD (Applications disabled — avoids chicken-and-egg)
make -C argocd bootstrap

# 4. Add GitHub repo credentials (fine-grained PAT, read-only)
make -C argocd add-repo-secret GITHUB_USER=<user> GITHUB_PAT=<token>

# 5. Enable ArgoCD self-management (App-of-Apps takes over from here)
make -C argocd self-manage

ArgoCD UI: http://localhost:8080 (run make -C argocd port-forward in a separate terminal)

For full setup including Cloudflare TLS/DNS, see argocd/README.md.


CI/CD Pipeline

Every push to main that touches app/:

  1. Build — Docker image tagged with the commit SHA
  2. Scan — Trivy checks for CRITICAL and HIGH CVEs; build fails if any unfixed vulnerabilities are found
  3. Push — Image pushed to GHCR as both :latest and :<sha>

ArgoCD polls the repo every 3 minutes and syncs any drift automatically.


Key Design Decisions

App-of-Apps — A single ArgoCD Application points at argocd/charts/argocd, which renders all other Application CRs. Adding a new service means adding one YAML file; ArgoCD discovers and deploys it automatically.

Sealed Secrets over external secret stores — Secrets are encrypted with the cluster's public key and committed directly to git. No dependency on Vault or AWS SSM. The trade-off: secrets must be re-sealed after a cluster rebuild.

Bootstrap order — Sealed Secrets controller must exist before ArgoCD starts, because ArgoCD immediately tries to apply SealedSecret resources from git. The Makefile encodes this dependency explicitly.

values.local.yaml committed — Local overrides (single-node Redis, no Istio, admin login) are committed so ArgoCD can render them during self-managed sync. Cluster-only secrets (PATs, image pull secrets) are never committed.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors