notable work
CASE 07 · AN AWS-PARTNER SOFTWARE HOUSE sole infrastructure author · 2024-07 → 2025-02

The client changes, the skeleton doesn't

5 min read
cloudformationnested stacksvpccloudfrontwafaurorards proxyaws backupiam
cloudformation nested stacks vpc cloudfront waf aurora rds proxy aws backup iam

After the internship converted into a full role, the work became infrastructure and nothing else. Over roughly eight months I was the author of the AWS infrastructure for seven production platforms the company built for its clients — designing the architecture, provisioning it, and then maintaining it once it was running. That last part matters more than it sounds. These weren’t hand-offs. The platforms stayed live, and staying live is a different job from standing something up.

Everything was hand-written CloudFormation YAML. No Terraform yet, no console clicking, no template wizard output.

One pattern, seven cuts

Every multi-stack platform ran the same shape: a root main.yaml composing S3-hosted child templates through AWS::CloudFormation::Stack, with !GetAtt carrying outputs between them — VPC subnet and security-group IDs into the compute and load-balancer stacks, the IAM instance profile into compute. No child stack ever held another child’s resource IDs as literals. The reasoning behind that constraint, and what it buys you, is documented as its own system elsewhere in this set.

What varied was how much of the graph a given platform actually needed. The largest was a full public-facing web platform: nine child stacks covering VPC, an autoscaling EC2 tier behind an ALB, CloudFront with a WAF web ACL in front of it, a Cognito user pool with custom schema attributes, three DynamoDB tables, SES for outbound mail, and an OpenSearch domain deployed inside the VPC rather than exposed publicly.

That one was the document repository I had built by hand during the internship a few months earlier — the same platform, re-expressed as templates. Codifying a system I’d personally clicked into existence is a specific and useful kind of exercise: every resource in the graph was one I could remember creating, so the gap between “it works” and “it is reproducible” was impossible to hand-wave. Nothing teaches the value of a template faster than writing one for infrastructure you built the other way first. That system’s own story, including the part of its architecture that didn’t survive to deployment, is CASE 06. The smallest was a single IAM stack — groups, policies, and users provisioning access to an HPC environment — built with the same templated rigour as the big one, because ad-hoc IAM is how access sprawl starts.

Between those two ends sat the specialist work: a three-instance Aurora cluster behind an RDS Proxy with its own subnet group, so connection pooling was a design decision rather than a later rescue; AWS Backup codified as vault, plan, selection, and service role, making DR a template rather than a runbook; a WAFv2 web ACL split into an independently deployable stack; and private connectivity built from five interface VPC endpoints plus an EC2 Instance Connect Endpoint, which removed the SSH jump box from the architecture entirely instead of hardening it.

flowchart TB
pattern["shared pattern — root main.yaml
s3-hosted children · !GetAtt wiring"]
subgraph full["full platforms"]
  a["9-stack web platform
  vpc · asg+alb · cloudfront+waf
  cognito · dynamodb · opensearch · ses"]
  b["3-tier web workload
  vpc · alb · ec2 asg · cloudfront+waf"]
end
subgraph slice["single-concern platforms"]
  c["aurora cluster + rds proxy"]
  d["aws backup — vault · plan · selection"]
  e["wafv2 web acl"]
  f["vpc endpoints + eice — no bastion"]
  g["iam groups/policies for hpc"]
end
pattern --> a & b & c & d & e & f
pattern -.->|"same rigour, no nesting needed"| g
as built — one root-stack pattern, re-cut across seven production platforms

Production ownership at a smaller scale

This was real production with real users on it, and it was smaller than what came after. Both of those are true and worth stating together, because the temptation with a first infrastructure role is to describe it in the vocabulary of the later ones. There was no platform team here to absorb a mistake, no shared landing zone already built, and no reference architecture to consume — but there also wasn’t the scale that makes those things necessary. What the role actually taught was breadth: seven platforms in eight months means seven different sets of requirements landing on the same pattern, which is a faster way to find out where a pattern breaks than running one system for years.

What survives, and what doesn’t

The delivery repositories lived on the company’s Bitbucket and I lost access to them when I left. What exists now is an extraction — my own authored templates, pulled into a private personal repository across sixty commits between July 2024 and February 2025, with client values and account data stripped out.

So the template content is first-hand evidence of the design work, and the dates are not evidence of delivery — they record when I preserved a template, not when the platform shipped. The per-platform commit split was never tracked. Every date attached to this period is approximate, and I’d rather say so than present a preservation timestamp as a delivery milestone.

filed as CASE 07 · notable work