Infrastructure as code (#3)

* Moves website to website/

* Adds terraform gitignores

* Terraform with AWS provider

* Initialises Terraform

* Locals and variables for provider

* Fetches SSL certificate from ACM

* S3 static website bucket

* CloudFront distribution

* Route53 records

* Deployment workflow uses secret S3 bucket suffix

* Adds README

---------

Co-authored-by: Joe Carstairs <65492573+Sycamost@users.noreply.github.com>
This commit is contained in:
Joe Carstairs
2024-05-05 21:00:40 +01:00
committed by GitHub
parent 579e12cfeb
commit 86450b3dd8
40 changed files with 293 additions and 3 deletions

View File

@@ -0,0 +1,44 @@
---
interface Props {
title: string;
description: string;
image?: string;
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const { title, description, image = '/images/headshot.jpg' } = Astro.props;
---
<!-- Stylesheets -->
<link rel="stylesheet" href="/css/reset.css" />
<link rel="stylesheet" href="/css/base.css" />
<link rel="stylesheet" href="/css/hcard.css" />
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />

View File

@@ -0,0 +1,76 @@
---
import type { CollectionEntry } from 'astro:content';
import { getCollection } from 'astro:content';
export interface Props {
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6,
hideAuthor?: boolean,
};
const { headingLevel = 2, hideAuthor = false } = Astro.props;
const posts = (await getCollection('blog'));
const distinctYears: number[] = posts
.map(post => post.data.pubDate.year)
.reduce<number[]>((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], [])
.sort((a, b) => b - a);
function matchesYear(year: number) {
return (post: CollectionEntry<'blog'>) => post.data.pubDate.year === year;
}
function sortByPubDateDescending(post1: CollectionEntry<'blog'>, post2: CollectionEntry<'blog'>) {
const year1 = post1.data.pubDate.year;
const year2 = post2.data.pubDate.year;
const month1 = post1.data.pubDate.month;
const month2 = post2.data.pubDate.month;
const day1 = post1.data.pubDate.day;
const day2 = post2.data.pubDate.day;
if (year1 !== year2) {
return year2 - year1;
} else if (month1 !== month2) {
return month2 - month1;
} else {
return day2 - day1;
}
}
const headingElem = `h${headingLevel}`;
const canonicalBlogUrl = new URL('blog', Astro.site)
---
<section class="h-feed">
<Fragment set:html={`
<${headingElem} class="p-name">
My blog
</${headingElem}>
`} />
<aside>
<p class={hideAuthor ? 'hidden' : ''}>
This blog is written by <a class="p-author h-card" href="/">Joe Carstairs</a>
</p>
<p>
<a class="u-url" href={canonicalBlogUrl}>Permalink</a>
</p>
</aside>
<ul>
{ distinctYears.map(year => (
<li>
{year}
<ul>
{ posts.filter(matchesYear(year)).sort(sortByPubDateDescending).map(post => (
<li class="h-entry">
<a class="u-url p-name" href={`/blog/${post.slug}`}>{post.data.title}</a>
</li>
)) }
</ul>
</li>
)) }
</ul>
</section>

View File

@@ -0,0 +1,21 @@
---
interface Props {
className?: string;
date: Date | string;
}
let { className, date } = Astro.props;
if (typeof(date) === 'string') {
date = new Date(date);
}
---
<time datetime={date.toISOString()} class={className ?? ''}>
{
date.toLocaleDateString('en-GB', {
year: 'numeric',
month: 'long',
day: 'numeric',
})
}
</time>

View File

@@ -0,0 +1,43 @@
---
---
<section class="h-card">
<img class="u-photo" src="/images/headshot.jpg" height="256" width="256" />
<div>
<h1>
<a class="p-name u-url u-uid" href="https://joeac.net" rel="me">
Joe Carstairs
</a>
</h1>
<p>
Hi! 👋 My name is <span class="p-given-name">Joe</span>
<span class="p-family-name">Carstairs</span>. Im a
<span class="p-job-title">software developer</span> at
<a class="p-org" href="https://www.scottlogic.com">Scott Logic</a>, a
graduate of Philosophy and Mathematics at the University of Edinburgh,
a committed Christian and a pretty rubbish poet.
</p>
<p>
Im also the <span class="p-job-title">secretary</span> of the
<a class="p-org" href="https://scotsleidassocie.org">Scots Language Society</a>.
<a href="https://github.com/joeacarstairs/lallans-wabsteid-astro">Help me maintain our website!</a>
</p>
<p>
Email me at
<a class="u-email" href="mailto:joeacarstairs@gmail.com">joeacarstairs@gmail.com</a>
with your thoughts on metaethics, Scots verse and eschatology.
</p>
<p>
Or get me on
<a href="https://www.facebook.com/joe.carstairs.5" rel="me">Facebook</a>,
<a href="https://mastodon.social/@joe_carstairs" rel="me">Mastodon</a>,
<a href="https://www.linkedin.com/in/joe-carstairs-0aa936277" rel="me">LinkedIn</a>,
or <a href="https://github.com/joeacarstairs" rel="me">GitHub</a>.
</p>
</div>
</section>