After the internship converted into a full role, the work became infrastructure and nothing else. Over roughly eight months I was responsible for the AWS infrastructure of seven production platforms the company built for its clients, provisioning it and then maintaining it once it was running. For most of them I designed the architecture as well; the largest was the exception, and an important one: a ministry’s AWS landing zone of three workload accounts, whose design came from an AWS principal architect, which I provisioned and then evolved rather than drew. I’ll come back to it. Either way, that maintaining 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. One of the fullest was a 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.
The largest single engagement here wasn’t one I designed, but it was one I built. A government ministry’s environment was an AWS landing zone with three workload accounts, and those workload accounts were where I worked. The architecture arrived as a diagram: a draw.io from an AWS principal architect, with the zone’s foundation provisioned by my senior solutions architect. Everything below that diagram was mine to write. I authored the infrastructure-as-code for all three workload accounts myself, turning the drawing into running infrastructure, and then evolved it as the application teams came back with requests that fell within the approved scope, each change signed off by the same senior SA. I didn’t draw the architecture and I won’t claim I did; but designer and builder are different jobs, and on the biggest thing I touched here I was the builder, front to back. That’s the distinction I’d rather draw plainly than let the diagram’s authorship and the code’s authorship blur into one.
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["ministry landing zone: 3 workload accounts vpc · alb · ec2 asg · cloudfront+waf draw.io by aws principal architect · iac + evolution mine"] 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
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. On most of these platforms I was working greenfield (no platform team to absorb a mistake, no shared landing zone already built, no reference architecture to consume) and not much of the scale that makes those things necessary. The ministry landing zone was the exception on every count: a principal-architect design, a zone my senior SA had already stood up, application teams to answer to. It’s the one place here where I was building inside someone else’s lines rather than drawing my own, and knowing the difference between those two jobs is part of what the role taught. The rest of it taught breadth: seven platforms in eight months means seven different sets of requirements landing on a shared 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.