Projekt

Arkitektur & utveckling

princelundgren.com

Min portfölj — jag har designat och byggt varje lager själv, från frontend till molnet den körs på.

AstroTypeScriptAWS CDKCloudFrontS3 (OAC)ACMRoute 53GitHub Actions
Besök princelundgren.com 
princelundgren.com
Skärmbild av princelundgren.com
Problem
Jag ville att min portfölj skulle vara lika omsorgsfullt gjord som arbetet den visar — en snabb, handbyggd sida, inte en mall — som körs på infrastruktur värd att visa upp. Den serveras från ett dedikerat arbetskonto medan DNS-zonen för princelundgren.com ligger i ett separat konto, utan några manuella DNS-steg och inga långlivade autentiseringsuppgifter någonstans.
Tillvägagångssätt
Frontend är ett statiskt Astro-bygge — ett eget designsystem, en illustrerad SVG-hjälte och praktiskt taget noll klient-JavaScript — utrullat på ett litet antal AWS CDK-stackar. Kontoövergripande DNS automatiseras genom en hårt avgränsad antagen roll, och ACM-certifikatet ägs av en provider-framework-Lambda (ett vanligt CloudFormation-certifikat låser sig när dess valideringsposter ligger i ett annat konto). CloudFront står framför en privat S3-bucket via Origin Access Control, med HTTP/3, en strikt säkerhetsheader-policy och standardloggning v2. CI rullar ut via GitHub OIDC — inga lagrade nycklar — med en tvåpass-cachestrategi och avgränsad invalidering.
Resultat
En sida som når rena 100 på Lighthouse för desktop (98–100 på strypt mobil) och levererar noll klient-JavaScript bakom en upprätthållen CSP. Under huven — handsfree certifikatförnyelse, CA-låst utfärdande, helt automatiserade OIDC-utrullningar och cdk-nag-ren infrastruktur med enhetstester på sina säkerhetsegenskaper — hela arkitekturen beskriven som ett portföljarbete i sig.

Den här sidan är sin egen fallstudie, i två halvor: en snabb, handbyggd frontend, och den kontoövergripande AWS-infrastrukturen den körs på. Frontend fick förtjäna sin plats — byggd för hand, inte från en mall — och plattformen hade ett specifikt uppdrag: servera apex-domänen princelundgren.com från ett dedikerat arbetskonto medan Route 53-zonen ligger i ett separat, automatiserat hela vägen utan långlivade autentiseringsuppgifter.

Själva sidan

Det är en handbyggd, statisk Astro 6-sida — ingen ramverks-runtime, ingen sidbyggare, och noll klient-JavaScript. Till och med den illustrerade hjälten — jag vid ett skrivbord av moln, drönare och en 3D-skrivare — är handritad SVG, animerad med CSS.

Utseendet är ett litet eget designsystem — varmt papper och bläck, en enda accent, en display-serif, en pappersstruktur och en orkestrerad sidladdningsreveal — så att det känns gjort, inte genererat. Tillgänglighet är inbyggd, inte påklistrad: varje textfärg är avstämd mot tydlig WCAG AA-kontrast, med en hopplänk, synliga fokusringar, stöd för reducerad rörelse, semantiska landmärken, metadata per sida, genererade Open Graph-kort och strukturerad data. (Prestanda och säkerhet får egna avsnitt nedan.)

Under huven

Det uppdraget är svårare än det låter. En apex-domän kan inte delegeras till ett annat konto på samma sätt som en subdomän kan. Så arbetskontot måste skriva ett par poster i en zon det inte äger: ACM-valideringsposterna, och apex-/www-aliasposterna som pekar mot CloudFront. Det rena sättet att överbrygga det är en enda, hårt avgränsad IAM-roll i DNS-kontot som arbetskontot antar — som kan ändra poster i exakt en hostad zon och ingenting annat.

Certifikatet är den vassa kanten. En CloudFormation-Certificate-resurs blockerar tills den är validerad, men du kan inte läsa dess valideringspost förrän den finns, och den posten måste hamna i det andra kontot — ett dödläge. Så certifikatet ägs av en liten provider-framework-Lambda som driver livscykeln över SDK:n: begär → skriv valideringsposterna kontoövergripande → polla tills utfärdat → städa upp vid radering. Inget dödläge, och förnyelser är handsfree för alltid efteråt.

Prestanda

Rena 100 på Lighthouse för desktop, och 98–100 på strypt mobil (Slow-4G + 4× CPU). Poängen är en bieffekt av bygget, inte ett jagat tal:

  • Noll klient-JavaScript → en Total Blocking Time på 0 ms. Det finns ingen ramverks-runtime att hydrera; de enda inline-skripten är JSON-LD-datablock.
  • Cumulative Layout Shift på 0 — självhostade typsnitt (förladdade för paret ovanför vikningen, latinsk delmängd, med metriska fallbacks) och dimensionerade bilder gör att inget flödar om när sidan landar.
  • Första rendering under en sekund — Brotli över HTTP/3, hashade tillgångar cachade oföränderligt medan HTML revalideras, levererat av en tvåpass-s3 sync.
  • Den illustrerade hjälten är inline-SVG, så det finns ingen bild att hämta — den målas med sidan. (Det enda strypt mobil anmärker på är Speed Index, när den detaljerade scenen rastreras.)

Säkerhet

Säkerhet behandlas som ett produktkrav — upprätthållet vid kanten, verifierat i CI:

  • Privat origin — S3 blockerar all publik åtkomst; CloudFront når den bara genom Origin Access Control, och signerar varje origin-förfrågan.
  • Strikt transport — endast HTTPS på TLS 1.2 (2021-policy), med HSTS i två år, includeSubDomains + preload (inskickad till webbläsarnas preload-lista).
  • CA-låst utfärdande — en CAA-post så att bara Amazons CA:er någonsin kan utfärda ett certifikat för domänen.
  • Upprätthållen CSP (script-src 'self') plus X-Frame-Options: DENY, X-Content-Type-Options, en strikt Referrer-Policy, och en Permissions-Policy som stänger av kamera, mikrofon och geolokalisering — allt från en CloudFront response-headers-policy. En enda kantfunktion sköter www→apex-omdirigeringen, snygga URL:er och språkdetektering vid första besöket.
  • Inga långlivade autentiseringsuppgifter — CI autentiserar via GitHub OIDC; kontoövergripande DNS är en enda least-privilege-antagen roll, avgränsad till en handfull postnamn och -typer och ingenting annat.
  • Kvitton — en /.well-known/security.txt för disclosure, standardloggning v2, en cdk-nag-ren synth, och enhetstester som verifierar de bärande säkerhetsegenskaperna.