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å.
Besök 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
Workload account
DNS account
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') plusX-Frame-Options: DENY,X-Content-Type-Options, en striktReferrer-Policy, och enPermissions-Policysom stänger av kamera, mikrofon och geolokalisering — allt från en CloudFront response-headers-policy. En enda kantfunktion sköterwww→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.txtför disclosure, standardloggning v2, en cdk-nag-ren synth, och enhetstester som verifierar de bärande säkerhetsegenskaperna.