Act I
Origins
Learning the place one ticket at a time.
Brian: June 2016. My first message on BRI’s Slack: “Hi guys, new helpdesk tech here.”
job 01 · helpdesk · 2016
Helpdesk Technician
I started at Benaroya Research Institute on the helpdesk: imaging PCs, chasing firmware bugs, resetting passwords.
It is the best possible introduction to an organization — every lab, every person, every machine, and every way they break.
Brian: Fixing things one at a time doesn’t scale. So I started writing scripts that fix them for me.
job 02 · automate · 2018 – 2019
Automating myself out of tickets
A PowerShell script for password resets grew into modules for the systems I touched every day: directory, mail, file sharing, virtualization, HR and procurement.
By 2019 one command onboarded a new employee end to end — and called Ansible to build their Linux hosts. That toolkit still runs today as GitHub Actions workflows on a self-hosted Windows runner.
“With one line, an operator can create Ubuntu hosts that can be SSH’d into… end-to-end provisioning.”
Act II
Foundation
Bare metal to Kubernetes, all of it in code.
Designed and led by me, built with my team.
Brian: Everything starts with real hardware in a real rack.
job 03 · bare-metal · the rack
Bare metal & golden images
BRI runs on its own hardware: vSphere hosts on 10 GbE, Pure, Isilon and QNAP storage, and seven bare-metal HPC servers — up to 128 cores and 773 GiB of RAM each — joined directly to production Kubernetes.
Every VM starts from a Packer-built Ubuntu golden image that CI rebuilds whenever its template changes.
- bare-metal HPC nodes in Kubernetes
- 7
- cores on the largest node
- 128
- on every host
- 10 GbE
Brian: If it isn’t in Git, it doesn’t exist. VMs, DNS, identity, certificates — all of it.
job 04 · terraform · provision
Terraform: the whole estate as code
One Terraform monorepo describes BRI’s infrastructure across vSphere, Azure, AWS, Kubernetes, identity, networking and the automation platform itself, split into 26 independent state roots so a change touches only what it should.
Every pull request gets a plan per root and an IaC security scan; merging applies it on our own runners. Certificates and app secrets rotate on a schedule, not on someone’s memory.
- state roots
- 26
- managed resources
- ~600
- providers
- 24
Brian: Terraform builds the VM. Ansible makes it useful — without anyone logging in.
job 05 · ansible · configure
Ansible & AWX: machines that configure themselves
Terraform provisions AWX itself — job templates, inventories, credentials and schedules — and new VMs register and launch their own configuration jobs.
Kubespray playbooks install, upgrade, scale and roll-reboot clusters one node at a time, and etcd backups are encrypted before they leave the box.
- Ansible roles
- 25
- AWX job templates, defined in Terraform
- 16
Brian: Kubernetes is Greek for “helmsman.” So I took the wheel.
job 06 · kubernetes · orchestrate
Kubernetes on hardware we own
Four GitOps-managed clusters — dev, staging, a 23-node production cluster that includes the HPC servers, and a standalone monitoring node — run on hardware BRI already owns.
Operators run MySQL, PostgreSQL and MongoDB; Velero backs up workloads; cert-manager handles TLS; secrets come from a key vault at runtime; Prometheus and Loki watch everything.
- clusters
- 4
- Kubernetes nodes
- 46
- managed-cluster fees
- $0
Act III
Delivery
From a git push to the whole fleet: backed up, patched and watched.
Brian: May 2025: we ran out of GitHub Actions minutes — the same week I finished moving our builds on-prem.
job 07 · on-prem-ci · 2025
On-prem CI: builds that cost $0 a minute
Our builds run on our own cluster: autoscaling runner scale sets on Kubernetes, 7 to 15 general runners plus a small isolated privileged pool that only allow-listed workflows from main can use.
I also wrote the shared workflows every app calls. A repo gets lint, tests, a single image build, a vulnerability scan and a verified rollout by adding a few lines of YAML.
- per runner-minute
- $0
- reusable workflows
- 21
- composite actions
- 7
Brian: Nobody runs kubectl apply in production. Git does.
job 08 · fluxcd · deploy
FluxCD: the bridge between GitHub and Kubernetes
FluxCD is the critical link between GitHub and our clusters. Git is the source of truth: Flux watches the registry, commits new image tags as its own bot, and reconciles every cluster to match. Deploys, rollbacks and even database restores are pull requests.
Images are built once and promoted by retagging, so staging and production run byte-identical code. When the public website moved onto the platform, its news page went from over 3 seconds to about half a second.
“Five years ago, before this whole crazy system I set up, it would be days of work to get a website online.”
- apps deployed by Flux
- ~53
- automated image policies
- 102
- faster public website
- 6×
Brian: Every production release can be undone. The backup finishes before the release can even start.
job 09 · safety-net · protect
A safety net under every release
Publishing a release first takes blocking backups of the app’s databases and volumes and records a MongoDB point-in-time restore point. Only then does the production image tag exist, so Flux has nothing to deploy until the safety net is in place.
Backups land in encrypted S3 — 30 daily, 13 weekly and 12 monthly — and a restore is a reviewed pull request, applied exactly once.
- MongoDB recovery point
- 10 min
- of backup history
- ~1 yr
- to restore a database
- $0.004
Brian: I own security patching for the fleet. A critical CVE is a same-day job, not a ticket.
job 10 · security · always
Patched before it’s a problem
Dependabot keeps our repos current — Terraform providers, GitHub Actions, Docker base images, and npm, Bun, Go and Python packages — and a Claude skill I wrote triages the backlog into merge, verify, investigate or hold, in the order to land them.
Trivy scans three layers: the Terraform on every pull request, every image the pipeline builds, and what is actually running in the clusters. CodeQL and lint gates run in the shared workflows, and third-party actions are pinned to commit SHAs.
When node2shell (CVE-2026-111497) hit in October 2026, I checked every app’s Node version and had a verified fix (Node 24 LTS plus the outstanding npm findings) in under three hours, staging first. This site builds on that release too.
- layers scanned by Trivy
- 3
- ecosystems kept current by Dependabot
- 8
- node2shell: triage to verified fix
- < 3 h
Brian: If a disk, a node or a database starts going bad, I want to hear about it before anyone else does.
job 11 · observability · every minute
Watching the whole fleet
The monitoring stack is defined in FluxCD like everything else: Prometheus, Alertmanager and Grafana, with Loki collecting the logs. I wrote most of it — 67 of the 93 commits — and Grafana signs in with our single sign-on.
On top of the stock rules sit 72 of my own: database health (no primary, replication lag, WAL archiving, failed or stale backups, volumes filling), HPC hardware (SMART and NVMe wear, ECC memory errors, temperatures, OOM kills), certificates, and storage. Alertmanager routes them by component to the right Slack channel, labeled with the cluster they came from.
- custom alert rules
- 72
- database alerts
- 25
- HPC hardware alerts
- 24
Act IV
Research platform
Tools that let scientists — and accountants — ship.
Brian: Sequencing data is huge, and most of it goes cold. Cold data shouldn’t cost hot-data prices.
job 12 · data · 2026
Data at scale on a nonprofit budget
Research data lives on JuiceFS Community Edition — free — backed by S3 Intelligent-Tiering, with SMB and S3 gateways so people use it like any other share.
We’re moving ~316 TiB off our scale-out filer and ~100 TiB off flash this way, and have already reclaimed ~76 TB of primary storage.
- Day 0$1,210 / month
50 TiB lands in the frequent-access tier, cached on-prem for speed.
- Day 90$217 / month
Untouched objects slide into the archive tier automatically.
- Day 180$83 / month
Deep archive: 93% cheaper than day one, still one recall away.
- cheaper after 180 days
- 93%
- files on JuiceFS
- ~3.8M
- primary storage reclaimed
- ~76 TB
Brian: Scientists shouldn’t have to fight their laptop to do science.
job 13 · coder · 2026
Coder: one research platform instead of two
I built BRI’s research computing platform on open-source Coder, running on our own Kubernetes. One click gives a scientist a workspace with Positron, VS Code, Jupyter and Claude Code, up to 48 cores and 360 GB of RAM on HPC nodes, their data shares mounted, and their own identity and file permissions.
Snakemake and Nextflow fan jobs out across the cluster, and a shared renv cache makes R package installs near-instant. It replaced both our Posit Workbench license, retired in June 2026, and Slurm, decommissioned the same year. Long job? Prefix it with slackme and Slack pings you when it’s done.
- in licenses
- $0
- workspaces
- ~52
- cores · GB per workspace
- 48 · 360
Brian: AI is only useful at a research institute if it’s reproducible and can’t leak anything.
job 14 · claude-skills · 2026
Claude Code skills, delivered to every scientist
I built BRI’s Claude Code plugin marketplace and ship it to every Claude install through managed settings: it auto-updates, and no token or secret ever touches a laptop.
The CI/CD plugin packs 14 skills and two read-only Kubernetes MCP servers that take an app from source to production the BRI way. Analysis skills give scientists reproducible workflows: saved code, pinned environments and notes for every step.
- No secret value is ever exposed to the agent.
- Production is never touched implicitly.
- Patient data never goes to the model.
- skills in the CI/CD plugin
- 14
- secrets on disk
- 0
- read-only cluster MCP servers
- 2
Brian: The real test of a platform: someone outside IT ships on it.
job 15 · one-afternoon · Sept 2026
From idea to production in one afternoon
A colleague in accounting — not an engineer — used the plugin to put a real app into production. It went through the same guardrails as every app: an isolated workspace, secrets the agent never sees, a scanned image, pull requests for every change, and a backup before release.
Their second app followed a few weeks later.
- 14:56Plugin installed
The BRI CI/CD plugin, from the marketplace, in Claude.
- 15:48Deploy PR opened
Container, pipeline, secrets and GitOps manifests, generated and reviewed.
- 16:14Live on staging
Built once, scanned, rolled out and verified by the pipeline.
- 16:34Live in production
Backed up, promoted by retag, rollout verified.
- pull request → production
- 46 min
- plugin install → production
- 1h 38m
- apps shipped by accounting
- 2
Act V
Software I write
Not just infrastructure — the apps, too.
Brian: Remember those 2019 lifecycle scripts? They grew up.
job 16 · humani · 2024 – 2026
Humani: HR & payroll integrations
Since 2024 I’ve rebuilt BRI’s employee-lifecycle automation as Humani, a TypeScript platform that keeps employee data in sync between HR/payroll, benefits, retirement and finance systems: scheduled jobs, PGP-encrypted vendor files over SFTP, remit reports, and one payroll digest instead of an email per job. I’ve written 649 of its ~670 commits.
- PostgreSQL migration (v5.0): SQLite to PostgreSQL 16 on our Kubernetes operator, with a one-time copy verified before it commits, a reverse copy for rollback, and a golden-file harness that replays a synthetic HR feed through the old and new versions to prove the vendor files come out identical. SSNs, bank details and I-9 fields are encrypted at the column level.
- UI redesign: a digest-style interface built around what people actually use: a GL converter home page, jobs grouped by what needs attention, and per-job history with every file sent, archive copies, remit reports, notes and an audit trail. API calls are now type-checked end to end.
- lines of TypeScript
- ~40K
- of ~670 commits
- 649
- golden-file differences
- 0
- TypeScript
- React 19
- tRPC 11
- TanStack Query
- Chakra UI
- Express 5
- Drizzle
- PostgreSQL 16
- Entra ID
Brian: Before you delete 300 TiB, you’d better be sure there’s a copy. Two, actually.
job 17 · dater · 2026
dater: a catalog and mover for genomics data
dater catalogs every file tree across five storage platforms in Postgres — built for tens of millions of rows — and answers “where is this project’s data?” instantly.
Then it moves data the safe way: Kubernetes jobs spread one per node with live progress and bandwidth limits, every byte hashed on both archive copies, a mandatory dry run, and a second person’s approval before anything risky is deleted. Along the way it found 41 TiB of duplicate files.
- lines of Go + TypeScript
- ~100K
- Go test files
- 110
- of duplicates found
- 41 TiB
- Go
- Bun
- TypeScript
- PostgreSQL
- Kubernetes Jobs
- Entra ID
Act VI
Impact
What it all adds up to.
Brian: A nonprofit’s dollars belong to the science. I spend them like they’re mine.
job 18 · savings · every year
The savings ledger
Most of what I build runs on open source and hardware BRI already owns. When we do pay, we pay for exactly what we use.
How these numbers were worked out
- Shared research filesystem: JuiceFS Community Edition instead of JuiceFS Enterprise, $2,048/month minimum tier
- The vendor’s enterprise tier starts at $2,048 a month for 100 TiB, plus AWS costs (August 2026).
- Cold genomics data: S3 Intelligent-Tiering with archive tiers instead of Frequent-access S3 prices forever
- Per 50 TiB: $1,210 a month on day one, $83 a month after 180 days (BRI’s cost model, September 2026). Grows with every TiB moved.
- Research IDE platform: Coder Community on our Kubernetes instead of Posit Workbench license
- The Posit Workbench contract was not renewed in June 2026; Coder Community is open source.
- CI build minutes: Self-hosted runners on our cluster instead of GitHub-hosted minutes and overages
- Self-hosted runner minutes are free; hosted Linux runners list at $0.006–$0.022 a minute (GitHub, October 2026).
- Kubernetes control planes: Kubespray on hardware BRI owns instead of Managed Kubernetes, billed per cluster-hour
- Four clusters on owned hardware, no per-cluster-hour charges.
- Primary storage capacity: Reclaiming it with verified moves instead of Buying more flash and scale-out disk
- About 26 TB on flash and 50 TB on the scale-out filer, October 2026.
- Database backups: Encrypted S3 with archive classes instead of A backup appliance or SaaS
- About 20 cents a month per site, and $0.004 to restore a database.
Savings ledger
Benaroya Research Institute
| Item | Saves |
|---|---|
| Shared research filesystemJuiceFS Community Edition | $24.6K / yr |
| Cold genomics dataS3 Intelligent-Tiering with archive tiers | $13.5K / yr per 50 TiB |
| Research IDE platformCoder Community on our Kubernetes | License retired |
| CI build minutesSelf-hosted runners on our cluster | $0 / minute |
| Kubernetes control planesKubespray on hardware BRI owns | No cluster fees |
| Primary storage capacityReclaiming it with verified moves | ~76 TB reclaimed |
| Database backupsEncrypted S3 with archive classes | ~$0.20 / site / mo |
| Verified, per year | $38,100+ |
Lines without a dollar figure aren’t counted in the total.
Brian: If it has a power cable, a login, or a deploy button at BRI, I’ve probably had a hand in it.
job 19 · many-pies · every day
Fingers in many pies
Beyond the platform, I’m who people find when something crosses team lines: networking and VPN, storage and disaster recovery, identity and single sign-on, HR and finance automation, the public website, and dozens of research apps.
- Networking
- Load balancers, VPN, guest Wi-Fi, DNS
- Storage & DR
- Filers, JuiceFS, S3, warm standby
- Research computing
- HPC nodes, Coder, pipelines
- Identity
- Single sign-on, key vaults, per-person cluster identities
- Security
- Dependabot, Trivy at every layer, same-day CVE patches, patient-data guardrails
- HR & finance
- Humani, employee lifecycle, payroll files
- Web
- The public website on Kubernetes, 6× faster
- Research apps
- ~53 apps through one pipeline
- Observability
- Prometheus, Grafana, Loki and Alertmanager → Slack
- AI
- Claude Code plugins, Claude in Coder
pipeline complete · run time 10y 4m
Side projects
Things I build for fun
Same habits, different stakes: measure honestly, keep the model on a short leash, and make the undo button real.
Sleeper Draft Assistant
A live fantasy-football draft assistant that follows a Sleeper draft in real time.
It tracks who is gone and what your roster still needs, then puts three to five recommendation cards in front of you. TypeScript does the value math; Claude only writes the cards from a pre-scored shortlist, which keeps it cheap and the numbers reproducible. 300 offline tests.
- Bun
- TypeScript
- Hono
- Zod
- Claude API
Quiesce
Pre-releaseA true Windows game mode: quiet the background, then put everything back exactly as it was.
It quiets the apps, services and Windows bloat a gaming session doesn’t need and restores the machine from a crash-safe journal written before every change. Honest by design: every tweak carries an evidence label, and there is no FPS counter because it doesn’t measure frames.
- .NET 10
- C#
- WPF
- xUnit
Mariners 2026
What bioinformatics in a Coder workspace feels like, told with baseball stats.
Heatmaps, volcano plots and PCA on live Seattle Mariners data, built to show researchers Coder and Positron. A daily GitHub Actions job re-renders the Quarto site after game days and deploys it to Vercel.
- R
- Quarto
- Shiny
- renv
- GitHub Actions
- Vercel
TL;DR
Résumé
Ten years at Benaroya Research Institute, from the helpdesk to designing the platform its research runs on: infrastructure as code, GitOps delivery, research computing and AI tooling, built mostly on open source and hardware the institute already owns.
Experience
DevOps Engineer · Benaroya Research Institute
2020 – Present · Seattle, WA
- Designed and led BRI’s infrastructure-as-code platform: Packer images, Terraform (26 state roots, ~600 resources, 24 providers), Ansible/AWX, and four Kubernetes clusters (46 nodes) on owned hardware.
- Built the GitOps delivery path: FluxCD for ~53 apps, build-once / promote-by-retag releases with blocking backups and verified rollouts, and self-hosted CI runners on Kubernetes at $0 a minute.
- Own security patching across the fleet: Dependabot on every repo; Trivy on IaC, images and the running clusters; CodeQL gates; node2shell (CVE-2026-111497) went from triage to a verified fix in under three hours.
- Built the observability stack in FluxCD (Prometheus, Grafana, Loki, Alertmanager) with 72 custom alert rules for databases, HPC hardware, certificates and storage, routed to Slack.
- Built the research computing platform on open-source Coder (~52 workspaces, up to 48 cores / 360 GB), replacing a Posit Workbench license and Slurm.
- Cut cold-storage cost 93% with JuiceFS Community on S3 Intelligent-Tiering, avoided ~$24.6K a year in enterprise licensing, and reclaimed ~76 TB of primary storage.
- Created BRI’s Claude Code plugin marketplace (org-wide, zero secrets on disk); a non-engineer shipped a production app in one afternoon — 46 minutes from pull request to production.
- Wrote Humani (~40K lines of TypeScript; HR and payroll integrations; PostgreSQL migration proven with golden files) and dater (Go + TypeScript genomics data catalog and mover).
Helpdesk Technician · Benaroya Research Institute
Jun 2016 – 2020 · Seattle, WA
- Supported every lab and department: imaging, firmware, accounts and access.
- Automated the repetitive work with PowerShell modules for directory, mail, file sharing, virtualization, HR and procurement, and an employee-onboarding command that built Linux hosts through Ansible.
Skills
- Infrastructure as code
- Terraform · Ansible · AWX · Packer · vSphere
- Containers & GitOps
- Kubernetes (Kubespray) · FluxCD · Helm · Docker
- CI/CD & security
- GitHub Actions · Self-hosted runners · Trivy & Trivy Operator · CodeQL · Dependabot
- Cloud, storage & data
- AWS S3 · Azure Entra ID & Key Vault · JuiceFS · PostgreSQL · MongoDB · Velero
- Languages
- TypeScript · Go · PowerShell · Bash · HCL · C# · R
- Research computing & AI
- Coder · Snakemake · Nextflow · renv · Claude Code plugins · MCP servers
- Observability
- Prometheus · Alertmanager · Grafana · Loki · Zabbix