A production-ready ASP.NET Core 8 REST API with MongoDB Atlas, demonstrating end-to-end DevOps practices β from code to cloud.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub (Source of Truth) β
β main branch βββ Production develop branch βββ Staging β
βββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β push / PR
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub Actions CI/CD Pipeline β
β Quality β Tests β Security Scan β Build β Sign β Deploy β
βββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β Helm upgrade
βΌ
ββββββββββββββββββββ AWS EKS Cluster βββββββββββββββββββββββββββββ
β ββββββββββββ ββββββββββββ ββββββββββββ β
β β Pod 1 β β Pod 2 β β Pod 3 β β HPA (2-10) β
β β API:8080 β β API:8080 β β API:8080 β β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ β
β βββββββββββββββ΄ββββββββββββββ β
β β β
β βββββββββ΄βββββββββ β
β β Nginx Ingress β β TLS termination β
β β + Rate Limit β β
β βββββββββ¬βββββββββ β
β β HTTPS β
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββ΄βββββββββββββ
β MongoDB Atlas β β Managed DB (M10+)
β (Multi-Region) β
ββββββββββββββββββββββ
Monitoring Stack (separate namespace):
Prometheus β Grafana β Alertmanager β Slack/PagerDuty
OTel Collector β Jaeger (traces)
Seq (structured logs)
| Category | Technology |
|---|---|
| Backend | ASP.NET Core 8, C# 12 |
| Database | MongoDB Atlas (cloud-managed) |
| Auth | JWT + Refresh Token rotation |
| Container | Docker (multi-stage, Alpine) |
| Orchestration | Kubernetes (EKS), Helm 3 |
| IaC | Terraform (AWS EKS, VPC, Secrets) |
| CI/CD | GitHub Actions |
| Registry | GitHub Container Registry (GHCR) |
| Monitoring | Prometheus + Grafana + Alertmanager |
| Tracing | OpenTelemetry + Jaeger |
| Logging | Serilog + Seq |
| Security | Trivy, CodeQL, Cosign (keyless) |
| Networking | Nginx + cert-manager (Let's Encrypt) |
| Testing | xUnit, Moq, FluentAssertions, Bogus |
taskmanager/
βββ .github/
β βββ workflows/
β β βββ ci-cd.yml # Main pipeline (testβbuildβdeploy)
β β βββ pr-validation.yml # PR checks (title, size, deps)
β β βββ security-scan.yml # Weekly CodeQL + Trivy scan
β βββ dependabot.yml # Automated dependency updates
β
βββ src/TaskManagerApp/
β βββ Controllers/ # API endpoints
β βββ Services/ # Business logic
β βββ Data/ # MongoDB context + indexes
β βββ Models/ # Domain entities
β βββ DTOs/ # Request/response + validators
β βββ Middleware/ # Error handling, security headers
β βββ Configuration/ # Settings classes
β βββ Program.cs # App bootstrap + DI
β
βββ tests/TaskManagerApp.Tests/ # xUnit + Moq + FluentAssertions
β
βββ infra/
β βββ terraform/ # AWS EKS + VPC + Secrets Manager
β βββ helm/taskmanager/ # Helm chart (deploy, HPA, PDB, etc.)
β
βββ k8s/base/ # Raw Kubernetes manifests
β
βββ monitoring/
β βββ prometheus/ # Scrape config + alerting rules
β βββ grafana/ # Dashboards + provisioning
β βββ alertmanager/ # Routing (Slack + PagerDuty)
β βββ otel-collector.yml # OTLP β Jaeger + Prometheus
β
βββ nginx/nginx.conf # Reverse proxy + rate limiting
βββ scripts/ # setup.sh, deploy.sh helpers
βββ Dockerfile # Multi-stage build
βββ docker-compose.yml # Full local dev stack
- Docker Desktop / Docker Engine 24+
- .NET 8 SDK
- MongoDB Atlas account (free M0 cluster works)
git clone https://github.com/yourusername/taskmanager.git
cd taskmanager
# Copy env template
cp .env.example .env
# Edit .env and add your MongoDB Atlas URI + JWT secret
nano .envchmod +x scripts/setup.sh
./scripts/setup.sh devThis will:
- Build the .NET application
- Run all tests
- Start the full Docker stack (API, Nginx, Prometheus, Grafana, Seq, Redis)
- Seed demo data
| Service | URL | Credentials |
|---|---|---|
| API | http://localhost:8080 | β |
| Swagger UI | http://localhost:8080/swagger | β |
| Grafana | http://localhost:3001 | admin / admin |
| Prometheus | http://localhost:9090 | β |
| Alertmanager | http://localhost:9093 | β |
| Seq Logs | http://localhost:5342 | β |
Admin: admin@taskmanager.com / Admin@1234!
User: demo@taskmanager.com / Demo@1234!
# Register
POST /api/auth/register
{
"email": "you@example.com",
"username": "yourname",
"password": "Strong@Pass1",
"firstName": "Your",
"lastName": "Name"
}
# Login
POST /api/auth/login
{ "email": "you@example.com", "password": "Strong@Pass1" }
# β { "accessToken": "...", "refreshToken": "...", "expiresAt": "..." }# Create task
POST /api/tasks
Authorization: Bearer <token>
{
"title": "Set up monitoring",
"priority": "High",
"dueDate": "2025-12-31T00:00:00Z",
"tags": ["devops", "monitoring"],
"estimatedHours": 4
}
# List tasks (paginated + filtered)
GET /api/tasks?page=1&pageSize=20&status=InProgress&priority=High
# Dashboard stats
GET /api/tasks/dashboardpush to develop/main
β
βββ Code Quality (format check, build, NuGet audit)
β
βββ Tests (xUnit + MongoDB service container + coverage gate 80%)
β
βββ Security Scan (Trivy CVE scan + Hadolint Dockerfile lint)
β
βββ Build & Push (multi-arch linux/amd64+arm64, GHCR)
β βββ Image signing (Cosign keyless OIDC)
β βββ SBOM generation (SPDX)
β
βββ Deploy Staging (develop branch)
β βββ Helm upgrade --atomic
β βββ kubectl rollout status
β βββ Smoke tests
β
βββ Deploy Production (main branch, after staging)
βββ Helm upgrade --atomic (zero-downtime rolling)
βββ kubectl rollout status
βββ Production smoke tests (3x retry)
βββ GitHub Release created
βββ Auto-rollback on failure
# AWS
AWS_ROLE_ARN_STAGING # OIDC role ARN for staging
AWS_ROLE_ARN_PROD # OIDC role ARN for production
AWS_REGION # e.g., us-east-1
# App secrets
MONGODB_URI_STAGING
MONGODB_URI_PROD
JWT_SECRET_STAGING
JWT_SECRET_PROD
# Notifications
SLACK_WEBHOOK_URL
PAGERDUTY_INTEGRATION_KEY # (optional)cd infra/terraform
# Initialize (S3 backend)
terraform init \
-backend-config="bucket=your-terraform-state-bucket" \
-backend-config="region=us-east-1"
# Plan
terraform plan \
-var="environment=production" \
-var="mongodb_uri=$MONGODB_URI" \
-out=tfplan
# Apply
terraform apply tfplanProvisions:
- VPC with public/private subnets across 3 AZs + NAT Gateways
- EKS Cluster (v1.31) with managed node groups (On-Demand + Spot)
- IRSA (IAM Roles for Service Accounts) β Secrets Manager access
- AWS Secrets Manager with KMS encryption for app secrets
- VPC Flow Logs to S3 (90-day retention, compliance)
Metrics (Prometheus + Grafana)
- HTTP request rate, error rate, p50/p95/p99 latency
- CPU/memory per pod, GC collections, thread pool
- Custom SLO dashboards with error budget burn rate
Traces (OpenTelemetry β Jaeger)
- Distributed tracing across HTTP requests
- Tail-based sampling: 100% errors, 10% success
- MongoDB query traces
Logs (Serilog β Seq)
- Structured JSON logs with correlation IDs
- Request/response logging (duration, status, user)
- 90-day TTL on audit logs via MongoDB TTL index
| Alert | Severity | Channel |
|---|---|---|
| API Down | Critical | PagerDuty + Slack |
| Error rate > 5% | Critical | Slack #alerts-critical |
| p95 latency > 1s | Warning | Slack #alerts-warnings |
| Pod crash-looping | Critical | PagerDuty + Slack |
| CPU > 85% | Warning | Slack |
| SLO error budget burning | Critical | Slack #slo-alerts |
- JWT authentication with refresh token rotation (7-day TTL)
- Account lockout after 5 failed login attempts (15min)
- bcrypt password hashing (work factor 12)
- Rate limiting β 100 req/min global, 10/15min for auth endpoints
- Security headers β HSTS, CSP, X-Frame-Options, etc.
- Container security β non-root user, read-only filesystem, no privilege escalation
- Kubernetes β NetworkPolicy, Pod Security Standards (restricted), RBAC
- Secrets β AWS Secrets Manager + KMS encryption (never in env files)
- Supply chain β Cosign keyless image signing + SBOM generation
- Dependencies β Dependabot weekly updates + Trivy/CodeQL scheduled scans
# Run all tests
dotnet test tests/TaskManagerApp.Tests/
# With coverage report
dotnet test tests/TaskManagerApp.Tests/ \
--collect:"XPlat Code Coverage" \
--results-directory coverage
# Generate HTML report
reportgenerator \
-reports:"coverage/**/coverage.cobertura.xml" \
-targetdir:"coverage-report" \
-reporttypes:HtmlCoverage target: 80% (enforced in CI via gate)
# Manual deploy (usually done by CI)
chmod +x scripts/deploy.sh
./scripts/deploy.sh 20241201-abc12345 production- Rolling update strategy (
maxSurge: 1, maxUnavailable: 0) - Pod Disruption Budget β minimum 1 pod always available
- preStop hook β 5s drain before SIGTERM
- gracefulTerminationPeriod β 30s for in-flight requests
- HPA β scales 2-10 pods on CPU/memory
# View logs
docker-compose logs -f api
# Restart API only
docker-compose restart api
# Update and redeploy locally
docker-compose pull && docker-compose up -d
# Check Kubernetes pod status
kubectl get pods -n taskmanager
kubectl describe pod <pod-name> -n taskmanager
kubectl logs <pod-name> -n taskmanager --follow
# Helm rollback (emergency)
helm rollback taskmanager --namespace taskmanagerMIT License β see LICENSE
Built as a DevOps showcase project demonstrating industry-standard practices. Covers: CI/CD, containerization, Kubernetes, IaC, monitoring, security, and testing.