From Interview Task to Production: Building a Security-First DevSecOps Platform
TL;DR
The Assignment: Deploy a simple app to local Kubernetes
What I Built: A production-grade DevSecOps platform with 6-layer security scanning, FinOps cost tracking, GitOps automation, and complete observability
Result: "Opsfolio" - A hands-on demonstration of how I approach real-world infrastructure challenges
π View the complete repository
Table of Contents
- The Challenge
- The Approach
- Security Architecture
- FinOps: Cost Intelligence
- Automation & GitOps
- Technical Implementation
- Results & Metrics
- Key Takeaways
The Challenge
The interview assignment was straightforward:
- β Set up a local Kubernetes cluster (kind/minikube/k3s)
- β Create a Dockerfile
- β Deploy an application
- β Bonus: IaC, GitOps, semantic versioning
Simple enough. But I asked myself a different question:
"What would this look like if I built it for production?"
That question changed everything.
The Approach
Instead of building the minimum viable solution, I treated this like a real-world production system with:
- Security-first mindset: Multiple scanning layers, zero static credentials
- Cost awareness: FinOps integration for visibility before deployment
- Full automation: From commit to production with zero manual steps
- Observability: Complete monitoring and alerting stack
- Documentation: Enterprise-grade docs for every component
Security Architecture
π‘οΈ Multi-Layer Defense Strategy
Layer 1: CI/CD Security Pipeline (6 Scanners)
1. GitLeaks - Secret Detection
- name: GitLeaks Scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Scans entire Git history for exposed secrets (API keys, passwords, tokens).
2. SonarCloud - Static Application Security Testing (SAST)
Achieved: A Security Rating
Detects code vulnerabilities, security hotspots, code smells
3. Snyk Open Source - Software Composition Analysis (SCA)
Scans dependencies for known vulnerabilities
Severity threshold: CRITICAL
4. Snyk Code - SAST
Static code analysis for security issues
Severity threshold: HIGH
5. Trivy - Container Security
- name: Run Trivy scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'interview-app:latest'
severity: 'CRITICAL,HIGH'
exit-code: '1' # Blocks pipeline on findings
Shift-left approach: Scans images BEFORE pushing to registry
6. TFSec - Infrastructure as Code Security
Scans Terraform for misconfigurations
Posts findings directly to PRs
7. MegaLinter - Code Quality & Security
Multi-language linting
Auto-fixes via pull requests
Layer 2: Container Hardening
securityContext:
## Pod-level security
runAsNonRoot: true
runAsUser: 101
fsGroup: 101
containers:
- name: interview-app
securityContext:
# Container-level security
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL # Drop all Linux capabilities
resources:
# DoS prevention
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "100m"
Dockerfile Security :
# Minimal Alpine base
FROM nginx:1.29.3-alpine
# OS updates
RUN apk update && apk upgrade
# Non-root user
USER 101
# Non-privileged port
EXPOSE 8080
Layer 3: Network Security :
args:
- "http"
- "interview-app-service:8080"
- "--authtoken"
- "$(NGROK_AUTH_TOKEN)"
- "--auth"
- "myuser:mypassword" # Basic auth
- "--allow-cidr"
- "192.168.0.0/16" # IP allowlist
- "--deny-cidr"
- "5.142.0.0/16" # IP denylist
- "--rate-limit"
- "20:60s" # DDoS protection
Features:
- β TLS encryption (Ngrok)
- β HTTP Basic Authentication
- β IP-based access control (CIDR filtering)
- β Rate limiting (20 requests/60 seconds)
- β Traffic inspection UI
Layer 4: Secrets Management
Zero Static Credentials Strategy:
- AWS OIDC Authentication (No long-lived keys)
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- Bitnami SealedSecrets (Encryted at rest)
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: grafana-admin-secret
namespace: monitoring
spec:
encryptedData:
admin-user: AgBxgB9cmAMxkypRMT5b5N7T...
admin-password: AgB6DRmxAXK6Ot1c9Pn7XnZr...
- Terraform Cloud (Encrypted State Backend)
Results: 100% encrpyted secrets, zero plaintext anywhere.
FinOps: Cost Intelligence
π° Infracost Integration
The Problem : Teams deploy infrastructure, then get surprised by AWS bills.
The Solution : Cost visibility BEFORE deployment.
- name: Generate Infracost JSON
run: |
infracost breakdown \
--path . \
--format json \
--out-file infracost.json
- name: Post Infracost Comment on PR
uses: infracost/actions/comment@v1
with:
path: infracost.json
behavior: update
Example PR Comment:
π° Monthly Cost Estimate
| Resource | Monthly Cost | Change |
|----------|--------------|--------|
| aws_eks_cluster.main | $73.00 | +$73.00 |
| aws_eks_node_group (t3.small) | $15.00 | +$15.00 |
| aws_nat_gateway (x2) | $65.00 | +$65.00 |
| **Total** | **$153.00** | **+$153.00** |
π‘ Cost Optimization Opportunities:
- Use spot instances for node group (save ~70%)
- Single NAT gateway for non-production (save $32.50/mo)
Business Impact : Infrastructure decisions become data-driven, not guesswork.
Automation & GitOps
π Complete Release Automation
Semantic Release Configuration :
// .releaserc.js
module.exports = {
branches: ['main'],
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
['@semantic-release/changelog', {
changelogFile: 'CHANGELOG.md'
}],
['@semantic-release/exec', {
prepareCmd: 'echo ${nextRelease.version} > VERSION.txt'
}],
['@semantic-release/git', {
assets: ['CHANGELOG.md', 'VERSION.txt']
}],
'@semantic-release/github'
]
};
Commit Convention:
feat: add new feature # β Minor version bump (1.0.0 β 1.1.0)
fix: resolve bug # β Patch version bump (1.0.0 β 1.0.1)
BREAKING CHANGE: ... # β Major version bump (1.0.0 β 2.0.0)
Result : Automated versioning, changelog generation, and GitHub releases
ArgoCD GitOps
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: interview-app
namespace: argocd
spec:
syncPolicy:
automated:
prune: true # Remove deleted resources
selfHeal: true # Auto-correct drift
source:
repoURL: https://github.com/AkingbadeOmosebi/Opsfolio-Interview-App
path: k8s
targetRevision: HEAD
Features:
- β Continuous deployment from Git
- β Self-healing (automatic drift correction)
- β Image Updater with semver constraints
- β Complete audit trail
Technical Implementation
Dual Environment Strategy
Local Environment (K3s)
# Install K3s
curl -sfL https://get.k3s.io | sh -
# Deploy application
kubectl apply -f k8s/
# Deploy monitoring
kubectl apply -f k8s/monitoring/prometheus-app.yaml
Purpose : Cost-free validation and prototyping
Cloud Environment (AWS EKS)
Terraform Infrastructure:
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = "opsfolio-cluster"
cluster_version = "1.31"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
main = {
min_size = 1
max_size = 3
desired_size = 2
instance_types = ["t3.small"]
}
}
}
Security Features :
- Private VPC subnets for nodes
- IAM to Kubernetes RBAC mapping
- TFSec scanning before deployment
- OIDC authentication (no static keys)
Results & Metrics
π Measurable Outcomes
π Measurable Outcomes
| Metric | Result |
|---|---|
| SonarCloud Security Rating | A |
| Critical Vulnerabilities | 0 (Snyk + Trivy) |
| Secrets Encrypted | 100% |
| Static Credentials | 0 (Full OIDC) |
| CI/CD Security Scanners | 6 |
| Automated Releases | Yes (Semantic) |
| Cost Visibility | Pre-deployment |
Key Takeaways
What This Project Demonstrates
- Defense-in-Depth Security
- Not one tool, but 6 scanning layers
- Container hardening at multiple levels
- Network-level access controls
- Zero static credentials anywhere
- FinOps as Code
- Cost estimation before deployment
- Optimization recommendations in PRs
- Data-driven infrastructure decisions
- Complete Automation
- Semantic versioning
- Auto-generated changelogs
- GitOps continuous deployment
- Self-healing infrastructure
- Production Thinking
- Not "does it work?" but "is it production-ready?"
- Observability from day one
- Documented for team scalability
- Cost-conscious engineering
The Difference
Junior approach: Meet the requirements
Senior approach: Understand WHY production systems need security, observability, cost controls, and automationβthen implement them
This project is my answer to: "How do you build production-ready infrastructure?"
Explore the Repository
π GitHub Repository
What's Inside:
- Complete source code
- Architecture diagrams (visual + ASCII)
- Step-by-step implementation guides
- Component deep-dives
- CI/CD workflows
- Kubernetes manifests
- Terraform infrastructure code
Documentation:
- Architecture Overview
- Local Setup Guide
- Cloud Infrastructure Setup
- CI/CD Workflows
Let's Connect
Found this helpful? Questions about the implementation?
β Star the repo
π¬ Open an issue for questions
π Share with your network
What production practices do you prioritize in your infrastructure? Drop a comment below!

Top comments (0)