A pipeline isn't a build-it-once artifact; it's a production system that needs operating. It degrades — tests get flaky, builds get slow, rollbacks get rusty — and if you can't measure your delivery, you can't improve it. This closing post is about keeping a pipeline healthy over time and using the DORA metrics to know whether your CI/CD is actually working.
A pipeline isn't a build-it-once artifact; it's a production system that needs operating. It degrades — tests get flaky, builds get slow, rollbacks get rusty — and if you can't measure your delivery, you can't improve it. This closing post covers keeping a pipeline healthy, fast recovery over rare failure, observability, and using the DORA metrics to know whether your CI/CD actually works.
The CI/CD pipeline is one of the most privileged systems in an engineering organization — it has access to source code, secrets, and the keys to production — which makes it a prime target. Worse, it can become the delivery mechanism for an attack: compromise the pipeline and you compromise everything it ships. This post is about securing the pipeline itself and building security into it, the heart of DevSecOps.
The CI/CD pipeline is one of the most privileged systems in an org — access to source, secrets, and the keys to production — which makes it a prime target and a potential delivery mechanism for an attack. This post secures the pipeline itself (least privilege, secrets, pinned deps) and builds security into it (SAST/SCA/DAST), plus supply-chain integrity: SBOM, signing, SLSA provenance.
A pipeline is only trustworthy if it's defined the same way your application is: as version-controlled code, reviewed and reproducible. "Pipeline as code" turns the path to production from clicked-together settings in a web UI into a file in your repository — and that shift, from configuration to code, brings the whole discipline of software engineering to bear on how you ship software.
A pipeline is only trustworthy if it's defined the same way your application is: as version-controlled code, reviewed and reproducible. Pipeline as code turns the path to production from clicked-together settings in a web UI into a file in your repository — bringing the whole discipline of software engineering to bear on how you ship software. The declarative model and principles for doing it well.
How you put new code into production is a design decision with real consequences for risk and downtime. Deploy it all at once and a bad release hits everyone; roll it out gradually and you can catch problems while they're small. Blue-green, canary, rolling, and feature flags are the core techniques — each trading complexity for safety in a different way. This post covers when and why to use each.
How you put new code into production is a design decision with real consequences for risk and downtime. Deploy it all at once and a bad release hits everyone; roll it out gradually and you catch problems while they're small. Blue-green, canary, rolling, and feature flags are the core techniques — each trading complexity for safety differently. When and why to use each.
The two D's in CD/CD get used interchangeably, but they name genuinely different practices with different risk profiles and different prerequisites. Getting the distinction right — and knowing which one your system is actually ready for — is the difference between a mature delivery pipeline and a dangerous one. This post draws the line clearly and covers what it takes to cross it.
The two D's in CD get used interchangeably, but they name genuinely different practices with different risk profiles and prerequisites. Continuous Delivery keeps a human approval before production; Continuous Deployment removes it. This post draws the line clearly, covers environment promotion, and helps you decide which your system is actually ready for.
The build and test stages are the engine of a pipeline — the part that decides, on every change, whether it's safe to proceed. Get them fast and trustworthy and the whole pipeline flows; get them slow or flaky and the pipeline becomes something developers route around. This post is about designing tests and builds that give a fast, reliable verdict.
The build and test stages are the engine of a pipeline — the part that decides, on every change, whether it's safe to proceed. Get them fast and trustworthy and the pipeline flows; get them slow or flaky and it becomes something developers route around. This post covers the test pyramid, deterministic tests, fail-fast staging, build-once-promote, caching, and parallelism.
Continuous Integration is the least glamorous and most important half of CI/CD. It's also the most misunderstood — teams install a build server, call it "CI," and miss the actual practice, which is a discipline about how often you merge, not which tool runs your tests. This post is about the real thing: integrating small, integrating often, and keeping the mainline always green.
Continuous Integration is the least glamorous and most important half of CI/CD, and the most misunderstood — teams install a build server, call it CI, and miss the actual practice, which is a discipline about how often you merge, not which tool runs your tests. This post is the real thing: integrate small, integrate often, keep the mainline always green.
CI/CD is one of those acronyms everyone uses and few can define precisely. Strip away the tooling and it's an answer to a simple, painful question: how do you take a change a developer just wrote and get it safely into users' hands, quickly and repeatedly, without fear? This opening post defines the terms from first principles and explains the problem they solve.
CI/CD is an answer to a simple, painful question: how do you take a change a developer just wrote and get it safely into users' hands, quickly and repeatedly, without fear? This opening post defines the terms from first principles — CI, Continuous Delivery vs Deployment, the pipeline — and explains the integration-hell and deployment-fear problems they were invented to kill.
Kubernetes's deepest idea isn't its built-in objects — it's that the reconciliation model is extensible. You can teach Kubernetes new concepts and automate operating them, which is what operators do. This closing post covers that extension model, the realities of running Kubernetes in production, and the honest verdict on when its power is worth its complexity.
Kubernetes's deepest idea isn't its built-in objects — it's that the reconciliation model is extensible. You can teach Kubernetes new concepts and automate operating them, which is what operators do. Plus the realities of running it in production, and when it's worth the complexity.
The hardest part of platform engineering isn't the technology — it's building a platform people actually adopt, and knowing whether it's working. This closing post covers treating the platform as a product, measuring it with DORA metrics and adoption, structuring the team, and the failure modes that sink platforms. Getting these right is what turns platform engineering from a project into a lasting capability.
The hardest part of platform engineering isn't the technology — it's building a platform people actually adopt, and knowing whether it's working. Treat the platform as a product, measure it with DORA metrics and adoption, and avoid the failure modes that sink platforms.
Kubernetes has to answer a question every time a pod is created: which machine should run it? The scheduler answers it, and the quality of that answer depends entirely on information you provide — resource requests and limits. Get those right and the cluster packs efficiently and stays stable; get them wrong and you get waste, evictions, and mysterious outages.
Kubernetes answers a question every time a pod is created: which machine runs it? The scheduler answers it, and the quality depends on resource requests and limits you provide. Get those wrong and you get waste, evictions, and mysterious outages.
A platform that ships fast but falls over isn't a good platform. Reliability is a first-class platform capability — and the smartest move platform engineering makes is to build observability and SRE practices into the platform, so every service gets monitoring, SLOs, and reliability by default instead of each team reinventing them. Reliability becomes a paved road too.
A platform that ships fast but falls over isn't a good platform. Reliability is a first-class platform capability — the smartest move is to build observability and SRE practices into the platform, so every service gets monitoring, SLOs, and reliability by default.
Pods are disposable — destroyed and recreated constantly — which raises two problems: how do you give a pod its configuration without baking it into the image, and how does any data survive a pod's death? ConfigMaps and Secrets answer the first; volumes and StatefulSets answer the second. This is how stateless-by-default Kubernetes handles config and the state it can't avoid.
Pods are disposable, which raises two problems: how to give a pod its config without baking it into the image, and how any data survives a pod's death. ConfigMaps and Secrets answer the first; volumes and StatefulSets answer the second.
A golden path is the well-lit, paved road through your platform — the supported, opinionated way to build and ship a service, so a developer can go from idea to production without making a hundred infrastructure decisions. Developer experience is the measure of how good that road feels. Together they're what makes a platform actually reduce cognitive load rather than just relocate it.
A golden path is the well-lit, paved road through your platform — the supported, opinionated way to build and ship a service, so a developer goes from idea to production without a hundred infrastructure decisions. Developer experience is how good that road feels.
Pods are ephemeral and get new IPs every time they're replaced, so how does anything reliably reach them? The Service — a stable address and load balancer in front of an ever-changing set of pods. Kubernetes networking looks intimidating, but it's a few clear layers solving one problem: stable communication over unstable pods.
Pods are ephemeral and get new IPs every time they're replaced, so how does anything reliably reach them? The Service — a stable address and load balancer in front of an ever-changing set of pods. Kubernetes networking is a few layers solving one problem.
The internal developer platform is the product platform engineering builds: a self-service layer that packages all the infrastructure complexity — CI/CD, Kubernetes, cloud, IaC — into paved roads a developer can use without understanding any of it. Getting the concept right, especially the "platform as a product" mindset, is the difference between a platform developers love and one they route around.
The internal developer platform is the product platform engineering builds: a self-service layer that packages all the infrastructure complexity into paved roads a developer can use without understanding any of it. The 'platform as a product' mindset makes or breaks it.
Controllers are where Kubernetes's core idea — declarative desired state plus reconciliation — becomes machinery. A controller is a loop that watches "what you want" versus "what exists" and acts to close the gap, forever. Self-healing, scaling, and zero-downtime rollouts are all just controllers doing that one thing. This is the engine of Kubernetes.
Controllers are where Kubernetes's core idea — declarative desired state plus reconciliation — becomes machinery. A controller is a loop that watches what you want versus what exists and acts to close the gap, forever. Self-healing, scaling, and rollouts are all just that.
GitOps takes one idea to its logical conclusion: if your infrastructure and deployments are declarative code, then git should be the single source of truth, and a machine — not a human running commands — should continuously make reality match git. It turns "deploy" from an action you perform into a state you declare, and it's how modern platforms run.
GitOps takes one idea to its conclusion: if infrastructure and deployments are declarative code, git should be the single source of truth, and a machine — not a human running commands — should continuously make reality match git.
Kubernetes doesn't run containers directly — it runs pods. This surprises newcomers: why wrap a container in another abstraction? Because the pod solves a real problem — some containers genuinely need to run together, sharing network and storage — and making the pod (not the container) the unit of scheduling is what makes the rest of Kubernetes coherent.
Kubernetes doesn't run containers directly — it runs pods. Why wrap a container in another abstraction? Because some containers genuinely need to run together sharing network and storage, and making the pod the unit of scheduling keeps the rest of Kubernetes coherent.
Clicking through a cloud console to set up infrastructure is fast, fun, and a disaster you'll regret — because nobody can reproduce it, review it, or remember what you did. Infrastructure as code turns your servers, networks, and databases into version-controlled, reviewable, reproducible code. It's the practice that makes infrastructure an engineering discipline instead of an artisanal craft.
Clicking through a cloud console to set up infrastructure is fast, fun, and a disaster you'll regret — nobody can reproduce it, review it, or remember what you did. Infrastructure as code turns your servers and networks into version-controlled, reproducible code.
CI/CD is the assembly line of modern software — the automated path from a developer's commit to running production code. It's the practice that turned releases from rare, terrifying events into routine, boring ones, and "boring releases" is one of the highest compliments in software. It's also the first capability any platform provides.
CI/CD is the assembly line of modern software — the automated path from a developer's commit to running production code. It turned releases from rare, terrifying events into routine, boring ones, and 'boring releases' is one of the highest compliments in software.
Kubernetes is famously complex, and most explanations start with its parts — pods, deployments, services — which is exactly backwards. Start with the problem: you have containers, you have many machines, and you need something to run the right containers on the right machines and keep them running as things fail. Kubernetes is a control loop for that, and once you see it that way, the complexity becomes comprehensible.
Kubernetes is famously complex, and most explanations start with its parts — which is backwards. Start with the problem: you have containers, many machines, and need something to run the right containers on the right machines and keep them running as things fail.
DevOps promised to tear down the wall between development and operations — and it worked, but it accidentally built a new problem: it made every developer responsible for a sprawling stack of infrastructure, pipelines, and tooling nobody has time to master. Platform engineering is the industry's answer: give developers a paved road instead of a pile of tools. Understanding that evolution is the key to the whole discipline.
DevOps tore down the wall between dev and ops — and accidentally built a new problem: it made every developer responsible for a sprawling stack nobody has time to master. Platform engineering is the answer: give developers a paved road instead of a pile of tools.
If you encode each SOC 2 control as a Terraform module, the audit becomes a check against module usage rather than a per-resource review. Notes from Bloom and adjacent projects.