Multi-cloud architectures, designed and delivered.
Production systems, not slideware. Every diagram on this page shipped on AWS, Azure, Google Cloud or Red Hat OpenShift.
FinOps and DevSecOps are where I go deepest. Cloud billing read line by line, and security built into the pipeline rather than bolted on before release.
Seventeen years, and I still draw the diagram first. The decision behind each system is written next to it.
Delivered while leading cloud and DevOps infrastructure teams on client engagements. Client names and confidential detail are withheld; the diagrams are shown as architecture, not as customer data.
The architectures are the output. These are the four disciplines behind them. The first two take up most of my week.
FinOps and cloud billing analysis
Primary focus
I read the invoice line by line across AWS, Azure and Google Cloud, find where the spend really lands against where teams assume it lands, and turn that into rightsizing, commitment coverage and shutdown decisions. It runs every month, not once a quarter.
Tagging and showback so every team sees its own bill, and anomaly review so a runaway environment surfaces in days instead of at month end. Cost is a property of the architecture, settled at design time.
Billing and invoice analysis
Cost allocation and tagging
Showback and chargeback
Rightsizing
Reserved instances
Savings plans and CUDs
Anomaly detection
Unit economics
Budgets and forecasting
DevSecOps
Primary focus
Security built into every stage of delivery instead of bolted on before release: image scanning and provenance, policy gates in the pipeline, managed identities and secret handling pulled out of application code, and a written answer to which role owns which control.
Built for estates inside a compliance boundary, where the security review decides whether the workload ships at all.
Shift-left security
Pipeline policy gates
Image scanning
Secrets management
Managed identities
WAF and perimeter
Least-privilege IAM
Compliance boundaries
Audit evidence
Kubernetes platform engineering
Core practice
Clusters built as products rather than installs. EKS, AKS and GKE with routing, scaling, observability and the release path designed in from the start. GitOps as the delivery model, so cluster state lives in Git and a rollback is a revert.
EKS
AKS
GKE
Argo CD
Flux
Helm
Istio
Jenkins
Autoscaling
Grafana
Cloud migration and architecture
Core practice
Multi-cloud estates across all three providers: landing zones, networking foundations, availability across zones, and the enablement receiving teams need to run what they inherit. Infrastructure defined as code, so the estate is reproducible rather than remembered.
AWS
Azure
Google Cloud
Landing zones
VPC and hub networking
Multi-AZ HA
Terraform
Migration planning
Team enablement
The full technical stack
Seventeen years of it, ordered the way it stacks up: the newest work at the top, the data centre foundations I started on at the bottom. 232 technologies across 13 disciplines.
AI engineering and ML35
Claude Code
MCP
Agentic workflows
Prompt engineering
AI-assisted code generation and review
Test and runbook generation
IaC authoring
Azure OpenAI
Azure AI Foundry
Copilot Studio
GitHub Copilot
RAG design
Chunking and embeddings
Hybrid retrieval
Re-ranking
Caching and evaluation
Azure AI Search
pgvector
Pinecone
Chroma
LangChain
Semantic Kernel
Context engineering
Guardrails
Prompt-injection mitigation
LLM observability and evaluation
LLM agents
Tool and function calling
Model-serving
GPU scheduling (NVIDIA Operators)
Triton
Azure ML
Vertex AI
SageMaker
MLOps CI/CD
CI/CD and GitOps14
Azure DevOps
GitHub Actions
GitLab CI
Jenkins
TeamCity
CircleCI
GO.CD
Bitbucket Pipelines
Argo CD
Flux CD
Pipeline policy gates
OPA/Conftest on Terraform plans
Policy checks on Kubernetes manifests
Container image checks
Containers and orchestration25
Kubernetes (AKS/EKS/GKE)
Red Hat OpenShift (OCP, ROSA, ARO)
oc CLI
Projects
Routes
DeploymentConfigs and Deployments
BuildConfigs and S2I
ImageStreams
Operators and OperatorHub
SCCs
OpenShift Pipelines (Tekton)
GitOps (Argo CD)
Docker
Podman
Helm
Kustomize
Istio service mesh
LXC/LXD
VMware ESXi
Hyper-V
KVM
Xen
Proxmox
OpenStack
Vagrant
Cloud platforms23
AWS
Microsoft Azure
Google Cloud
Alibaba Cloud
EC2/S3/RDS
EKS
AKS
GKE
ECS
Lambda
Azure Functions
App Services
API Management
Front Door
App and Load Gateways
VNet/VPC
Route 53
Azure DNS
IAM
RBAC
BLOB/S3
Cosmos DB
Service Bus
Infrastructure as code and configuration7
Terraform
Pulumi
Bicep
Ansible
Chef
Puppet
Packer
DevSecOps and security17
Open Policy Agent (OPA)
Gatekeeper
Snyk
SonarQube
Trivy
Checkov
tfsec
Falco
Kube-bench
SAST/DAST
HashiCorp Vault
Azure Key Vault
AWS Secrets Manager
Defender for Cloud
AWS Security Hub
SOC compliance
PCI compliance
Observability16
Prometheus
Grafana
Loki
OpenTelemetry
Datadog
New Relic
Dynatrace
Elastic/ELK
Azure Monitor
CloudWatch
Zabbix
Nagios
SolarWinds
SCOM
PRTG
Site24x7
Migration expertise10
VM migrations (VMware vSphere/ESXi to cloud)
Kubernetes workload migrations (EKS / AKS / GKE)
Database migrations (MySQL, PostgreSQL, MongoDB, MS SQL, Oracle)
Public-to-private cloud
Private-to-public cloud
Azure and OpenStack
Data centre to cloud
Azure Migrate
Site Recovery
VPN/ExpressRoute
Migration and DR tooling20
Velero 1.14+ with OADP 1.4 (CSI)
CSI VolumeSnapshot
Veeam Backup & Replication v12+
Veeam Agent (Linux/Windows) v6+
Skopeo 1.15+
rclone 1.66+ (S3 sync)
Argo CD 2.12+
pglogical 2.4+ (PostgreSQL 15)
Native binlog (MySQL 8.4)
MyDumper 0.16
Native replica set (MongoDB 8.0)
Oracle Data Guard
Elasticsearch CCR
Zeebe broker snapshot
iperf3
k6 0.50+
pytest
kubectl health and smoke tests
OpenStack Designate
ExternalDNS
Microsoft 365 and identity13
M365 implementation and migration
Exchange Online
SharePoint
Teams
OneDrive
Entra ID (Azure AD)
Conditional Access
MFA
SSO
Intune
Microsoft Purview
Defender for Office 365
DLP
Windows and data centre14
Windows Server 2003–2025
Active Directory
GPO
DNS/DHCP
IIS
Exchange
SCCM
WSUS
On-prem AD sync with Azure AD
RAID
iSCSI storage
SSL
Endpoint protection
PowerShell
Linux, web and networking16
RHEL
CentOS
Ubuntu (through 24.04 LTS)
Apache
Nginx
LAMP
MEAN
LDAP
Postfix
SFTP/FTP
Bash scripting
Borg Backup
Firewalls
VPN
ExpressRoute
iSCSI
Databases and languages22
Python (platform orchestration)
FastAPI
REST APIs
Webhooks
Azure Python SDK
Azure CLI
Azure RM/ARM templates
Bicep
Bash
PowerShell
YAML
Groovy
MySQL
MS SQL
Oracle
MariaDB
PostgreSQL
MongoDB
Cosmos DB
Cassandra
Redis
RabbitMQ
AI security and governance
Where the AI layer meets the compliance boundary · 2 architectures
The two risks every AI rollout eventually hits: a retrieval pipeline that answers correctly from a document it should never have surfaced, and a team that solved its own AI problem by pasting company data into a tool nobody vetted. Both get treated as security work, because that is what they are.
01
LLM guardrails and secure RAG on Azure AI Foundry
Azure
Simplified architecture diagram
What I built
A retrieval-augmented generation pipeline on Azure OpenAI and Azure AI Foundry where access control is enforced at the vector layer, not just the application layer — a user's query can only retrieve documents their own identity is already entitled to see, checked against Entra ID at query time rather than filtered after the fact. Azure AI Content Safety and Prompt Shields sit in front of every call to catch prompt injection delivered through retrieved content, and every response is screened for PII and secrets before it leaves the model boundary.
Every RAG call is logged and traced end to end — the query, what was retrieved, what the model saw, and what it returned — so a wrong answer is debuggable and an audit is answerable.
Stack
Azure OpenAI
Azure AI Foundry
Azure AI Search (vector)
Azure AI Content Safety
Prompt Shields
Entra ID
Azure API Management
Why it matters
RAG is the default pattern for internal AI tools now, and the fastest way to open a new data-exposure path is a retrieval layer that was never asked to respect the permissions the rest of the estate already enforces. Getting the right answer from the wrong document is still a breach.
Engineering note. The hard part was never the generation — it was making retrieval honour the same access boundary as everything else in the estate, so the AI layer couldn't quietly become the one place permissions didn't apply.
02
AI usage governance for shadow AI
Azure
Simplified architecture diagram
What I built
Visibility into ungoverned AI usage across the organisation — which teams were calling which models, through which apps, with what data — surfaced by routing AI traffic through a governed gateway instead of leaving it to reach consumer tools directly. A policy layer at that gateway enforces which models are sanctioned for which data classification, so a prompt carrying regulated data can't reach a model tier that was never cleared for it.
Every call is tied to an identity and logged, turning "someone is probably using AI somewhere" into an answerable question.
Stack
Azure API Management (AI gateway)
Entra ID
Azure OpenAI
Microsoft Purview
Azure Monitor / Log Analytics
Why it matters
Shadow AI is this decade's shadow IT — employees solving their own problem by pasting confidential data into a tool nobody governs, discovered only after the fact. The organisations asking for this work aren't trying to stop AI adoption; they're trying to stop finding out about it in an incident report.
Engineering note. The deliverable was the same one DevSecOps work always comes down to: not more tooling, but a written answer to who is accountable when a model sees something it shouldn't have.
Secure by design
Platform-level security, not just application-level · 3 architectures
Three architectures where the security posture was the requirement, not an afterthought. These are the reference patterns I reach for in banking, insurance and any workload sitting inside a compliance boundary.
03
DevSecOps on Azure Kubernetes Service
Azure
Architecture as delivered
What I built
Security controls embedded into every stage of the DevOps lifecycle rather than bolted on at release, with the built-in platform tooling preferred over third-party add-ons wherever it exists.
The model is written for three audiences at once — developers building applications that run on AKS, cloud engineers building the AKS infrastructure itself, and the operations teams who govern clusters and monitor security issues day to day.
Stack
Azure Kubernetes Service
CI/CD pipelines
Built-in Azure security tooling
Why it matters
Most teams can name their security tools. Far fewer can say which role owns which control. This is the artifact that settles that argument before the first sprint.
Engineering note. The real deliverable was ownership. Naming the controls is easy; deciding which role signs off a container image before it reaches production — developer, platform engineer or cluster operator — is what stops the argument recurring every sprint.
04
Locked-down applications on Azure App Service Environment
Azure
Architecture as delivered
What I built
An expense-report application deployed into an App Service Environment, with access from the public internet restricted through Azure Application Gateway and Azure Web Application Firewall.
Continuous integration and deployment into the App Service Environment handled through Azure DevOps.
Stack
App Service Environment
Application Gateway
Azure WAF
Azure DevOps
Why it matters
Built for the sectors that ask about platform-level security before they ask about features — banking and insurance being the usual two.
Engineering note. Designed for a workload that had to clear a security review before it cleared a functional one. An isolated App Service Environment behind Application Gateway and WAF is the shortest defensible path to that.
05
Line-of-business application on App Service Environment v3
Azure
Architecture as delivered
What I built
An isolated, dedicated environment for a line-of-business application belonging to a tightly governed, compliance-restricted customer segment — designed to hold up under high memory utilisation and high requests per second, not only under audit.
Deployable two ways: consuming existing resources in the customer’s Azure landing zone hub VNet, or standing alone as a self-contained workload.
Stack
App Service Environment v3
Azure landing zone
Hub VNet
Why it matters
Isolation usually costs you scale. This one is engineered so security and performance are answered in the same design.
Engineering note. Built to deploy either way — into an existing landing zone hub VNet or standalone — so the pattern survives a network team that has already made its decisions.
Pipelines that actually ship
Six CI/CD builds across three clouds · 6 architectures
The largest group in this portfolio, and deliberately so. Every one of these takes a commit and ends at a running workload — Jenkins, Argo CD, Cloud Build, CodePipeline and Flux, chosen to fit the environment rather than the other way round.
06
Node.js on GKE with Jenkins, Argo CD and Helm
Google Cloud
Architecture as delivered
What I built
A containerised Node.js application deployed to Google Kubernetes Engine. Jenkins owns continuous integration — building, testing and pushing the image to Docker Hub.
Argo CD with Helm owns delivery: it syncs against the charts repository, pulls the images Jenkins published, and applies the resulting changes to the GKE cluster.
Stack
Node.js
Docker
GKE
Jenkins
Argo CD
Helm
Docker Hub
Why it matters
A clean split between build and deploy. The cluster’s desired state lives in Git, so a rollback is a revert rather than an incident.
Engineering note. Build and deploy kept deliberately separate. Desired cluster state lives in Git, so a bad release is a revert rather than an incident.
07
Cross-project CI/CD with Cloud Build
Google Cloud
Architecture as delivered
What I built
Code developed in Cloud Shell and pushed to Google Source Repositories, which triggers Cloud Build.
Cloud Build executes the build, produces container artifacts and pushes the images, then deploys the application onward — through Artifact Registry to GKE and Cloud Run.
Stack
Cloud Shell
Source Repositories
Cloud Build
Artifact Registry
GKE
Cloud Run
Why it matters
Entirely managed services end to end. Nothing here is a build server somebody has to patch.
Engineering note. Managed services end to end. There is no build server in this design for anyone to patch, and Cloud Run absorbs the request- and event-driven workloads that do not justify a cluster.
08
Container pipeline on AKS with Jenkins
Azure
Architecture as delivered
What I built
An engineer pushes code from VS Code to GitHub. Jenkins, running on an Azure VM, automatically builds the container service through Azure Container Registry.
Azure Cosmos DB holds the data. Azure Monitor collects and analyses telemetry, and Grafana turns that telemetry into the analytics and alerts the operations team actually watches.
Stack
Jenkins
Azure VM
Azure Container Registry
AKS
Cosmos DB
Azure Monitor
Grafana
Why it matters
The observability layer is drawn in from the start. The pipeline and the dashboards were designed together, which is rarer than it should be.
Engineering note. The observability layer was designed alongside the pipeline rather than added after the first outage. What operations can see during an incident is decided while the pipeline is still on paper.
09
AWS CodePipeline with Flux
AWS
Architecture as delivered
What I built
A push to the AWS code repository triggers CodePipeline, which builds the application.
Amazon ECR manages the node worker through Flux — the continuous and progressive delivery toolset for Kubernetes — so cluster state follows the registry.
Stack
AWS CodePipeline
Amazon ECR
Flux
Kubernetes
Why it matters
Progressive delivery on AWS-native services. Releases move forward in controlled steps rather than one all-or-nothing cutover.
Engineering note. GitOps without adding a vendor to an AWS-committed estate. Flux reconciles the cluster against ECR rather than a pipeline pushing into it, which keeps the cluster the source of truth for its own state.
10
React.js to EC2 via CodePipeline and CodeDeploy
AWS
Architecture as delivered
What I built
Developers push to GitHub. CodePipeline pulls and builds the application from a YAML definition and pushes the build output to an S3 bucket.
A second YAML definition drives the deploy: the artifact is downloaded and unzipped from S3 and released onto the EC2 instance through AWS CodeDeploy.
Stack
React.js
GitHub
CodePipeline
S3
CodeDeploy
EC2
Why it matters
Not everything belongs in a cluster. This is the pragmatic path for a front end that has to land on instances the client already runs.
Engineering note. Not everything belongs in a cluster. The team already ran EC2 and had no appetite for Kubernetes, so the design met the estate that existed rather than the one on the roadmap.
11
Cloud-native CI/CD on Google Cloud
Google Cloud
Architecture as delivered
What I built
Automation applied across building, testing and deploying software, so that defects surface at the earliest possible stage instead of at release.
The commercial case is the point of this one: shorter turnaround to market, and a measurable reduction in total software development cost from catching bugs and issues early.
Stack
Google Cloud
CI/CD automation
DevOps practice
Why it matters
The board-level version of the argument. Faster releases are a revenue and market-share conversation before they are an engineering one.
Engineering note. The one architecture here argued in commercial terms — earlier defect detection and shorter turnaround to market — because the sponsor was funding it on that basis, not on tooling.
Kubernetes platform engineering
Clusters designed as products, not as installs · 2 architectures
Standing a cluster up is a weekend. Making it routable, observable, cost-aware and safe to deploy into is the job. Two builds that show the difference.
12
Kubernetes on AWS with EKS
AWS
Architecture as delivered
What I built
An Amazon VPC purpose-built for the cluster, including subnets and security groups, with the EKS cluster created on top and applications deployed onto it.
A Kubernetes Service of type LoadBalancer exposes the application; the VPC load balancer is configured to use the ELB as its target group; Route 53 maps the application hostname to the load balancer’s DNS name.
Stack
Amazon EKS
VPC
Subnets
Security groups
ELB
Route 53
Why it matters
The full path from DNS name to pod, drawn once and agreed once. This is the diagram that prevents six weeks of networking tickets.
Engineering note. The complete path from DNS name to pod, drawn and agreed once. Most Kubernetes networking tickets exist because that path was never written down.
13
GKE with Istio service mesh
Google Cloud
Architecture as delivered
What I built
Containerised services packed into pods and placed across nodes, with Istio installed for service-to-service communication.
Placement is treated as a graph clustering problem: the application is modelled as a graph, and placement minimises both node resources and the bandwidth consumed between communicating nodes. Several clustering methods were deployed on GCP against two real use cases — an IoT architecture and an e-shop.
Stack
GKE
Istio
Kubernetes scheduling
Graph clustering
Why it matters
Measured against default Kubernetes placement, hosting cost on GCP came down significantly. This is FinOps done in the scheduler rather than in a spreadsheet.
Engineering note. Pod placement modelled as a graph clustering problem instead of left to the default scheduler, then measured against two real workloads — an IoT estate and an e-shop — rather than a synthetic benchmark.
OpenShift on private infrastructure
Enterprise Kubernetes inside the perimeter · 2 architectures
Not every regulated workload is allowed to leave the building. These two run on Red Hat OpenShift in a private network, where the ingress path, the east-west policy and the storage class are all decisions someone has to own.
14
Three-tier .NET and PostgreSQL platform on OpenShift
OpenShift
Architecture as delivered
What I built
A three-tier application on a Red Hat OpenShift cluster, split across three Projects: the .NET application tier with its Deployment, Service and Route; the database tier running PostgreSQL as a StatefulSet with its own Secret and PersistentVolumeClaim; and a supporting Project for Redis and other internal services.
External traffic arrives over HTTPS on 443, reaches the highly available OpenShift Router, and is matched against a Route that forwards to the application Service. The application reaches its backend and its database through internal Services and cluster DNS, never through Pod addresses. Deployments run through OpenShift Pipelines: commit, build, test, push to the internal image registry, then a rolling update onto the worker nodes.
Stack
Red Hat OpenShift
Projects and namespaces
Router and Route
ClusterIP Services
.NET Deployment
PostgreSQL StatefulSet
PVC and StorageClass
Secrets and ConfigMaps
OpenShift Pipelines
Internal image registry
Redis
NetworkPolicies
Why it matters
The request path and the deployment path drawn in one picture, with the control plane, worker nodes and each Project's responsibilities named. It is the document an operations team can actually run the platform from.
Engineering note. Two rules carry most of the design. Applications address PostgreSQL through the Service FQDN, postgres.db.svc.cluster.local:5432, because Pod addresses change on every reschedule. And a StatefulSet buys stable identity and storage, not database high availability: production PostgreSQL HA needs a proper replication design or an operator, and saying so early avoids a painful conversation later.
15
Private OpenShift platform for a health and wellbeing SaaS
OpenShift
Target architecture as designed
What I designed
A React frontend, a Node.js backend and a replicated MySQL tier on a private OpenShift cluster, sitting on-premises or in a private VPC. Exactly one hostname is published: the Route points at the frontend Service, while the backend and database Services stay ClusterIP and have no Route at all.
MySQL runs as a StatefulSet with a primary and at least one replica, each Pod claiming durable storage through a PVC, a StorageClass and the cluster's underlying volumes. NetworkPolicies encode the intended three-tier path as a deny-by-default table: internet to Router on 443, Router to frontend, frontend to backend on the API port, backend to MySQL on 3306, and nothing else. CI/CD builds both images, runs tests and security checks, then rolls Pods forward behind readiness and liveness probes.
Stack
Red Hat OpenShift
HAProxy Router
Route and TLS
React.js
Node.js
MySQL primary and replica
StatefulSet
PVC, PV and StorageClass
Secrets and ConfigMaps
NetworkPolicies
OpenShift Pipelines
Readiness and liveness probes
Why it matters
The design a security review asks for: a single public entry point, everything else private, and a written policy for which service is allowed to talk to which. It is also the version of a three-tier app that survives an audit.
Engineering note. The interesting work was the traffic policy table rather than the components. Writing down every allowed flow, and explicitly denying internet access to the backend and the database, turns a diagram into something a platform team can implement and a reviewer can check. The same caveat applies as on the PostgreSQL build: a StatefulSet is not MySQL HA, so the replication approach has to be chosen and validated on its own terms.
Resilience, scale and the network underneath
What holds when a zone goes dark · 3 architectures
High availability is a claim until someone draws the failure path. These three cover redundancy, elastic capacity, and the cloud networking fundamentals a migrating team is usually missing.
16
Multi-AZ high availability for WordPress
AWS
Architecture as delivered
What I built
Two availability zones connected through a single internet gateway, with the WordPress application deployed into both.
A load balancer fronts the pair. When one availability zone goes down, traffic is redirected to the other — and in normal operation the same mechanism keeps any single instance from being overloaded.
Stack
AWS
Two availability zones
Internet gateway
Load balancer
WordPress
Why it matters
The smallest architecture here and often the most convincing. Everyone understands what it means for half the picture to disappear.
Engineering note. The smallest design here and the one that proves its own failure path: remove an availability zone from the picture and the remaining half still serves traffic.
17
Multi-service AWS architecture with autoscaling
AWS
Architecture as delivered
What I built
Client requests arrive over the internet through the NAT gateway and routing association, then reach the load balancer, which distributes traffic across servers according to availability and health.
Autoscaling handles multi-user demand — scaling out when requests spike and back in when traffic normalises. Jenkins propagates developer code changes automatically to the production servers.
Stack
AWS
NAT gateway
Load balancer
Auto Scaling
Jenkins
Why it matters
Elastic capacity and automated release in one architecture, so a traffic spike and a deployment are not two separate emergencies.
Engineering note. Elastic capacity and automated release in the same design, so a traffic spike and a deployment stop being two separate emergencies competing for the same on-call engineer.
18
Google Cloud networking foundations
Google Cloud
Architecture as delivered
What I built
A grounding in how cloud networking departs from a traditional on-premises data centre — written for the network engineers, system administrators and infrastructure teams who inherit the cloud estate.
GCP shares many concepts and capabilities with AWS and Azure, but the differences between providers are exactly what bites when workloads are migrated or moved between them.
Stack
Google Cloud VPC
Cloud networking
Multi-cloud comparison
Why it matters
I do not hand a migrated estate to a team that has not been briefed on it. Enablement is part of the delivery.
Engineering note. Written as enablement for the network and infrastructure teams inheriting the estate. Provider differences are what bite during a migration, and they bite the people who were never briefed.
Workflow and media automation
Where DevOps meets the actual business process · 2 architectures
Two builds that reach past infrastructure into the operation itself — a broadcast media supply chain, and a forms process that was costing a business real money every month.
19
Media supply chain on AWS ECS
AWS
Architecture as delivered
What I built
Clients upload files to a Vidispine server over high-speed transfer. Vidispine converts the video to the required formats and passes it to the MCM server, which hands off to the Chef server.
Chef automates deployment of the software to an S3 bucket acting as object storage, from which it is released to ECS. In parallel, the Jenkins build server on a Linux EC2 instance watches the GitHub repositories, builds on change, runs automated tests and packages the software as containers for ECS to run.
Stack
AWS ECS
Vidispine
MCM server
Chef
Jenkins
GitHub
S3
MongoDB
MS Exchange
EC2
Why it matters
Eleven distinct systems, including third-party media servers I did not write, integrated into one automated flow. The hard part of enterprise DevOps is rarely the cloud services.
Engineering note. Eleven systems, several of them third-party media servers whose interfaces I did not control, integrated into one automated flow. The integration was consistently harder than the cloud services.
20
Automated PDF forms processing on Azure
Azure
Architecture as delivered
What I built
A designated Outlook account receives PDFs as attachments; the arriving email triggers a logic app that uploads them to a container in Azure Data Lake Storage. Files can also be placed in that container manually or programmatically.
A PDF landing in the container triggers a second logic app, which passes the file location to an Azure Functions app. The function splits multi-page files into single-page forms, saves them to a second container, and posts each location to Azure Form Recognizer over the REST API.
Form Recognizer’s response is written as a JSON data file to a third container, returned to the processing logic app, and saved into Azure Cosmos DB. Power BI reads Cosmos DB to deliver the dashboards and insights, and further processing can be layered on the same data.
Stack
Azure Logic Apps
Azure Functions
Data Lake Storage
Form Recognizer
Cosmos DB
Power BI
Outlook
Why it matters
Replaces a costly, inflexible forms process with one that is cheap to run and easy to change — and ends in a dashboard rather than a filing cabinet.
Engineering note. Event-driven from the first trigger — an email arriving, a blob landing, a function splitting pages, a Form Recognizer call — so each stage stays independently replaceable as the forms change.
A regulated platform, end to end
The full-stack build · 1 architecture
One architecture that pulls together everything above — clients, real-time communication, microservices and managed data — inside healthcare’s constraints.
21
Telehealth platform on Azure
Azure
Architecture as delivered
What I built
Built on four pillars: clients, communication components, APIs and business logic, and the storage and infrastructure services underneath.
Two client groups. The healthcare professional works through fitting software and a web portal; the patient uses a mobile app paired to a medical device over Bluetooth. Public-facing APIs and internal microservices carry the traffic between them — WebRTC for video calls, SignalR for client-to-client messaging, Azure Cache for Redis for inter-service coordination, and Azure Notification Hub for asynchronous push.
State persists in Azure Database for PostgreSQL, media in Azure storage accounts, and every service’s logs land in a centralised Application Insights solution. Managed identities secure service-to-service communication and remove most secret handling from the codebase.
Stack
Azure
WebRTC
SignalR
Azure Cache for Redis
PostgreSQL
Blob storage
Application Insights
Notification Hub
Managed identities
Why it matters
Deliberately split so each team owns a functional domain and can move at its own pace. Independent codebases keep the CI/CD pipeline for the whole platform simple, and central logging keeps it debuggable.
Engineering note. Split so each team owns a functional domain and can release at its own pace, with managed identities carrying service-to-service auth so secrets largely leave the codebase.
A product of my own
Alertloop
A multi-tenant SRE and observability platform I designed, built and run — monitoring, APM, alerting and security advisories in one product, aimed at the ground Site24x7 and Datadog occupy. It is also where I test the architectural patterns on this page against a system I have to keep running myself.
Platform architecture
What it does
Universal asset model. One assets table with a tag-based rule engine and fingerprint deduplication, so hosts, containers and ephemeral workloads are monitored under a single model rather than four.
APM and RUM on OpenTelemetry. Traces collected through the OTel Collector into ClickHouse, derived metrics into VictoriaMetrics.
Tenant isolation by design. A database per tenant, with an automated test suite that exists specifically to prove tenants cannot see each other.
Security advisories tied to your estate. CVE feeds matched against the assets you actually run, with generated remediation held behind a mandatory human review gate.
LLM cost observability. Token and spend tracking across the major providers, broken down per developer — the FinOps problem moved to AI workloads.
CI/CD observability. Pipeline health treated as a first-class signal rather than something you learn about from a failed deploy.
Stack
Python
FastAPI
SQLAlchemy
MySQL, database per tenant
ClickHouse
VictoriaMetrics
OpenTelemetry
OTel Collector
React
Vite
Tailwind
shadcn/ui
Alembic migrations
Azure Container Apps
pytest
Certifications
Current credentials across the four platforms in this portfolio. Each one links to its issuer for verification.
What I am brought in for
Five disciplines behind the twenty-one architectures. Each has its own page, with the builds that prove it.
The sequence behind every architecture above. Most cloud programmes come apart at the first phase, not the last.
Requirements
I map the estate as it stands: workloads, constraints, compliance boundary and who owns what. That comes before anything is drawn.
Design
The architecture is drawn and agreed with the people who will run it. Every diagram above started here.
Build
Infrastructure and pipelines built to the agreed design, with security controls embedded as the work proceeds.
Test
Automated tests in the pipeline, plus verification that the failure paths behave the way the diagram claims.
Cutover
Deployment and handover, including the enablement the receiving network and operations teams need.
Run
Ongoing maintenance and iteration. Timelines ran from six weeks for a simple build to several months for a full platform.
What clients said
Feedback on engagements delivered by teams I led, paraphrased from client reviews.
Credited the team with bringing task-oriented focus to a technical job that badly needed leadership and direction.
Crockett Dunn, LLC
Highlighted the team’s communication and its command of both AWS and Azure across the engagement.
Omnium Group Corporation
Noted regular communication through a large deliverable, and deep subject knowledge in the Proxmox environment.
Tellarc
Described the engagement as a straightforward pleasure and said they would engage the team again immediately.
Andrew Carlson
Bring your requirements. I’ll bring the diagram.
Slots come straight from my calendar, so the times shown are ones I am actually free. Thirty minutes is enough to walk through an architecture in detail or give you a first read on your cloud bill. Most of my work runs remotely, and I travel across Canada and the United States for meetings, kickoffs and workshops.