Skip to content

sarojnaik-cloudarchitect/enterprise-devsecops-platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

113 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Enterprise DevSecOps Platform

Production-grade DevSecOps platform on AWS EKS — security enforced automatically at every layer, from code commit to running container.


Platform Capabilities

Capability Tool Status
Container orchestration AWS EKS 1.34 ✅ Running
Infrastructure as Code Terraform — 4 modules ✅ Complete
GitOps delivery ArgoCD app-of-apps ✅ Deployed
Admission control Kyverno — 8 policies ✅ Enforcing
Security CI/CD Gitleaks, Bandit, Trivy, Checkov ✅ Live
Observability Prometheus + Grafana ✅ Deployed
AI security analysis Claude via AWS Bedrock ✅ Complete
Node autoscaling Karpenter 🔄 Phase 2
Secret management External Secrets + IRSA 🔄 Phase 2
Zero-trust networking Istio + Cilium 🔄 Phase 2

Architecture

Developer pushes code
↓
GitHub Actions CI Pipeline
├── Gitleaks     — secret scanning
├── Bandit       — Python SAST
├── Safety       — dependency CVE audit
├── Trivy        — container CVE scan
├── Checkov      — IaC security scan
└── Bedrock AI   — plain English security summary
↓
ArgoCD GitOps (pull-based deployment)
↓
EKS Cluster
├── Kyverno      — admission control (8 policies)
├── Prometheus   — metrics collection
├── Grafana      — dashboards and alerting
└── App Pods     — FastAPI with OTel instrumentation

---

Repository Structure

app/
├── main.py              FastAPI — OTel instrumented, 2 intentional security flaws
├── Dockerfile           --platform linux/amd64 explicit
└── requirements.txt
k8s/                     8 hardened Kubernetes manifests
├── deployment.yaml      securityContext, IRSA, anti-affinity, probes
├── networkpolicy.yaml   default-deny + TCP+UDP 53
├── hpa.yaml             2-10 replicas, CPU 70%, memory 80%
├── pdb.yaml             minAvailable: 1
├── resourcequota.yaml   namespace resource cap
└── limitrange.yaml      per-container defaults
terraform/
├── modules/
│   ├── vpc/             VPC, subnets, NAT gateway, flow logs
│   ├── eks/             EKS 1.34, KMS encryption, IMDSv2, OIDC
│   ├── ecr/             ECR, scan-on-push, lifecycle policy
│   └── iam/             GitHub OIDC, IRSA, Karpenter roles
└── environments/
├── dev/             t3.small, 2 nodes, ap-south-1
└── staging/
gitops/
├── argocd/apps/         app-of-apps + 5 ArgoCD applications
└── infrastructure/
├── kyverno/policies/ 8 ClusterPolicy admission rules
└── observability/    Prometheus, Grafana, OTel, Loki, Tempo
scripts/
└── ai-security-summary.py  Bedrock Claude security summariser
docs/
├── adr/                 5 Architecture Decision Records
├── architecture.md      Full platform design document
├── platform-roadmap.md  Production evolution roadmap
├── rebuild-runbook.md   Step-by-step rebuild guide
└── commands.md          All commands used with explanations
.github/workflows/
└── ci.yml               8-stage security pipeline

---

Security Pipeline — What It Scans

Job 1 — Security Scanning:
Gitleaks     secret detection across full git history
Bandit       Python SAST — SQL injection, hardcoded secrets
Safety       dependency CVE audit
Job 2 — Build, Scan and Push:
Trivy        container CVE scan (CRITICAL + HIGH)
Syft         SBOM generation (CycloneDX format)
tflint       Terraform linting
Checkov      IaC security — 40+ policy checks
Bedrock AI   Claude summarises all findings in plain English
Job 3 — Deploy (when DEPLOY_ENABLED=true):
kubectl apply    all 8 manifests
rollout status   verify deployment succeeded

Two intentional flaws in `app/main.py` prove the gates work:

```python
# Flaw 1 — caught by Gitleaks (hardcoded secret)
SECRET_API_KEY = "sk-prod-9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c"

# Flaw 2 — caught by Bandit B608 (SQL injection)
query = "SELECT * FROM users WHERE id = " + user_id

Download bandit-sast-report or ai-security-summary from any pipeline run to see real output.


## Kyverno Admission Policies

| Policy | Mode | Blocks |
|---|---|---|
| require-resource-limits | Enforce | Pods without CPU/memory limits |
| restrict-image-registries | Enforce | Non-ECR images |
| disallow-latest-tag | Enforce | :latest image tag |
| require-non-root | Enforce | Root containers |
| require-labels | Enforce | Missing app/version/managed-by |
| disallow-privileged | Enforce | Privileged containers |
| require-readonly-filesystem | Enforce | Writable root filesystem |
| require-pod-disruption-budget | Audit | Deployments with no PDB |

---

## Architecture Decisions

Five ADRs document the key decisions made during platform design:

| ADR | Decision | Why |
|---|---|---|
| [001](docs/adr/001-eks-over-ecs.md) | EKS over ECS | Cloud-agnostic, full CNCF ecosystem |
| [002](docs/adr/002-gitops-argocd-over-kubectl.md) | ArgoCD over kubectl | Drift detection, self-healing |
| [003](docs/adr/003-kyverno-over-opa-gatekeeper.md) | Kyverno over OPA | Developer experience, YAML policies |
| [004](docs/adr/004-karpenter-over-cluster-autoscaler.md) | Karpenter over CAS | 40-60% cost reduction |
| [005](docs/adr/005-irsa-over-instance-profile.md) | IRSA over instance profiles | Minimal blast radius |

---

## Screenshots

| What | Screenshot |
|---|---|
| Platform stack — all namespaces | [view](screenshots/01-platform-stack-overview-3.png) |
| EKS cluster | [view](screenshots/02-eks-cluster.png) |
| Node group | [view](screenshots/03-eks-nodegroup.png) |
| ECR repository | [view](screenshots/04-ecr-repo.png) |
| CI pipeline green | [view](screenshots/05-github-pipeline-blue.png) |
| App health endpoint | [view](screenshots/06-app-health.png) |
| App running in browser | [view](screenshots/07-app-browser.png) |
| FastAPI docs | [view](screenshots/08-app-docs.png) |
| Kyverno 8 policies | [view](screenshots/09-cluster-policy.png) |
| Nodes running | [view](screenshots/10-nodes.png) |
| Grafana node dashboard | [view](screenshots/11-grafana-dashboard-nodes.png) |
| Grafana namespace workloads | [view](screenshots/12-grafana-namespace-workloads.png) |
| Grafana login | [view](screenshots/13-grafana-loginpage.png) |
| Grafana metrics | [view](screenshots/23-grafana-metrics.png) |

---

## Rebuild From Scratch

```bash
# 1. Provision infrastructure (~12 minutes)
cd terraform
terraform init
terraform apply -auto-approve

# 2. Configure kubectl
aws eks update-kubeconfig \
  --name devsecops-cluster \
  --region ap-south-1

# 3. Build and push image
docker buildx build \
  --platform linux/amd64 \
  -t <AWS_ACCOUNT_ID>.dkr.ecr.ap-south-1.amazonaws.com/devsecops-app:v1.0.0 \
  --push ./app

# 4. Deploy application
kubectl apply -f k8s/

# 5. Install GitOps and policy engine
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
kubectl apply -f gitops/infrastructure/kyverno/policies/

# 6. Install observability
helm install prometheus prometheus-community/kube-prometheus-stack \
  -n observability --create-namespace \
  --set grafana.adminPassword=your-password

# 7. Verify everything
kubectl get pods -n devsecops
kubectl get pods -n argocd
kubectl get pods -n kyverno
kubectl get pods -n observability
kubectl get clusterpolicy

# 8. Destroy when done
terraform destroy -auto-approve

Full runbook: docs/rebuild-runbook.md All commands with explanations: docs/commands.md


Known Issues and Lessons Learned

Apple Silicon architecture mismatch Building without --platform linux/amd64 produces ARM images that cannot run on EKS x86 nodes. Always specify explicitly.

EKS KMS key and launch template conflict Custom KMS key on EBS volumes in launch template requires the node IAM role to have explicit KMS permissions. Fix: use AWS default EBS encryption key instead of custom KMS.

NetworkPolicy blocking DNS TCP-only port 53 egress breaks DNS — Kubernetes uses UDP by default. Fix: allow both TCP and UDP on port 53 in egress rules.

ECR token expiry ECR tokens expire after 12 hours. Fix: re-run aws ecr get-login-password before any push session.

t3.small memory pressure Running ArgoCD + Kyverno + Prometheus on t3.small causes OOM. Fix: use t3.medium for full observability stack deployment.


Production Roadmap

See docs/platform-roadmap.md for the full production evolution plan including:

  • External Secrets Operator — AWS Secrets Manager via IRSA
  • Karpenter — spot + on-demand autoscaling (~40% cost reduction)
  • Falco — runtime threat detection
  • Zero-trust networking — Istio mTLS + Cilium L7
  • Multi-environment promotion — dev → staging → prod via ArgoCD

Author

Saroj Naik — Principal Cloud Architect

20+ years experience in Cloud AI, Zero-Trust Architecture, Multi-Cloud Observability, Kubernetes, GitOps, and DevOps.