Local infrastructure based on Kubernetes (Kind), deployed via Terraform and managed according to GitOps principles using ArgoCD.
The project simulates a production-like environment with separation into environments (dev and prod), automatic synchronization of manifests from Git, traffic routing through Nginx Ingress, and metrics collection in Prometheus/Grafana.
graph TD
SubGraph1[Git Repository] -->|Pull Manifests| ArgoCD[ArgoCD Engine]
subgraph K8s Cluster - Kind
TF[Terraform] -->|Deploys Infrastructure| IngressController[Nginx]
TF -->|Deploys Infrastructure| ArgoCD
TF -->|Deploys Infrastructure| PromStack[kube-prometheus-stack]
ArgoCD -->|App of Apps| RootApp[Root Application]
RootApp -->|Deploys| DevApp[App Dev Namespace]
RootApp -->|Deploys| ProdApp[App Prod Namespace]
IngressController -->|demo-dev.local| DevApp
IngressController -->|demo-prod.local| ProdApp
end
Grafana[Grafana Dashboard] -->|Scrapes Metrics| PromStack
- Orchestration: Kubernetes (Kind)
- IaC: Terraform
- GitOps: ArgoCD
- Package Manager: Helm
- Ingress Controller: Nginx
- Observability: Prometheus + Grafana
.
├── argocd/
│ ├── apps/ # Manifests of child applications (dev / prod)
│ │ ├── dev-app.yaml
│ │ └── prod-app.yaml
│ └── root-app.yaml # Root manifest (App of Apps)
├── charts/
│ └── demo-app/ # Application Helm chart
│ ├── templates/
│ ├── values-dev.yaml
│ └── values-prod.yaml
├── terraform/ # IaC manifests for base infrastructure
│ ├── main.tf
│ ├── ingress.tf
│ ├── argocd.tf
│ └── monitoring.tf
├── kind-config.yaml # Local cluster config with port forwarding for 80/443
└── README.md
- Docker Desktop
- kubectl
- kind
- terraform (v1.0+)
- helm (v3+)
kind create cluster --name gitops-demo --config kind-config.yaml
kubectl label nodes gitops-demo-control-plane ingress-ready=truecd terraform
terraform init
terraform apply -auto-approve
cd ..Add the following entries to /etc/hosts to access the applications via a browser:
127.0.0.1 demo-dev.local demo-prod.local
Make sure that the files argocd/root-app.yaml and argocd/apps/*.yaml contain your GitHub repository URL, then apply the root application:
kubectl apply -f argocd/root-app.yaml| Service | Address / Access Command | Credentials |
|---|---|---|
| Dev Environment | http://demo-dev.local | — |
| Prod Environment | http://demo-prod.local | — |
| ArgoCD Web UI | kubectl port-forward svc/argocd-server -n argocd 8080:80 → http://localhost:8080 |
admin / (from secret argocd-initial-admin-secret) |
| Grafana Dashboards | kubectl port-forward svc/kube-prometheus-stack-grafana -n monitoring 3000:80 → http://localhost:3000 |
admin / admin123 |
- App of Apps Pattern: Adding new environments or services is done declaratively by adding manifests to the
argocd/apps/directory without manual intervention in the ArgoCD UI. - Self-Healing & Auto-Sync: Automatic synchronization and drift detection are enabled. When resources are manually changed in the cluster via kubectl, ArgoCD automatically brings the cluster state back to what is described in Git.
- Environment Isolation: Dev (2 replicas) and Prod (3 replicas) are deployed in isolated namespaces (
devandprod) using independent values files (values-dev.yaml,values-prod.yaml).