DevOps Engineering Portfolio
LiveThree sanitized case studies from production work at Keel Digital. Each documents the actual constraints and the reasoning behind the architecture that answered them, with before/after diagrams rather than just the finished state. Hostnames, network ranges, and service names are generalized; the architecture and decisions are real. The full write-ups live on GitHub.
Proxmox bare-metal migration
The dev environments ran on 14 DigitalOcean droplets, each billing independently and each with its own public IP — which meant 14 internet-facing machines that needed individual firewall hygiene, patching urgency, and monitoring as if they were production, for what were functionally internal environments.
The replacement is a single OVHcloud bare-metal server running Proxmox VE with
two bridges: vmbr0 carries the public interface and connects only
to a minimal gateway VM; vmbr1 is an internal RFC1918 bridge where
every dev VM lives, with no route out except through the gateway. The gateway
masquerades outbound traffic via nftables, and inbound access is deliberately
narrow — SSH to the gateway, then onward, with no direct port-forwards to dev
VMs by default. Because all egress now passes one chokepoint, logging and
restricting what dev environments can reach externally became a single config
file instead of 14.
The migration favored rebuild over copy: services already deployed via configuration were rebuilt fresh — which doubled as a test that the environment setup was actually reproducible — while databases were synced ahead of time and re-synced during cutover. New environments ran in parallel with the droplets, and nothing was destroyed until its replacement was confirmed working. Results: ~$1,500 CAD/month eliminated, attack surface down from 14 public IPs to 1, dedicated CPU and NVMe in place of shared-vCPU droplets, and Proxmox snapshot/restore where backups had been per-droplet and ad hoc. The retrospective is candid: the rebuild-vs-migrate classification took longer than the migration itself, and internal DNS should have existed before the first VM moved. Read the case study
Self-managed OpenSearch SIEM
A HIPAA environment with FedRAMP in scope, and observability scattered across CloudWatch, Keycloak, and Zabbix with no way to correlate between them. Three constraints shaped the build: logs containing PHI-adjacent metadata couldn't leave the AWS account in transit to a third-party SIEM, putting managed SaaS options off the table without significant legal review; per-GB commercial licensing gets expensive fast at 40+ services of continuous log volume; and detections needed to be owned and tuned in-house, not fit into a vendor's fixed rule taxonomy. Self-managed OpenSearch on AWS answered all three.
Ingestion runs Fluent Bit as a sidecar on every ECS task into a central
Logstash cluster, which normalizes fields, enriches at write time (IP
geolocation, instance metadata, Keycloak realm context — cheaper once on write
than repeatedly at query), and routes log types to index patterns with
different retention. ISM policies tier the lifecycle: hot on SSD for 7 days,
warm and compressed for 30, then snapshots to encrypted S3 for the one-year
retention HIPAA requires. Detections are Sigma rules compiled to OpenSearch DSL
with sigma-cli and tracked in git with normal PR review — the
audit trail for "when did we start detecting X" is just git log.
Alerts route to Slack for low severity and PagerDuty for high.
The build order mattered: schema and index templates before any data (remapping
after indexing means an expensive reindex), sources one at a time in order of
compliance value starting with CloudTrail, detections tuned against real data
before any dashboards. Auditor requests like "all authentication events for
user X over 90 days" went from a manual process to a saved search. The
lessons-learned section covers a user_id field collision that
forced a mid-stream reindex, and an initial detection set noisy enough that
tuning took longer than writing the rules.
Read the case study
OPKSSH dev access
Dev servers had three shared Linux accounts — devreadonly,
devuser, devadmin — and access meant a sysadmin
manually adding your public key to the right authorized_keys
file. Static keys never expired, offboarding depended on a checklist being
followed on every server, and answering "who has what access" meant matching
key fingerprints across machines by hand.
OPKSSH replaces the static key with an SSH certificate cryptographically bound
to a Google Workspace identity. A developer runs opkssh login,
completes a browser OAuth flow, and receives a time-limited cert carrying
their email and Google Group claims. Server-side, an
AuthorizedPrincipalsCommand in sshd_config invokes
the OPKSSH verifier, which checks the cert against Google's JWKS, confirms the
token hasn't expired, and matches group claims against
/etc/opkssh/policy.yml — a per-server mapping of Google Groups to
the three Linux accounts. No authorized_keys file involved. The
account tiers themselves were kept as-is; only what authorizes a person to use
each one changed.
The migration ran both auth paths in parallel: a fingerprint audit mapped every
existing key to a person (surfacing two keys attributable to nobody current),
Google Groups were populated to mirror the existing state, and developers moved
over in small batches before authorized_keys was removed entirely.
Offboarding was verified directly — a test account was suspended in Workspace
and a freshly issued cert for that identity was rejected at OIDC validation.
Access changes are now a Google Group edit, a leaked cert is self-revoking at
token expiry, and the orphaned-key problem is structurally impossible.
Read the case study