Overview
You're looking at the result. This site started on Firebase Hosting and now runs
entirely on AWS. Static files live in a private S3 bucket that is never publicly
accessible; CloudFront serves them over HTTPS using an ACM certificate and reads
from the bucket through Origin Access Control. DNS is hosted in Route 53, with an
alias record pointing the domain at the distribution. The visitor counter is
serverless: page JavaScript calls a Lambda function URL, which increments and
returns a count stored in DynamoDB.
The migration had zero downtime. Because my registrar, Squarespace, can't point a
root domain at CloudFront, I first moved DNS to Route 53 by mirroring the existing
records into a new hosted zone and switching nameservers while Firebase was still
serving the site. Only after the CloudFront distribution was fully tested did I
switch the record over.
What broke
Two problems taught me the most. Certificate validation stayed pending because the
validation records had never been created; adding them to Route 53 fixed it within
minutes. Then CloudFront returned AccessDenied: my files sat under a
public/ prefix while CloudFront was requesting the bucket root, and
S3 reports missing objects as AccessDenied rather than "not found", so it looked
like a permissions problem. Setting the origin path to /public solved
it. I confirmed the cutover through response headers: server: AmazonS3
and x-cache moving from Miss to Hit.
Infrastructure as code & CI/CD
The entire stack — S3 bucket, CloudFront distribution, ACM certificate, Route 53
records, Lambda function and DynamoDB table — is defined in Terraform. Every push to
the main branch runs a GitHub Actions pipeline that syncs the site to S3, invalidates
the CloudFront cache and deploys the Lambda, authenticating to AWS through OIDC
rather than stored access keys.
Resume
Software engineer with 5+ years of experience (TypeScript, Node.js, Angular) moving into
cloud engineering. I build and deploy on AWS with Terraform and CI/CD, and work across
frontend, .NET APIs and Azure DevOps pipelines in production.
Professional Experience
Software Engineer
06/2024 – Present
Aptean · Wrocław, Poland
- Coordinate versioned releases of 4 interdependent projects on Azure DevOps: version bumps, git tags, pipeline runs and dependency-ordered deploys.
- Fixed a deployment issue where Keycloak kept running a stale image by adding a pipeline stage that restarts its pods on AKS (Azure Kubernetes Service) after each build.
- Own remediation of
npm audit failures in CI: investigate advisories and apply upgrades to keep pipelines unblocked without breaking builds.
- Upgraded an Nx monorepo from Angular 14/16 to 21, combining Nx migrations with manual refactoring of 20+ files.
- Extend .NET (C#) REST APIs and build the matching Angular features for MES/ERP software: entity catalogues, hierarchical trees, audit questionnaires and rating systems.
Software Engineer
07/2023 – 05/2024
Providius · Ontario, Canada (remote)
- Built a real-time telemetry dashboard for Disney operations using WebSockets and RxJS, rendering hundreds of live data points with <3s anomaly detection.
- Wrote runbooks and onboarding documentation that reduced new-hire ramp-up time by 30%.
- Built a reusable component library meeting WCAG 2.1 AA accessibility standards.
Web Developer II
01/2020 – 01/2023
Q4 Inc. · Toronto, Canada
- Delivered 40+ high-traffic investor-relations websites for clients including Shopify and BlackRock, meeting accessibility requirements.
- Built reusable TypeScript widgets consuming REST and GraphQL APIs, reused across all site templates.
GitHub repo ↗