One application, two clouds, two architectures
The app on this site, deployed twice under opposite constraints: on AWS behind an on-premises Palo Alto firewall for the final project, then rebuilt as a single hardened host on Oracle Cloud once the job changed from proving an architecture to running a site.
The application on this site has been deployed twice, and the second deployment is the more interesting one, because almost nothing carried over.
The first was the final project: four AWS accounts, the app on ECS Fargate in private subnets with no NAT gateway in its path, every route hairpinned through an on-premises Palo Alto firewall for App-ID policy, decryption and logging, and users pushed in from Entra ID over SCIM with no AWS passwords. That architecture existed to prove something. Once the numbers were in it was torn down on purpose, because the cost story only works if it is torn down.
What runs now had a different brief: keep the same application online indefinitely, on a free tier, with no appliance in front of it and no budget to replace one. So the controls moved rather than disappeared. Traffic is served through Cloudflare, which terminates TLS at the edge. The origin's address is never published. The host accepts web traffic from Cloudflare's network and nowhere else, enforced twice, once in the provider's network rules and again in the host's own firewall rules, because sooner or later one of the two gets edited by hand. Administrative access is restricted to a single address. Every asset that can change carries a content hash in its address, and the page naming them is never cached, so a purge and a fresh browser always show the current site.
Neither architecture is the better one. The constraints were different and the architecture changed with them, and being able to say which control is doing which job in each of the two is what the pair is evidence of.
What I would do differently: put the record in before the site went public, not after. An early outage came from starting the maintenance job by hand while a rebuild was already running, and ten minutes later nothing could prove it had happened; the job had been writing a careful log straight to nowhere. Now every restart, outage and scheduled run is written down.