Copied to clipboard
Main content
Johannesburg, ZA · GMT+2 7+ years

Hi, I'm Khwelisile Lukhuleni a Senior Platform Engineer

I architect, build and run enterprise-scale cloud platforms on AWS & Azure — Kubernetes, GitOps, Terraform, observability, and developer experience. I help teams ship faster, safer, and at lower cost.

0
Years building
0
Pipelines shipped
0
Enterprises
0
Uptime SLO
Khwelisile Lukhuleni
Khwelisile Lukhuleni
@platform-engineer
Online
platform.tf
# platform.tf
resource "aws_eks_cluster" "prod" {
  name     = "platform-prod"
  version  = "1.30"
  role_arn = aws_iam_role.eks.arn

  vpc_config {
    subnet_ids = module.vpc.private_subnets
  }
}
Kubernetes
GitOps
Observability
SCROLL
Companies I've engineered for
ShopriteX
Capitec Bank
Old Mutual
Symbiotics
01 · ABOUT

Engineering platforms that teams love.

I build secure, resilient, developer-first platforms — bridging DevOps, SRE and FinOps to turn cloud complexity into speed.

What I do

Architect & manage enterprise-scale cloud infrastructure for insurance, banking and retail. Kubernetes on AWS EKS, GitOps with ArgoCD, Terraform modules, and observability that actually pages the right human.

Kubernetes
EKS · Helm · ArgoCD
IaC
Terraform · CFN
CI/CD
Jenkins · GitLab · ADO
Observability
Prometheus · Grafana
0
Cloud-native by default. AWS & Azure across multi-region, multi-tenant footprints.

Zero-trust by design

AWS IAM, OIDC federation, least-privilege boundaries — security is the first PR, not the last.

Developer experience

Self-service namespaces, Helm templates, golden paths — devs deploy independently without paging me.

FinOps minded

Right-sized requests, smart HPA policies, and Cost Explorer insight — cloud spend aligned to workload, not vibes.

02 · EXPERIENCE

A journey through cloud & code.

From intern to senior platform engineer — building, breaking, learning across insurance, banking and retail.

2024.08 – Present Current

Senior Cloud Engineer

ShopriteX · South Africa
AWS EKS ArgoCD Terraform Airflow
  • Orchestrated end-to-end Kubernetes on AWS EKS with Helm + ArgoCD — automated rollbacks, consistent dev/qa/prod deploys.
  • Built observability with Prometheus, Grafana & Elastic — proactive incident response and reliable SLOs.
  • Authored reusable Terraform modules across teams, enforcing consistency, compliance and cost-effective scaling.
  • Built self-service developer platforms — namespace provisioning, Helm templating, ArgoCD sync workflows.
  • Orchestrated Airflow + KubernetesPodOperator pipelines for ETL, batch & infra maintenance.
  • Integrated Kubernetes workloads with Azure AD via OIDC for federated zero-trust auth.
  • Streamlined CI/CD with Azure DevOps Build & Release Pipelines for both containerized apps and serverless workloads.
  • Developed Python and Bash automation tooling that improved platform operations and developer productivity.
  • Collaborated cross-functionally with development, security and infrastructure teams to uphold platform compliance and performance.
  • Drove container-based Airflow data pipelines dynamically scheduled across Kubernetes clusters, reducing manual intervention.
  • Partnered with data engineers on Airflow-to-Kubernetes job migrations, improving cross-cloud workflow portability.
  • Built internal Python, Bash and PowerShell tooling to abstract Kubernetes complexity and enable self-service infra.
  • Optimized cloud spend by refining Kubernetes requests/limits, scaling HPA policies and using AWS Cost Management.
  • Integrated Airflow DAGs with Kubernetes to launch and monitor containers programmatically in EKS.
  • Advised application teams on cloud-native patterns, containerization best practices and zero-downtime rollouts.
2023.07 – 2024.07

Systems Engineer

Capitec Bank Limited
GitLab CI Rancher Kafka AWS Glue
  • Designed modular Terraform for VPCs, EC2, S3, security groups — versioned state with rollback strategy.
  • Built GitLab CI/CD pipelines deploying backend services into Kubernetes via Rancher.
  • Implemented Kafka producers/consumers for event-driven payments, transfers and account updates.
  • Designed AWS Glue jobs & Python scripts for ETL across S3 and downstream targets.
  • Integrated Terraform into CI/CD pipelines to automate infrastructure deployment and updates.
  • Managed Terraform state with versioning strategies to support reliable change tracking and rollbacks.
  • Streamlined containerized app deployments with Rancher, integrating monitoring for health and performance.
  • Used AWS ECR as the container and package registry for efficient Docker image management.
  • Established Kafka topics as durable queues guaranteeing the order and delivery of transactional messages.
  • Partnered with development & testing teams to design robust, scalable backend solutions.
  • Contributed to .NET, JS and AWS-based back-end services supporting microservice architectures.
2022.05 – 2023.06

Intermediate Software Engineer

Old Mutual
Jenkins AWS CodePipeline Fargate SonarQube
  • Automated CI/CD with Jenkins & CodePipeline; introduced blue-green deployments for safer rollouts.
  • Deployed HA stacks on AWS Fargate, ALB/NLB, EC2 autoscaling groups.
  • Migrated on-prem databases to AWS RDS and apps to AWS Managed Services.
  • Built monitoring with Grafana & Kibana; mentored engineers across React/Vue/Angular & C#/Node/Kotlin stacks.
  • Adopted Docker & Kubernetes for containerized workloads, improving scalability and resource efficiency.
  • Provisioned EC2 instances and networking primitives — load balancers, firewalls, routing.
  • Raised code-quality bar by integrating SonarQube and Nexus into the CI pipeline alongside unit tests.
  • Authored Bash scripts that automated web artifact builds for CI/CD.
  • Provisioned AWS resources via Terraform / CloudFormation as part of an Infrastructure-as-Code workflow.
  • Managed Kubernetes deployments using Docker images hosted as pods across environments.
  • Troubleshot complex production issues across system configuration and deployment layers.
  • Researched and designed new infrastructure and CI/CD processes; wrote operational documentation.
2020.08 – 2022.05

Analyst Programmer

Old Mutual
AWS Jenkins SOLID
  • Shipped APIs & web apps on AWS, deployed via Jenkins across multiple environments.
  • Wrote SOLID, maintainable backend code; partnered with clients on specs & system design.
  • Analysed user requirements and translated them into technical designs for business applications.
  • Researched, designed and developed new software for business workflows.
  • Provided sizing and scoping estimates for development work.
  • Authored operational documentation for deployed services.
2019.02 – 2020.07

GAP Trainee · Analyst Programmer

Old Mutual
  • Helped build Old Mutual's Broker Web and Quotes Web applications, including the underlying API services.
  • Unpacked business requirements alongside analysts to clarify technical scope.
  • Offered architectural design input during early-stage planning.
  • Participated actively in design sessions, contributing to solution shape.
  • Integrated existing systems so legacy and new platforms could work together cleanly.
2018.06 – 2018.07

Software Engineer Intern

Symbiotics
  • Built an AngularJS customer-project tracker on AWS.
03 · PROJECTS

Selected case studies.

A few platform problems I've solved end-to-end — from architecture to rollout to operating in production.

CASE STUDY · 01

Self-service Kubernetes platform on AWS EKS

Problem: Engineering teams blocked on infra tickets; inconsistent deploys across environments.

  • Reusable Terraform modules with policy guardrails baked in
  • GitOps via ArgoCD with automated rollbacks and drift detection
  • Internal CLI to provision namespaces, Helm releases & ArgoCD apps
Hrs → min
deploy time
8+ teams
self-service
Multi-env
dev · qa · prod
Architecture
dev teamPR + review CI buildtest · scan ECRimages ArgoCDapp-of-apps EKSdev · qaprod Terraform modulesversioned · pinned VPC · IAM · EKSguardrails baked in Prom + GrafanaSLOs · alerts
Decisions & tradeoffs
  • Flat, single-concern Terraform modules composed per environment — no mega-module. State split by env and service boundary so plans stay fast and lock contention stays rare.
  • Every module dependency pinned to exact versions; upgrades roll dev → qa → prod behind automated plan checks, never straight to prod.
  • ArgoCD app-of-apps with sync waves: CRDs first, platform services next, workloads last — no more race-condition installs.
  • One golden-path Helm chart: teams override ~10 values, the paved defaults handle probes, resources, HPA and network policy.

Outcome: onboarding a new service went from a multi-day ticket queue to a same-day pull request. 8+ teams deploy independently and infra changes get reviewed by both the owning team and platform.

AWS EKS ArgoCD Helm Terraform Python
CASE STUDY · 02

Zero-trust workload identity across AWS & Azure

Problem: Static cloud credentials scattered across CI pipelines and workloads — over-privileged, rarely rotated, impossible to audit.

  • IRSA: every pod assumes its own scoped IAM role via the EKS OIDC provider
  • CI pipelines federate with short-lived OIDC tokens — no stored cloud keys
  • Internal apps authenticate through Azure AD OIDC, enforced at the ingress
0 secrets
stored in CI
Short-lived
15-min creds
Least-priv
role per workload
Architecture
CI pipelineOIDC id token EKS pod + SAIRSA IAM OIDC trustaud + sub claimspinned per role STS15-min credsscoped role AWSleast privilege Azure ADOIDC · internal apps ingress authno app passwords CloudTrailevery role use
Decisions & tradeoffs
  • IRSA gives each workload its own IAM role through the cluster's OIDC provider — pod-level least privilege instead of one fat node role shared by everything on the box.
  • CI jobs exchange their pipeline's OIDC token for 15-minute STS credentials; trust policies pin the audience and repo/branch claims, so main can deploy prod and a fork can't.
  • Internal apps delegate login to Azure AD at the ingress — services never handle passwords, and joiner/leaver access reviews happen in one directory instead of per app.
  • The honest tradeoff: federation adds moving parts — issuers, thumbprints, clock skew. Worth it, because leaked credentials stopped being an incident class at all.

Outcome: long-lived access keys were eliminated from CI and workloads. A leaked laptop credential can no longer reach production, and "who touched prod?" went from spreadsheet archaeology to a single CloudTrail query — every AssumeRole carries the workload's identity.

AWS IAM OIDC EKS IRSA Azure AD STS
CASE STUDY · 03

Event-driven banking transactions with Kafka

Problem: Synchronous APIs straining under peak transaction load; ordering guarantees missing.

  • Kafka producers / consumers for payments, transfers and account updates
  • Partitioned topics guaranteeing ordered, durable transaction delivery
  • GitLab CI deploying consumers into Kubernetes via Rancher
Async
decoupled
In-order
per account
Replayable
DLQ + tooling
Architecture
payments svc transfers svc Kafka topicskeyed by accountordered partitions consumersidempotentK8s via Rancher ledgercore bank DLQ + replaypoison messages lag monitoringalerts on growth
Decisions & tradeoffs
  • Partition keys are account IDs — per-account ordering is guaranteed where it matters, without paying the throughput cost of global ordering.
  • Idempotent consumers plus transactional producers give effectively-once processing — the honest version of "exactly-once", and the one that survives an audit.
  • Poison messages route to dead-letter topics with replay tooling, so a single bad event never blocks an account's stream.
  • Consumer lag is a first-class SLI: alerts fire on lag growth rate, catching slow consumers long before customers notice.

Outcome: peak transaction bursts are absorbed asynchronously instead of timing out synchronous APIs, and event replay turned incident recovery from data-fixing scripts into a routine operation.

Kafka AWS Rancher GitLab CI Terraform
CASE STUDY · 04

Zero-downtime blue-green deployments on AWS

Problem: Deploy windows causing customer-facing outages; manual rollbacks under pressure.

  • Blue-green pipeline on AWS CodePipeline with automatic traffic shift
  • Highly-available stack on Fargate behind ALB/NLB with autoscaling
  • SonarQube + Nexus quality gates blocking risky merges
Zero
downtime
1-click
rollback
Auto-heal
on failure
Architecture
CodePipelinebuild · test quality gateSonar · Nexus green (new) blue (current) ALBshift users health checkssynthetic + CloudWatch auto-rollbackrepoint ALB
Decisions & tradeoffs
  • The green stack takes synthetic traffic and must pass health checks before a single real request moves — the shift is health-gated, not time-gated.
  • Rollback is repointing the load balancer, not redeploying — recovery is measured in seconds, and it's the same tested path every time.
  • Running two stacks costs double for the deploy window; that's the deliberate price of never taking a customer-facing outage on release.
  • SonarQube and Nexus gates block risky merges upstream, so the deploy pipeline defends prod instead of discovering problems there.

Outcome: deploy windows and change freezes were eliminated — releases ship during business hours, and rollback under pressure became a one-click, well-rehearsed motion.

Jenkins CodePipeline Fargate SonarQube Terraform
CASE STUDY · 05

FinOps: right-sizing an EKS estate without slowing teams down

Problem: Cloud spend growing faster than traffic — requests set by copy-paste, clusters sized for peak and idle most of the day.

  • Requests & limits derived from real Prometheus usage percentiles, not guesses
  • HPA tuned per service; burst node groups scale to zero off-peak
  • Cost Explorer + allocation tags: spend attributed to every team and service
p95-based
requests & limits
Scale-to-0
off-peak capacity
Per-team
showback
Architecture
Prometheus30-day p95 usage right-sizing PRsinto team Helm values EKS workloadsHPA tunedburst pools → zero allocation tagsteam · service · env Cost Explorerspend vs workload team showbackGrafana per service
Decisions & tradeoffs
  • Requests come from observed p95 over 30 days, delivered as pull requests into the owning team's Helm values — robots suggest, humans review, nothing changes silently.
  • Headroom is explicit: limits are sized for real burst, not fear. CPU-throttling alerts catch the ones we got wrong before users do.
  • Batch and bursty workloads moved to dedicated node groups that scale to zero; the stateless tier rides cheaper capacity while the base stays on-demand.
  • Showback before chargeback: every team sees its own spend per service in Grafana first. Visibility changed behavior without a single mandate — the cheapest governance there is.

Outcome: cluster utilization climbed while the bill flattened — spend now tracks workload demand instead of peak-day fear. Cost conversations moved out of finance escalations and into sprint planning, where they're cheap.

Cost Explorer Prometheus HPA EKS Helm
CASE STUDY · 06 — META

How this site ships

Premise: a platform engineer's portfolio should be held to platform standards. This page is a static artifact with a real build pipeline, a strict security posture, and its own observability — treat it as a tiny production system.

0 CDNs
on first paint
0 trackers
no analytics
Offline-ready
service worker
Lighthouse (mobile, throttled): 96 perf · 100 a11y · 100 best-practices · SEO checks passing — audited Jul 2026
Pipeline
git pushmain Tailwind buildminified CSS assemble _sitestamp sitemap deploystatic host you CSP: default-src 'self' · HSTS · X-Frame-Options: DENY · SW cacheruntime guarantees enforced in the browser
  • Every font, icon and library is self-hosted — the CSP is effectively default-src 'self', with a single scoped exception for the booking widget, loaded only on demand.
  • Security headers shipped from the edge: HSTS with preload, frame-ancestors 'none', nosniff, a locked-down Permissions-Policy.
  • A service worker precaches the shell and serves stale-while-revalidate — the site works offline and repeat visits render from cache.
  • No analytics, no tracking pixels, no consent banner needed — the only telemetry is the live panel in the footer, computed in your browser and never sent anywhere.
  • Animations respect prefers-reduced-motion, the theme respects your OS, and everything works without JavaScript except the toys.
  • Immutable cache headers on hashed assets; HTML revalidates every five minutes — the classic static-site cache split.
Tailwind Node build CSP Service Worker Zero CDN
04 · STACK

Tools of the trade.

A working library of cloud, container, IaC, observability and language tools I use day-to-day.

Cloud & Infrastructure

Where I provision, network and pay the bills.

AWS
Azure
Terraform
CloudFormation
Networking

Containers & Orchestration

How I run workloads at scale.

Docker
Kubernetes
Helm
ArgoCD
Rancher

CI/CD & GitOps

Commits to production, hands-off.

Jenkins
GitLab CI
Azure DevOps
GH Actions
CodePipeline

Observability & Data

How I keep prod boring.

Prometheus
Grafana
Kafka
Airflow
Snowflake
Elastic

Languages & Backend

What I reach for to glue platforms together.

Python
Bash
PowerShell
.NET / C#
Node.js
TypeScript
JavaScript

Frontend & Ways of Working

How I ship — and how I work with humans.

React
Angular
Vue.js
Redux
Agile · Scrum
khwelisile@platform · ~/platform-prod

          
05 · WRITING

Notes from production.

Things I learned the hard way, written down so you don't have to. Field notes, not thought leadership.

Terraform modules that survive their second team

8 min read · IaC

A module that works for one team is easy. A module that works for eight teams — without a platform engineer in every review — is a design problem. Here's the structure that held up.

The mega-module trap

The first version of our platform modules did too much. One eks-platform module created the cluster, node groups, IAM roles, the VPC endpoints, and half the observability stack. It felt productive — one module block and you had a platform. Then the second team needed a slightly different node group topology, and the third team needed the cluster without the VPC endpoints, and every "small" option became another variable. Within six months the module had 70+ inputs and nobody could predict what a change would do.

The fix was boring and it worked: flat modules, one concern each, composed at the environment level. The networking module doesn't know compute exists. The cluster module takes subnet IDs as inputs; it never looks them up itself. Composition happens in a thin per-environment root that reads like a manifest:

module "network"  { source = "…//vpc"        version = "2.4.1" … }
module "cluster"  { source = "…//eks"        version = "3.1.0"
  subnet_ids = module.network.private_subnets }
module "o11y"     { source = "…//monitoring" version = "1.9.2" … }

State is a blast radius, not a database

Our second hard lesson: one state file per environment sounds tidy until terraform plan takes eleven minutes and two teams hit lock contention every afternoon. We split state along service boundaries within each environment — network, cluster, shared services, then one workspace per team's infrastructure. Plans dropped back under a minute, and more importantly, the blast radius of a bad apply shrank to the boundary of one state file.

Version pins are a feature, not paranoia

Every module reference is pinned to an exact version. Upgrades are pull requests that roll dev → qa → prod, with the plan output posted into the PR by CI. Two reviewers: someone from the consuming team, someone from platform. The team validates intent; platform validates that the change won't create a cascading failure. It sounds heavyweight — in practice it takes minutes, because the modules are small enough that diffs are readable.

What I'd tell you to steal

  • One concern per module. If the name needs an "and", split it.
  • Compose at the root, pass IDs explicitly — no data-source archaeology inside modules.
  • Split state by environment and service boundary before plans get slow, not after.
  • Exact version pins everywhere, upgrades as reviewed PRs with plan output attached.
  • Ship a module template repo — the fastest way to keep standards is to make the right way the lazy way.

Airflow on EKS: what KubernetesPodOperator actually buys you

7 min read · Data platform

Everyone quotes "isolation" as the reason to run Airflow tasks as pods. The real wins are quieter: dependency freedom, honest resource accounting, and failure modes you can reason about.

The problem with workers

Classic Airflow puts your task code and the scheduler in the same Python environment. The first time a data team needs pandas 2.x while another DAG pins 1.5, you're in dependency hell — and upgrading Airflow itself becomes a cross-team negotiation. We moved every task to KubernetesPodOperator: each task is a container image the owning team builds, and Airflow's environment contains Airflow and nothing else.

That one decision decoupled three lifecycles that had been tangled together: the scheduler's upgrade cadence, each pipeline's dependency set, and the platform's node capacity. Teams ship task images through the same CI as their services. Airflow upgrades stopped being scary.

Self-healing is configuration, not magic

The reliability wins came from three settings applied ruthlessly:

  • Retries with backoff on every task. Transient EKS scheduling hiccups and spot interruptions stopped paging anyone — they retry and pass.
  • Execution timeouts on every task. A hung pod is worse than a failed one; timeouts turn "silently stuck since 3am" into a clean failure with a page.
  • Pools around shared backends. One team's 400-task backfill used to brown-out the warehouse for everyone. Pools cap concurrent connections per resource, so a backfill is a queue, not an incident.

Pay for what runs, not what waits

With per-task resource requests, heavy transforms schedule onto a dedicated node group with cluster-autoscaler behind it. When the DAG finishes, the nodes drain and disappear. Our old static worker fleet was sized for the nightly peak and idle 80% of the day — the pod model cut that waste out entirely, and Cost Explorer finally attributed spend to the team whose image was running.

The observability contract

Every DAG exports success/duration metrics to Prometheus, and each pipeline has an SLO. The routing rule that made this sustainable: a missed SLO pages the pipeline's owning team, not the platform on-call — with the run ID, task logs and the Grafana panel in the alert. The platform team gets paged when the scheduler or the cluster is unhealthy. Ownership boundaries in the alerting config are what keep a shared Airflow from becoming a shared burden.

SLOs that page the person who can fix it

8 min read · Observability

We had hundreds of alerts and no idea if users were happy. Building an SLO platform on Prometheus and Grafana fixed both — mostly by deleting alerts and being ruthless about ownership.

CPU alerts are a lie detector that always lies

The alert estate I inherited was classic: CPU over 80%, memory over 90%, disk over 85% — per node, per service, per environment. Pager volume was high, and none of it answered the only question that matters: are users having a bad time right now? A service can run hot and be perfectly healthy; it can idle at 20% CPU while every request times out on a dead dependency. Resource alerts measure the machine's comfort, not the user's experience.

So the platform's rule became: page on symptoms, graph the causes. The only thing that wakes a human is a service-level indicator moving toward breaching its objective. CPU, memory and saturation still exist — as dashboard context for the person already awake.

Two SLIs cover almost everything

For each service we define exactly two SLIs at the edge that matters (the ingress, the topic, the DAG): availability — the fraction of requests that succeed — and latency — the fraction served faster than the threshold users notice. Each gets an objective agreed with the owning team, and the gap between objective and reality is the error budget. That's it. Teams that wanted ten bespoke SLIs got talked down to two; the discipline is the feature.

Burn rate, not thresholds

A static "error rate > 1%" alert has two failure modes: it pages at 3am for a blip that self-heals, and it stays silent while a slow leak quietly spends a month of budget. Multi-window burn-rate alerts fix both:

# page: burning 5% of monthly budget in an hour
(burn_rate_5m > 14.4 and burn_rate_1h > 14.4)
# ticket: slow leak, look tomorrow
(burn_rate_6h > 1 and burn_rate_3d > 1)

Fast burn pages a human immediately; slow burn opens a ticket. The 5m/1h pairing stops flapping — both windows must agree before anyone's phone makes a sound.

The routing rule that made it stick

Every ServiceMonitor carries a team label, and Alertmanager routes on it: an SLO burn pages the service's owning team; the platform team is paged only when the platform itself is the problem — cluster, ingress, Prometheus, the pipeline. The alert body carries the Grafana panel, the runbook link and the current budget remaining, because an alert without context is just anxiety with a timestamp.

Dashboards as code, or they rot

Every service gets one provisioned golden dashboard — SLI trend, budget remaining, saturation, dependencies — generated from the same Git repo that defines the SLOs. Hand-edited dashboards drift, multiply and lie; provisioned ones stay honest because a PR is the only way to change them.

What actually changed

  • Pager volume dropped hard once symptom-based paging replaced threshold noise — most old alerts became dashboard panels or got deleted.
  • Time-to-fix dropped because the page arrives with the graph, the runbook and the budget math already attached.
  • Error budgets turned reliability arguments into arithmetic: burn the budget, spend the sprint on stability; keep it, ship features. Nobody has to win a meeting.

Postmortem: the rollout that paged everyone (sanitized)

6 min read · Incident

A deployment that passed every check took down internal services for 40 minutes. The failure wasn't in the code — it was in what our checks didn't look at. Written up in the same format we use internally.

Summary

A routine Helm release bumped a shared ingress controller. The new version changed a default: connection draining dropped from 300s to 30s. Rollout health checks passed — new pods were Ready, endpoints healthy. But long-lived internal gRPC connections were severed mid-stream across every namespace behind that ingress. Downstream services saw connection resets, retried aggressively, and the retry storm pushed p99 latency past timeout budgets. Impact: ~40 minutes of degraded internal APIs. No customer data affected.

Timeline (condensed)

  • 14:02 — ArgoCD syncs the ingress chart bump. Rollout completes green.
  • 14:04 — First alerts: gRPC error-rate SLO burn on two services. On-call assumes app issue.
  • 14:11 — Three more teams paged. Pattern recognized: every affected service shares the ingress.
  • 14:19 — Rollback initiated via ArgoCD history. Drain settings restored.
  • 14:42 — Error rates back within SLO. Incident closed.

What actually failed

Not the ingress controller — it did exactly what its new defaults said. What failed was our model of "safe change": rollout checks validated that the new pods were healthy, but nothing validated the behavior of existing traffic during the transition. Readiness is a statement about the future; draining is a statement about the present. We were only testing one of them.

What changed afterwards

  • Upgrade diffs for shared infrastructure now include a rendered-defaults diffhelm template old vs new, so changed defaults show up in review even when our values file doesn't change.
  • Shared components roll through a canary ingress class first, with synthetic long-lived connections attached — the exact failure mode this incident would have caught.
  • Alert routing got a "shared infra" correlation rule: three teams paging on the same dependency escalates to platform immediately, instead of three parallel investigations.
  • Blameless review, as always. The engineer who shipped the bump also wrote the canary tooling — that's how you keep people shipping.

The lesson I keep re-learning

Green checks mean your change passed the tests you thought to write. The riskiest changes are the ones that alter behavior you never encoded as a test — and shared-infrastructure defaults are exactly where those live.

06 · EDUCATION

Credentials & continuous learning.

A foundation in computer science, sharpened with industry certifications.

2015 – 2018

BSc Information Technology

North-West University · South Africa

2022 – 2023

AWS Certified Cloud Practitioner

Amazon Web Services

2020

Agile Project Management Foundation

APMG International

2019

AWS Intermediate Solutions Architecture

Zensar Technologies · Pune, India

07 · CONTACT

Let's build something that scales.

I'm open to Senior Platform, Cloud, DevOps, Engineering and SRE roles, contracting and advisory work. Drop a note — I usually reply within 24 hours.

Download CV WhatsApp +27 74 966 7831 LinkedIn
Johannesburg, South Africa · 2188