RSSAmplifier

Blog

Andrew Odendaal

Hands-on technical guides on AWS, Kubernetes, Terraform, Rust, Python & Go by Andrew Odendaal — cloud architecture and DevOps notes from production, since 2007.

andrewodendaal.comRSS feed ↗50 posts

Latest posts

Programming Puzzle Solutions: JS, Java, Python, Go

This is the index for the four programming puzzle problems on this site. Each one has language-specific solutions in JavaScript, Java, Python, or Go — pick the variant that matches what you’re working in. Every solution is tested, runs in linear time, and includes the trade-off between the idiomatic approach and the manual one. Find the number with the most digits Given an array of positive…

Karpenter v1 vs Cluster Autoscaler: A Production Migration Story

I’d been running Cluster Autoscaler on our production EKS cluster for years. It worked. It wasn’t exciting, it wasn’t cheap, but it worked. Then in early 2025 Karpenter hit v1 and the API stopped breaking every release, and I finally ran out of excuses. This is the story of that migration — what I learned, what I’d do differently, and why I think Karpenter has effectively…

Longest Alphabetical Substring (JS)

The challenge Find the longest substring of a string where characters appear in non-decreasing alphabetical order . If two substrings share the maximum length, return the first one. Example: the longest alphabetical substring in "asdfaaaabbbbcttavvfffffdf" is "aaaabbbbctt" (length 11). Inputs can reach 10,000 characters, so the solution must be O(n). Solution 1: index tracking (fastest, O(1)…

Longest Alphabetical Substring in Java

The challenge Find the longest substring of a string where characters are in non-decreasing alphabetical order . If multiple substrings share the maximum length, return the first one. Example: the longest alphabetical substring in "asdfaaaabbbbcttavvfffffdf" is "aaaabbbbctt" (length 11). Inputs can be up to 10,000 characters, so the solution must be O(n). Solution 1: index tracking (fastest, O(1)…

Longest Vowel Substring in JS

The challenge Given a lowercase string of letters (no spaces, no digits), return the length of the longest substring made only of vowels ( aeiou ). Examples: solve ( 'codewarriors' ); // → 2 (the 'io' in warriors) solve ( 'suoidea' ); // → 3 (the 'uoi') solve ( 'aeioaexaeuoiou' ); // → 7 (the 'aeuoiou') solve ( 'bcd' ); // → 0 solve ( 'a' ); // → 1 The Codewars Kata in the JavaScript track uses…

Longest Vowel Substring in Python

The challenge Given a lowercase string of letters (no spaces, no digits), return the length of the longest substring that contains only vowels ( aeiou ). Examples: solve( 'codewarriors' ) # → 2 (the 'io' in warriors) solve( 'suoidea' ) # → 3 (the 'uoi') solve( 'aeioaexaeuoiou' ) # → 5 (the 'aeioa' or 'uoiou') solve( 'bcd' ) # → 0 solve( 'a' ) # → 1 The puzzle appears in Codewars in both Python and…

Permutations Alphabetically in JS

The challenge Given a lowercase word, return every permutation of its letters in alphabetical order. Do not use built-in permutation libraries. Examples: permutations ( 'the' ); // → ['eht', 'eth', 'het', 'hte', 'teh', 'the'] permutations ( 'a' ); // → ['a'] This is a Codewars classic in the JavaScript track. The two stumbling blocks are generating the permutations from scratch and producing them…

Permutations Alphabetically (Java)

The challenge Given a word (a string of lowercase letters), return all its permutations in alphabetical order. Do not use built-in permutation functions. Examples: permutations( 'the' ); // → [eht, eth, het, hte, teh, the] permutations( 'a' ); // → [a] This puzzle is asked on Codewars and HackerRank Java tracks. Two parts trip people up: generating the permutations from scratch, and ordering them…

Find Number With Most Digits in Go

The challenge Given a slice of positive integers, return the value with the most digits. If two or more values share the highest digit count, return the first one in the slice. Examples: findLongest ([] int { 1 , 10 , 100 }) // → 100 findLongest ([] int { 9000 , 8 , 800 }) // → 9000 findLongest ([] int { 8 , 900 , 500 }) // → 900 This Codewars-style puzzle is asked in Go interviews and screens for…

Find Number With Most Digits in Java

The challenge Given an array of positive integers, return the number with the most digits. If two or more numbers share the highest digit count, return the first one that appears in the array. Examples: findLongest( new int [] {1, 10, 100}); // → 100 findLongest( new int [] {9000, 8, 800}); // → 9000 findLongest( new int [] {8, 900, 500}); // → 900 This puzzle appears on Codewars and HackerRank in…

Find Number With Most Digits in JS

The challenge Given an array of positive integers, return the number with the most digits. If two numbers have the same number of digits, return the first one in the array. Examples: findLongest ([ 1 , 10 , 100 ]); // → 100 findLongest ([ 9000 , 8 , 800 ]); // → 9000 findLongest ([ 8 , 900 , 500 ]); // → 900 This puzzle is asked in JavaScript-flavoured Codewars, HackerRank, and front-end…

AWS Organizations and Control Tower: Multi-Account Strategy

Single-account AWS is a ticking time bomb. I don’t say that lightly. I’ve watched it blow up firsthand, and I’ve spent more hours than I’d like to admit cleaning up the aftermath. If you’re running anything beyond a personal side project in a single AWS account, you’re playing a game you will eventually lose. This is the guide I wish I’d had years ago.…

Kubernetes eBPF: Next-Generation Observability and Security

eBPF is the biggest shift in Linux observability since strace. I don’t say that lightly. I’ve spent years wiring up monitoring stacks, bolting sidecars onto every pod, and watching resource requests balloon because each workload needed its own little proxy just to get visibility into what was happening on the network. eBPF changes the game entirely — it moves instrumentation into the…

DevSecOps Pipeline: Integrating Security into Every Stage

Security as a gate at the end of the pipeline is security theater. I’ve believed this for years, but it took watching a real incident unfold to make me truly militant about it. If your security checks only run after code is merged, packaged, and ready to ship, you’re not doing security — you’re doing compliance paperwork. I’ve spent the last few years building DevSecOps…

Rust Async Runtime Deep Dive: Tokio Architecture

Tokio is Rust’s killer app for network services. I don’t say that lightly. After spending years building concurrent systems in Go and other languages, Tokio changed how I think about async I/O. It’s not just a library — it’s a full runtime that turns Rust’s zero-cost futures into something you can actually build production services with. I’ve been running Tokio…

Chaos Engineering on AWS: Fault Injection Simulator Guide

You don’t know your system is resilient until you’ve broken it on purpose. I believed our payment processing service was fault tolerant. We ran multi-AZ. We had health checks. We had auto scaling. We had all the boxes ticked on the Well-Architected review. Then us-east-1b had a networking event on a Tuesday afternoon, and we watched a service that was supposed to gracefully fail over…

Python Data Pipelines with Polars and DuckDB

I’m going to say something that’ll upset a lot of people: pandas had its run. Polars is just better. I don’t mean that lightly. I spent years writing pandas code. I taught pandas to junior developers. I built production systems on pandas. But after migrating several data pipelines to Polars and DuckDB over the past year, I can’t go back. The performance difference…

Why I Built Wyn: A Programming Language That Compiles to C

I’ve spent years writing Python for DevOps tooling and Go for services. Python is a joy to write but painfully slow for anything compute-heavy. Go is fast but verbose — error handling alone accounts for a third of my code. Rust is powerful but the learning curve is brutal for the kind of tools I build daily. So I built Wyn . Wyn compiles to C, produces 49KB binaries, builds in under a…

Kubernetes Gateway API: The Future of Ingress

Gateway API is what Ingress should have been from day one. I don’t say that lightly. I’ve spent years wrangling Kubernetes Ingress resources, writing controller-specific annotations, and debugging routing issues that only existed because the Ingress spec was too simple for real-world traffic management. Gateway API fixes nearly every complaint I’ve ever had, and if you’re…

AWS Bedrock: Building AI Applications with Foundation Models

Bedrock is AWS finally getting AI right. I don’t say that lightly. I’ve watched AWS stumble through SageMaker’s complexity, watched teams burn months trying to self-host open-source models on EC2, and watched startups hemorrhage money on OpenAI API calls with zero fallback plan. Bedrock cuts through all of that. You pick a foundation model, call an API, and you’re building.…

Infrastructure Drift Detection and Remediation

If you’re not running scheduled terraform plan , you have drift. You just don’t know it yet. I learned this the hard way. A colleague made a “quick fix” in the AWS console — changed a security group rule to unblock a vendor integration. Totally reasonable in the moment. Nobody updated the Terraform code. Three weeks later, I ran a deploy that included security group changes…

AWS Architecture Guide: Production Patterns and Best Practices

Everything I’ve learned building on AWS since 2012, organized by domain. Serverless AWS Lambda Cold Starts: Causes, Measurement, and Mitigation — The definitive cold start guide AWS Step Functions: Orchestrating Complex Workflows — State machine patterns AWS EventBridge: Event-Driven Architectures — Building event-driven systems Containers AWS ECS vs EKS: Choosing Your Container Orchestrator…

Kubernetes Guide: From Basics to Production Operations

This is the hub for everything I’ve written about Kubernetes. Whether you’re setting up your first cluster or optimizing a multi-tenant production environment, start here. Cluster Security Kubernetes RBAC Deep Dive: Multi-Tenant Clusters — Role-based access control for teams sharing a cluster Kubernetes Network Policies: Practical Security Guide — Pod-to-pod traffic control with Calico…

Kubernetes Multi-Cluster Management with Fleet and Rancher

I’ve been running Kubernetes in production for years now, and there’s a specific kind of pain that only hits you once you cross the threshold from “a couple of clusters” to “wait, how many do we have again?” That threshold, for me, was eight clusters. Eight clusters across three cloud providers and two on-prem data centers. And every single one of them had…

Rust WebAssembly: Building High-Performance Web Applications

Last year I ported an image processing pipeline from JavaScript to Rust compiled to WebAssembly. The JS version took 1.2 seconds to apply a chain of filters — blur, sharpen, color correction, resize — to a 4K image in the browser. The Rust Wasm version did the same work in 58 milliseconds. Not a typo. A 20x speedup, running in the same browser, on the same machine, called from the same React app.

AWS Aurora Serverless v2: Architecture and Performance Guide

Aurora Serverless v2 is what v1 should have been. I don’t say that lightly — I ran v1 in production for two years and spent more time fighting its scaling quirks than actually building features. The pausing, the cold starts, the inability to add read replicas. It was a product that promised serverless databases and delivered something that felt like a managed instance with extra steps. When…

Implementing SLOs and Error Budgets in Practice

99.99% availability sounds great until you realize that’s 4 minutes and 19 seconds of downtime per month. Four minutes. That’s barely enough time to get paged, open your laptop, authenticate to the VPN, and find the right dashboard. You haven’t even started diagnosing anything yet. I’ve watched teams commit to four-nines SLOs because someone in a leadership meeting said…

Python Packaging in 2026: uv, Poetry, and the Modern Ecosystem

I mass-deleted requirements.txt files from a monorepo last month. Fourteen of them. Some had unpinned dependencies, some had pins from 2021, one had a comment that said # TODO: fix this next to a package that no longer exists on PyPI. Nobody cried. The CI pipeline didn’t break. We’d already moved everything to pyproject.toml and uv. Python packaging has been a punchline for years.…

Kubernetes Ingress Controllers: NGINX vs Traefik vs Istio Gateway

NGINX Ingress is the Honda Civic of ingress controllers. Boring, reliable, gets the job done. I’ve deployed it on dozens of clusters and it’s never been the thing that woke me up at 3am. That’s the highest compliment I can give any piece of infrastructure. But boring doesn’t mean it’s always the right choice. I’ve spent the last three years running all three…

AWS Step Functions: Orchestrating Complex Workflows

I deleted roughly 2,000 lines of orchestration code from our payment processing service last year. Replaced it with about 200 lines of Amazon States Language JSON. The system got more reliable, not less. That’s the short version of why I think Step Functions is one of the most underappreciated services in AWS. The longer version involves a 3am incident, a chain of Lambda functions calling…

Terraform Testing: Unit, Integration, and End-to-End

Most Terraform code has zero tests. That’s insane for something managing production infrastructure. We wouldn’t ship application code without tests — why do we treat the thing that creates our VPCs, databases, and IAM roles like it’s somehow less important? I learned this lesson the painful way. Last year I pushed a Terraform change that modified a security group rule on a shared…

Distributed Tracing with OpenTelemetry: A Complete Guide

I spent four hours on a Tuesday night debugging a 30-second API call. Four hours. The call touched 12 services — auth, inventory, pricing, three different caching layers, a recommendation engine, two legacy adapters, and a handful of internal APIs that nobody remembered writing. Logs told me nothing useful. Metrics showed elevated latency somewhere in the pricing path, but “somewhere”…

Container Security Scanning in CI/CD Pipelines

If you’re not scanning container images before they hit production, it’s only a matter of time before something ugly shows up in your environment. I learned this the hard way, and I’m going to walk you through exactly how I set up container security scanning in CI/CD pipelines so you don’t repeat my mistakes. The Wake-Up Call About two years ago, I was running a handful of…

AWS EventBridge: Building Event-Driven Architectures

EventBridge is the most underused AWS service. I’ll die on that hill. Teams will build these elaborate Rube Goldberg machines out of SNS topics, SQS queues, and Lambda functions stitched together with duct tape and prayers, when EventBridge would’ve given them a cleaner architecture in a fraction of the time. I know this because I was one of those teams. About two years ago I inherited…

Python Performance Optimization: Profiling and Tuning Guide

Don’t optimize until you’ve profiled. I’ve watched teams rewrite entire modules that weren’t even the bottleneck. Weeks of work, zero measurable improvement. The code was “cleaner” I guess, but the endpoint was still slow because the actual problem was three database queries hiding inside a template tag. I learned this the hard way on a Django project a couple…

Kubernetes Operators: Building Custom Controllers in Go

Operator SDK vs kubebuilder — I pick kubebuilder every time. Operator SDK wraps kubebuilder anyway, adds a layer of abstraction that mostly just gets in the way, and the documentation lags behind. Kubebuilder gives you the scaffolding, the code generation, and then gets out of your face. That’s what I want from a framework. I built my first operator about two years ago. The task: automate…

Rust Error Handling Patterns for Production Applications

I got paged at 3am on a Tuesday because a Rust service I’d deployed two weeks earlier crashed hard. No graceful degradation, no useful error message in the logs. Just a panic backtrace pointing at line 247 of our config parser: .unwrap() . The config file had a trailing comma that our test fixtures didn’t cover. One .unwrap() on a serde_json::from_str call, and the whole service went…

AWS CDK vs Terraform: A Practical Comparison in 2026

I use both. Terraform for multi-cloud, CDK when it’s pure AWS and the team knows TypeScript. That’s the short answer. But the long answer has a lot more nuance, and I’ve earned that nuance the hard way — including one migration that nearly broke a team’s shipping cadence for two months. This isn’t a “which one is better” post. I don’t think that…

Platform Engineering: Building an Internal Developer Platform

Platform engineering is DevOps done right. Or maybe it’s DevOps with a product mindset. Either way, it’s the recognition that telling every team to “own their own infrastructure” without giving them decent tooling is a recipe for chaos. I’ve watched organisations try the “you build it, you run it” approach and end up with fifteen different ways to deploy a…

Kubernetes Horizontal Pod Autoscaling with Custom Metrics

CPU-based autoscaling is a lie for most web services. There, I said it. I spent a painful week last year watching an HPA scale our API pods from 3 to 15 based on CPU utilization. The dashboards looked great — CPU was being “managed.” Meanwhile, the service was falling over because every single one of those 15 pods was fighting over a connection pool limited to 50 database connections.…

Go Concurrency Patterns for Microservices

Goroutines are cheap. Goroutine leaks are not. I learned this the hard way at 2am on a Tuesday, staring at Grafana dashboards showing one of our services consuming 40GB of RAM and climbing. The service normally sat around 500MB. We’d shipped a change three days earlier — a seemingly innocent fan-out pattern to parallelize calls to a downstream API. The code looked fine. Reviews passed. Tests…

Implementing Zero-Trust Networking on AWS

VPNs are not zero trust. Stop calling them that. I can’t count how many times I’ve sat in architecture reviews where someone points at a Site-to-Site VPN or a Client VPN endpoint and says “we’re zero trust.” No. You’ve built a tunnel. A tunnel that, once you’re inside, gives you access to everything on the network. That’s the opposite of zero trust.…

Python Type Hints and Static Analysis in Production Codebases

If you’re writing Python without type hints in 2026, you’re making life harder for everyone — including future you. I held out for a while. I liked Python’s flexibility, the duck typing, the “we’re all consenting adults here” philosophy. Then a production bug cost my team three days of debugging, and I changed my mind permanently. I’m going to walk through…

AWS Cost Optimization: 15 Techniques That Actually Work

I got a call from a startup founder last year. “Our AWS bill just hit $47,000 and we have twelve engineers.” They’d been running for about eighteen months, never really looked at the bill, and suddenly it was eating their runway. I spent a week inside their account. We cut it to $28,000. That’s a 40% reduction, and honestly most of it was embarrassingly obvious stuff. That…

Kubernetes RBAC Deep Dive: Securing Multi-Tenant Clusters

I’m going to say something that’ll upset people: if your developers have cluster-admin access in production, you’re running on borrowed time. I don’t care how small your team is. I don’t care if “everyone’s responsible.” It’s insane, and I’ve got the scars to prove it. This article is the RBAC deep dive I wish I’d had before a…

Terraform Modules: Design Patterns for Reusable Infrastructure

I once inherited a project with a single main.tf that was over 3,000 lines long. No modules. No abstractions. Just one enormous file that deployed an entire production environment — VPCs, ECS clusters, RDS instances, Lambda functions, IAM roles — all jammed together with hardcoded values and copy-pasted blocks. Changing a security group rule meant scrolling for five minutes and praying you edited…

GitOps with ArgoCD: From Zero to Production

ArgoCD won the GitOps war. I’ll say it. Flux is fine—it works, it’s CNCF graduated, it has its fans—but ArgoCD’s UI alone makes it worth choosing. When something’s out of sync at 2am, I don’t want to be parsing CLI output. I want to click on a resource tree and see exactly what drifted. I’ve been running ArgoCD in production across multiple clusters for a couple…

Rust for Cloud Engineers: Why Systems Programming Matters

I started learning Rust as someone who’d spent years writing Python scripts and Go services for cloud infrastructure. My first reaction was honestly frustration — the borrow checker felt like a compiler that existed purely to reject my code. But something kept pulling me back. The binaries were tiny. The startup times were instant. And once my code compiled, it just… worked. No…

AWS ECS vs EKS: Choosing the Right Container Orchestrator in 2026

ECS is underrated. Most teams picking EKS don’t need it. I’ve been saying this for years, and I’ll keep saying it until the industry stops treating Kubernetes as the default answer to every container question. I watched a team — smart engineers, solid product — choose EKS for what was essentially a three-service CRUD application behind an ALB. They’d read the blog posts,…

Building Production-Ready Docker Images: A Multi-Stage Build Guide

I’ve shipped Docker images to production for years now, and the single biggest improvement I’ve made wasn’t some fancy orchestration tool or a new CI platform. It was learning to write proper multi-stage Dockerfiles. My CI pipeline used to spend 20 minutes rebuilding a bloated 2GB image every push. After switching to multi-stage builds, that image dropped to 45MB and builds…