
Building a static serverless website using S3 and CloudFront - SanderKnape
https://sanderknape.com/2020/02/building-a-static-serverless-website-using-s3-cloudfront/
======
Thorentis
I don't work for them or anything, but I've honestly found Netlify to be the
absolute easiest solution for static site hosting. And it's free! There are
some paid features, but the free stuff is all you need. You can use SSL,
accept form inputs through request capturing, automate deployments with
Github/Gitlab hooks, auto generate static pages for most popular static site
generators (Jekyll, Hugo, etc.) Absolute breeze to use. Beats any hacky AWS
solution hands down imo.

~~~
shadowprofile77
Maybe an overly simple and dumb question but have to ask: What's the big
difference between hosting static sites on services like these and just going
with a regular webhost like Bluehost and slapping in something like a
wordpress template? This is what a lot of blogs, landing pages and even fairly
static small business or organization sites seem to do without problems and
it's all pretty user.friendly for the non-developer crowd (me included)

~~~
michaelt
People have been coming up with solutions to the 'make a basic business
website' problem since the 90s, when Microsoft FrontPage, Macromedia
Dreamweaver and NetObjects Fusion fought it out, and computer magazines would
mail out their entire website on the CD on the magazine's cover, for readers
without web access.

At this point, there are a great many ways to skin a cat.

Assuming you've got $5 a month or so, it mostly comes down to personal
preferences about workflow, vendor independence, security, reputation, and who
you already have an account with.

~~~
shadowprofile77
I asked below but no answer, so hopefully not bothering but I ask again here.
Any solid guide or resource you could recommend on doing just this, building a
static site with these services while not using wordpress and typical hosting
services like bluehost etc.

------
superkuh
This is hilarious. All this complicated and unneeded stuff for a static
website. It completely misses not just a point but multiple points.

Maybe you want a static sites so that it'll 'live' forever and not be effected
by future changes in software stacks. You definitely don't get that by doing
this.

Maybe you want a static site so that it's simple to set up. It's not this.

Maybe you want a static site for security, all the complexity and accounts
here make it less secure than a random site running random php.

This is just buzzword bingo for someone's resume.

~~~
joeyspn
Hmm you conveniently omitted comments about HA, latency or scalability...
Pushing a bundle of files to a CDN it's undeniably a superior static site/SPA
hosting in many ways.

Maybe the article overcomplicates but with services like Netlify, Amplify or
Firebase Hosting it's stupid easy and cheap, and there's no vendor lock-in.

------
ehonda
Host a static website the HN way:

1\. Buy the cheapest most unsustainable VPS ipv4 deal out there.

2\. Make A record and WWW record and point domain to your new fangled server.

3\. Configure server:

apt-get install nginx goaccess

cd website

cp * /var/www/html

Yearly maintenance required: apt-get update, apt-get upgrade

reboot

View traffic stats: goaccess -f /var/log/nginx/access.log

~~~
iudqnolq
Serious question: how much more maintenance is required? Could I get away with
unattended-upgrades and nginx+wsgi+PostgreSQL?

I ask because actual servers seem like dark magic to me so I want to try to
build a product with them, but I can't find anywhere if it's possible to run a
reasonably secure server without years of studying.

~~~
geofft
If you're serving static content, installing Apache, nginx, or any other web
server will do just fine. Make sure to set the document root to a directory
you're fine being public.

If you're running something dynamic like WordPress, stay extremely on top of
patches, unfortunately, and be super cautious about what plugins you use.
(This is one of the better reasons to use a static website.)

If you want to run a Postgres for your dynamic website, configure it to listen
only to localhost or only via UNIX sockets.

Make sure you keep your software up-to-date. unattended-upgrades is a great
idea for OS-provided software.

Be careful about where you get software from. More than just "get it from
somewhere trustworthy," the big concern here is to get it from someone who is
applying software updates. For most OS-ish things, you want to get them from
your distro; try to avoid downloading e.g. PHP from some random website,
because you won't get automatic updates. For a few things - especially things
like WordPress - I wouldn't trust the distro to keep up, largely because the
common practice is to release security fixes by releasing new versions, and
distros are going to want to backport the fixes, which is slower and not
always guaranteed to work.

As another commenter mentioned, turn off remote password logins and set up SSH
keys. (Most VPS providers will have some form of console / emergency access if
you lose access to your SSH keys.)

~~~
cmroanirgo
I run my sites, all static on a VPS, but I do the authoring in a single multi-
site wordpress install and use 'Simply Static' plugin to publish the result.
The benefits are pretty awesome:

heaps of templates (because I'm often lazy), 1 stop shop for patches, locked
down plugins (child sites can't install plugins, only enable/disable), and
only one place to look for problems (& you can lock the wordpress site to a
single IP if you always want to use it from a single place).

FWIW, I never groked AWS & it's ping times in my country are about 1/2 as good
as local providers. (15-30ms for local, vs 50-100ms for AWS local). Speed
matters.

Also, my use case is to 'fall over' (meaning: fail/stop working/be
unresponsive) wrt DDOS, whereas I know many here are 'must not fail' (with
varying levels of acceptability). So, I write concise, low bandwith consuming
websites that appear instantly (to my local market users).

------
calvinmorrison
I would like to just mention that github does static site hosting for free. I
have used it for a few years. Never had a problem. Static, Free, probably not
going out of business in the next 5+ years, domain is my only cost.

~~~
JoshTriplett
True, but they reserve the right to prohibit sites that use up a non-trivial
amount of bandwidth, or that have commercial purposes, or various other
reasons.

It's a great service, but I wouldn't count on it as your primary hosting.

------
m82labs
I found s3 + cloudflare to be a better combo. Cloudflare offers free ssl certs
and has overall been a great experience. I also use AWS SES for my domain
mail. It gets delivered to S3, then a local python script grabs it and dumps
it in a mailbox file for dovecot to serve via imap. I pay $0.05/month for my
hosting of my site and email.

[https://markw.dev](https://markw.dev)

~~~
divbzero
I find your email setup intriguing. Any chance you could share those scripts
in a GitHub repo or gist?

~~~
mxie-ca
I have this set up couple years ago via this lambda function:
[https://github.com/arithmetric/aws-lambda-ses-
forwarder](https://github.com/arithmetric/aws-lambda-ses-forwarder)

It may look outdated, but it still functions well for me

~~~
m82labs
The big difference is my setup doesn’t require another email service. Just 10
lines in a config to spin up an imap server. I was trying avoid the big mail
providers when I set this up.

------
simonw
How is this so complicated? I shudder to think of the amount of developer
hours wasted by the weirdness and complexity of AWS. Really wish they would
prioritize usability and developer experience.

~~~
harryh
AWS's business isn't making simple things like this easy for solo
practitioners who are never going to spend any money.

Their business is making big complicated things possible for companies that
are going to spend a lot of money and don't care about a small amount of
incidental complexity.

~~~
touristtam
> Their business is making big complicated things possible for companies that
> are going to spend a lot of money and don't care about a small amount of
> incidental complexity.

While imposing technical limitations to extract more revenue along the way.

~~~
nostrebored
Could you share some examples?

------
rexreed
Can someone please provide practical advice on moving from a site hosted on
Wordpress using all the plugins to a static hosted site? It seems unbelievably
complicated.

My non-technical employees and partners like Wordpress. We like the plugins
that make web development easy and not arcane.

But we don't like the fact that every page requires basically a database read.
Yes, we use WP-SuperCache, and it's ok.

But why oh why is it so hard to do the editing on Wordpress and the publishing
on a Static site? Anyone with some real guidance here?

We want the people who come to the site to get the static experience while the
people who edit the site to get the Wordpress experience.

~~~
oconnore
In a previous life I worked on a site that had a private Wordpress instance
that was scraped and cloned to a more or less static site.

You can either do this explicitly using a small scraper tool, or implicitly
using aggressive reverse-proxy caching rules.

~~~
rexreed
Sounds pretty intensive. Every page would need constant scraping as links
update and sidebars change, wouldn't they?

~~~
oconnore
I think you might be overthinking it. Just drop cache after publishing.

Maybe you’re doing something more complicated that isn’t amenable to pseudo-
static?

------
dayjah
I’ve had to do this multiple times over the past two years. It’s always a
shock to me how hard it is.

The Lambda@Edge functions especially. They have 4 phases they can be injected
into: viewer-request, origin-request, origin-response, and viewer-response. If
you put your code in the wrong place you get hard to debug issues.
Additionally you cannot “annotate” a request, so a decision at say “viewer-
request” cannot pass information to later stages.

Also, deployments take 15 minutes at least which just further frustrates the
debugging process.

~~~
eastbayjake
This was actually one of my most delightful experiences with Azure Functions
and Microsoft's API Management solution - overhead does not make it the right
fit for every serverless architecture, but it did make orchestrating functions
in this way a lot easier

~~~
nostrebored
Thanks for this comment! I know what the next side tech I'll play around with
will be :)

------
meritt
It's amusing to me how programmers look back with disdain at web development
in the 90s and how "you just uploaded files to a FTP server" and now we've
circled back to the same thing, just with a whole lot more plumbing in the
middle.

~~~
awb
For me, Netlify is the right mix (I'm not affiliated with them). It has the
90s ease of use with modern tools and performance out of the box. It's simple
to upload files or sync a repo and it it's free. I'm not sure why anyone would
host a static website on the AWS stack.

~~~
xienze
> I'm not sure why anyone would host a static website on the AWS stack.

Well, I do that, so I guess I'll chime in.

First and foremost is the idea of not tying your site's build process and
hosting to a company that could go under. Yes, Amazon could, but if I had to
bet Netlify will either cease to exist, be bought out, have its free offering
discontinued/changed/etc. long before that.

Second is that sometimes your site's build process is more complicated than
what Netlify provides. For example, my site is a static Hugo site, which
Netlify supports, but there's one crucial step in the build process where I
turn my "resume.html" page into "resume.pdf" \-- I have to run a Docker image
that starts headless Chrome in order to render the PDF properly. As far as I
can tell, that can't be rigged up in Netlify.

Finally, I was able to learn a lot about AWS by hosting my site this way --
setting up a Lambda to listen for GitHub commits, using the AWS API to launch
an EC2 instance to build my site, how to configure S3 and CloudFront to serve
up content properly, etc. And at the end of the day I get a site that I have
complete control over and is approximately free to run.

~~~
seanwilson
> First and foremost is the idea of not tying your site's build process and
> hosting to a company that could go under.

Sounds like you're imposing a complex build process on yourself while getting
locked into a web of AWS features to be honest.

Could you not skip generating the PDF resume since you've already got the HTML
version to keep life simple?

If you stick to running a basic NPM script to build your site there's little
lock-in with Netlify. You could also build your site on a CI platform then
push the generated pages + assets to Netlify after.

~~~
xienze
> Sounds like you're imposing a complex build process on yourself while
> getting locked into a web of AWS features to be honest.

I should elaborate a little. My whole site is contained within a Docker
container that has NPM, Yarn, headless-chrome, Hugo, etc. I can generate
everything with a single command. The AWS bits are just there for hosting and
responding to a GitHub commit. So the build process is portable-ish, but from
what I saw Netlify doesn’t just let you do headless-chrome on a free plan[1].

> Could you not skip generating the PDF resume

Not really, the point is to automate everything away behind a single Git push.

1: [https://community.netlify.com/t/using-zipped-binaries-how-
to...](https://community.netlify.com/t/using-zipped-binaries-how-to-actually-
use-them/2740/12)

~~~
seanwilson
Why do you need a PDF resume that's built automatically though? Does it need
to be in PDF? Does it change that often? Aren't resumes something you
customise per job application?

------
misterbrian
Since we are all sharing how to deploy static sites, here's my approach using
CloudFormation to build a static site with S3, CloudFront, Certificate Manager
and Route53.

[https://gitlab.com/verbose-equals-true/django-postgres-
vue-g...](https://gitlab.com/verbose-equals-true/django-postgres-vue-gitlab-
ecs/-/blob/develop/cloudformation/infrastructure/static-site.yaml)

and here's how I deploy that site with GitLab CI.

[https://gitlab.com/verbose-equals-true/django-postgres-
vue-g...](https://gitlab.com/verbose-equals-true/django-postgres-vue-gitlab-
ecs/-/blob/develop/gitlab-ci/aws.yml#L29)

Also, nobody mentioned GitLab pages which offers some pretty nice static site
solutions as well.

~~~
nostrebored
Nice solution! If you're interested in a code based solution, this is one
space where the CDK really shines. OAI, CloudFront Website Distributions, and
Route53 AAAA records to the distribution are all turnkey constructs.
Deployment is just executing 'cdk deploy'.

If your CFN gives you headaches ever, maybe take a look

~~~
misterbrian
Thanks, I'm interested in learning a code-based solution. I like the ideas
behind CDK, Pulumi and Terraform, but I feel like they all have trade-offs.
CFN isn't the best, but I don't look forward to having to re-implement my
entire tech stack to achieve the same result compared with what I currently
have

------
heavyset_go
Just use Netlify, it's free, you can hook it up to a GitHub repository and
they'll handle your Let's Encrypt certs for you.

~~~
oxplot
Just use Github pages, supports TLS, CNAME and is free.

~~~
heavyset_go
Netlify does DNS and can serve from private repos for free. Not sure if GitHub
changed their policy, but last time I looked, if you wanted to serve from a
private repo, you needed to have a Pro plan.

~~~
yyhhsj0521
That's not true (at least not anymore). Now that Github offers free unlimited
private repos, there's no difference between public/private ones.

~~~
trazire
No, it is still true. From [https://help.github.com/en/github/working-with-
github-pages](https://help.github.com/en/github/working-with-github-pages)

> GitHub Pages is available in public repositories with GitHub Free, and in
> public and private repositories with GitHub Pro, GitHub Team, GitHub
> Enterprise Cloud, and GitHub Enterprise Server. For more information, see
> "GitHub's products."

~~~
yyhhsj0521
Ah, I guess it's because I'm on Github Student.

------
davidweatherall
For anyone who is hosting .html files and doesn't want to have to put index
files inside directories, the "trick" with s3 is to rename the file to the
name without the html extension, and change the Content Type to text/html.

Earlier today I modified the popular jakejarvis s3 sync github action to allow
for this during my CI/CD process.

[https://github.com/davidweatherall/s3-sync-
action](https://github.com/davidweatherall/s3-sync-action)

~~~
tomcam
Thanks for sharing that. Nice repo! Can you explain why I wouldn't want an
index file in a directory? I assume you mean index.html?

~~~
davidweatherall
I do mean index.html! Personally I prefer the url structure of
example.com/about as opposed to example.com/about/ \- especially when adding
on anchors or parameters (example.com/about?param as opposed to
/about/?param).

Relative pathing can be useful depending on file structure.

It avoids issues with directory / page naming conflicts. E.g. my images are
stored at /assets/img/image.png - but if I wanted to create a page at
example.com/assets this would require me to then place an index.html inside my
assets directory - which doesn't seem logical.

Overall, mostly personal preference of me disliking the index.html inside
directory method - It just doesn't seem like it's the "right" way to access a
page. If I have a example.com/about page - I expect them to be hitting an
about.html file.

------
lemax
I’ve been using S3 static hosting and CloudFront for all of my static sites
recently and it’s fantastic (and nearly free). This is not a hacky solution by
any means, S3 buckets support static file hosting out of the box and
CloudFront sits in front caching your content across the CDN. Throw in AWS
Certificate Manager and you get TLS solved too. Low traffic sites cost
literally nothing. S3 runs $0.004 per 10k requests and Cloudfront comes in at
$0.001 per 10K.

------
nostrebored
I don't really understand the author's claims here.

    
    
            const streamsBucket = new s3.Bucket(this, 'StreamsBucket', { websiteIndexDocument: 'index.html', removalPolicy: RemovalPolicy.DESTROY })
            /* Create a cloudfront endpoint to make it publicly accessible */
            const streamsDistributionOai = new cloudfront.OriginAccessIdentity(this, 'StreamsBucketOAI', {});
            const streamsDistribution = new cloudfront.CloudFrontWebDistribution(this, 'StreamsDistribution', {
                originConfigs: [
                    {
                        s3OriginSource: {
                            s3BucketSource: streamsBucket,
                            originAccessIdentity: streamsDistributionOai,
                        },
                        behaviors: [ {isDefaultBehavior: true} ],
                    }
                ]
            });
    

Will create a bucket that will serve index.html from a non website bucket.
Three lines of cdk code. If you need to populate the bucket, add another line
to create a new BucketDeployment to populate the bucket.

All files are secured by OAI and not accessible over the public internet.

------
mellowhype
This is a ridiculously complicated tutorial.

Sure, S3 works if you're deploying it as safest as possible and want to pay
for it too and do this on a recurrent basis, but otherwise is too big of a
fuss for a personal blog, I use GitHub pages for over 4 years now with no
issues, my own domain and SSL.

The simplest is surge.sh, period. If you don't need a domain, a web platform
and just want to deploy from your CLI, surge.sh is the solution. It's good
when you want to show off a static website to someone outside your sever. Even
the switching to a premium plan is done from the CLI.

Other solutions are: Netlify, ZEIT Now, Aerobatic or Render.

I frequently use this list from this GatsbyJS wiki to check for static website
hosts, I recommend it: [https://www.gatsbyjs.org/docs/deploying-and-
hosting/](https://www.gatsbyjs.org/docs/deploying-and-hosting/)

------
mlmitch
The complicated stuff seems predicated on this:

“However, the S3 website endpoint is publicly available. Anyone who knows this
endpoint can therefore also request your content while bypassing CloudFront.
If both URLs are crawled by Google, you risk getting a penalty for duplicate
content.”

I’m curious if anyone has experienced these issues in practice.

~~~
lawik
I run the setup of S3 + Cloudfront and never ran into their index problem
because I'm not trying for URLs without document file extensions.

I assume that's the reason for really wanting index redirect in directories.
Pretty URLs, I didn't feel the need. There are other valid reasons too I'm
sure. But my needs diverged from the article even earlier than SEO penalties.

~~~
mlmitch
The pretty URLs thing is confusing me now too. AWS lets you configure the
buckets to do the pretty URLs.

[https://docs.aws.amazon.com/AmazonS3/latest/dev/HowDoIWebsit...](https://docs.aws.amazon.com/AmazonS3/latest/dev/HowDoIWebsiteConfiguration.html)
[https://docs.aws.amazon.com/AmazonS3/latest/dev/IndexDocumen...](https://docs.aws.amazon.com/AmazonS3/latest/dev/IndexDocumentSupport.html)

I put up a Jekyll site on s3/cloudfront recently and it seems to work well.

Anyway, I’m still wondering about the consequences of the naked s3 endpoint
being available.

------
firefoxd
I know this is not a popular opinion here, but here goes:

I use a digitalocean instance where I install nginx. Then I copy the static
files through sftp or scp. For ssl, I install letsencrypt.

~~~
clutchingstraws
"I saw a guy building a website today.

No React.

No Vue.

No Ember.

He just sat there.

Writing HTML.

Like a Psychopath."

(credit to
[https://twitter.com/kiddbubu/status/1187120868259979269](https://twitter.com/kiddbubu/status/1187120868259979269))

------
gitgud
What benefits does this have? in comparison to much easier solutions like;
Netlify, Github Pages etc..

------
spectramax
What's wrong with old school apache server running on a $5/month DigitalOcean
droplet?

~~~
miguelmota
I've been running my personal blog and many other micro-sites on a $5
DigitalOcean droplet for years. It's seriously the best bang for the buck.

------
dave_sid
What I’ve gleaned from this thread is that in 2020 there are a thousand easy
ways to host a static website. Just take your pick and go with it.

~~~
woutr_be
And for every way, there will be 10 people who will call you names for doing
it this way, and that you should really do it another way. Just do whatever
makes sense for you.

------
svnpenn
I see you are using Hugo 0.62.1

[https://sanderknape.com](https://sanderknape.com)

FYI starting with 0.63.0 the speed has about doubled:

[https://github.com/gohugoio/hugo/releases/tag/v0.63.0](https://github.com/gohugoio/hugo/releases/tag/v0.63.0)

~~~
dewey
Is the speed it's taking to building the static site usually a problem? I
don't recall ever waiting for it to be done. Maybe my site is too minimal to
see a difference ([https://annoying.technology](https://annoying.technology)).

~~~
heinrichhartman
I have compile times of >30 seconds with Jekyll blog [1,2]. This is an issue.
It adds a lot of friction to the edit/preview loop.

BTW: I just moved it to Netlify since reading this thread. Took me ~5 minutes.

[1]
[https://github.com/HeinrichHartmann/HeinrichHartmann.github....](https://github.com/HeinrichHartmann/HeinrichHartmann.github.io)

[2] [https://www.heinrichhartmann.com/](https://www.heinrichhartmann.com/)

~~~
dewey
FWIW I'm getting a "certificate does not match *.netlify.com" SSL error on
your site.

------
welder
It's much simpler to use GitHub Pages + Cloudfront (optional).

~~~
abstrct
Ya, I'm trying to understand what the downside to github pages is compared to
this strategy. Can anybody elaborate on what I might be missing?

~~~
philistine
I’d rather be a paying customer and know I’m not going to lose my setup
because of some reason.

~~~
abstrct
That's absolutely a valid reason. All my static sites are not generating
income and don't need support. I've also got my own backups, so if GH decides
I shouldn't be there I'm not losing much. If a site is important to your
business then support is certainly more critical.

Thanks for the very valid counterpoint!

------
lunias
Did the same for my personal site. Really happy with the result:
[https://ethanaa.com/blog/conversion-to-static-site-with-
vuep...](https://ethanaa.com/blog/conversion-to-static-site-with-vuepress-and-
aws-s3/#amazon-route53)

I also wrote follow up posts on adding document search:
[https://ethanaa.com/blog/document-search-with-
algolia/](https://ethanaa.com/blog/document-search-with-algolia/)

And continuous deployment: [https://ethanaa.com/blog/continuous-deployment-
with-circleci...](https://ethanaa.com/blog/continuous-deployment-with-
circleci-and-s3deploy/)

------
philfreo
> The redirect logic provided by the S3 website endpoint can be moved to a
> Lambda@Edge function.

The post here is using Lambda@Edge to handle pointing example.com/about/ to
example.com/about/index.html

However there's a lot more you can do / may want to do with Lambda@Edge if
you're hosting a Cloudfront+S3 website.

I just wrote up how I set up a system to make managing server-side redirects
(e.g. 301s from /old-page to /new-page) easier via Lambda@Edge.

[https://news.ycombinator.com/item?id=22351484](https://news.ycombinator.com/item?id=22351484)

[https://engineering.close.com/posts/redirects-using-
cloudfro...](https://engineering.close.com/posts/redirects-using-cloudfront-
lambda-edge)

~~~
jillesvangurp
I did some redirects without lambda's last year using s3 routing rules, which
kind of worked. As figuring out this and several other things, I also wrote up
some details on this.

[https://dev.to/jillesvangurp/using-cloudfront-s3-and-
route-5...](https://dev.to/jillesvangurp/using-cloudfront-s3-and-route-53-for-
hosting-395o)

IMHO, Amazon should be ashamed of themselves for making it so unbelievably
convoluted and hard to host a simple website on cloudfront. It's the one thing
almost every website out there has to solve and they made it super painful to
get this right.

------
simlevesque
You should use Amplify, it solves allk those problems.

~~~
desas
I use AWS Amplify, it makes all of these headaches go away and it's
ridiculously simple to configure.

1\. Add your domain in AWS Route 53

2\. Tell it which git repo & branch you want to use (including private github
ones)

3\. It detects the repo contains a hugo site (works for other ssg) and
generates a build script

So now every time I commit to my selected branch, Lambda is notified, it fires
up a vm to generate the html, move it into S3 and takes care of Cloudfront,
SSL & so on.

------
altrum
I did something very similar recently with my website. With that said, I would
not do it again. For doing something—seemingly so simple, the infrastructure
work was a pain.

Also, while I’m at it, static websites are, in my opinion, a little “gimmicky”
since it’s impossible to determine the user’s browser size at build time. This
means that you have to make a choice to build for either mobile or desktop
first. Then, if the user is using the other device, they’ll encounter the FOUC
issue (flash of unstyled content).

For me, that’s big enough reason to not use static websites in the future.

~~~
robertoandred
What? Why aren’t you using media queries?

~~~
altrum
I am using media queries—while they work, they’ll flash the “unadapted”
version depending on what component is rendered first. The alternative is to
add some kind of loading aspect to each component but I think it’s not very
scalable

~~~
onion2k
_they’ll flash the “unadapted” version depending on what component is rendered
first_

A normal CSS file is render blocking so the DOM content won't be displayed
until the browser has downloaded it, parsed it, and knows what to display. If
you move your main layout styles out of the component (presumably this is
using styled components or similar?) and in to a CSS file that's defined as a
<link> in the header of the page then that problem will go away (or a <style>
tag in the header if you're worried about the additional fetch). This is how
browsers have been designed to work.

------
vegardx
Now you just need to configure a Lambda to take care of cache invalidation on
CloudFront, based on s3:PutObject events. CloudFront also supports headers
like "cache-control: public, max-age=3600, s-maxage=86400", so you can have
quite aggressive caching on CloudFront where you can just invalidate it on
demand anyway.

Personally I just listen for any event and invalidate all objects, since
that's way cheaper than issuing an invalidation request for each object, but
performance wise that might not be the best option.

------
coolsunglasses
Here's my terraform-ization of an S3 + Cloudflare setup for SSGs. I use Zola
but that's incidental.

[https://gitlab.com/bitemyapp/statically-
yours](https://gitlab.com/bitemyapp/statically-yours)

There's a weird bug with the `tf init` but it can be worked around by running
`tf init`, deleting the providers in `.terraform`, then running again.
Hashicorp has an open bug for the problem I think.

I could probably clean it up more but this has been okay for a couple sites I
run.

------
SkyMarshal
What are good ways of managing your content with a static website?

For example, say you want a single index.html file, with each article
contained in a separate content file - "blogpost01.html", "blogpost02.html",
etc. - that you somehow include in the <body></body> of your index file?

Is there any way to do that with a static site, or something similar where
your content is separated out into individual files?

~~~
hunter2_
Use a static site generator. The parts you touch for authoring posts will end
up "included" during the build step, producing files that you don't touch
which each redundantly contain the common markup. Or with an SPA generator
like Gatsby, there wouldn't even be any redundancy (but client side JS is
required).

~~~
gravitas
One example of the above is PyKwiki:
[https://github.com/nullism/pykwiki](https://github.com/nullism/pykwiki)

------
brown9-2
One thing that these guides on using S3 never mention is to make sure to set
alerts if the cost of the bucket grows too fast, i.e. your site gets popular.

------
actionowl
We've also been using S3 + Cloudfront for our static website, it's super cheap
and has been low touch.

We've run into two things though:

\- We have very little control over TLS versions and cipher settings.

\- We have to use a CNAME so we can't point a bare domain at it which also
means we can't add our site to the HSTS preload list (I think there is a way
to purchase an IP though now, if anyone knows please let me know).

Overall totally worth it though.

~~~
jbourne
On your point about using CNAMEs - if you have the domain set up with Route
53, you can create an A/AAAA alias record on the domain apex pointing to
CloudFront.

------
tobilg
I struggled with setting up static website hosting on S3, CloudFront, Route53
and ACM, so I created [https://github.com/tobilg/serverless-aws-static-
websites](https://github.com/tobilg/serverless-aws-static-websites) to
automate this via the Serverless framework

------
pansa2
Are there any guidelines for controlling cost when running a static website on
S3+CloudFront?

Say my regular bill for this setup was $5 a month. Can I at least get a
notification if I have a lot of visits and the bill goes over a threshold, say
$50?

Also, is there any protection against things like DDoS that could quickly push
the bill into the $100s and beyond?

~~~
avip
aws (and all other cloud providers I've used) has a pretty elaborate cost
alert system.

~~~
jfkebwjsbx
Alerts do nothing to stop a huge bill.

~~~
justasitsounds
You can use a lambda function that is triggered by a cloudwatch alarm when
your bill approaches an arbitrary limit.

What you do in response to such an event is entirely up to you

------
Animats
Why is this "serverless"? It's just rented server capacity on a shared host,
right?

~~~
nostrebored
Serverless is an operational construct that refers to the amount of management
you have over the underlying servers.

------
mathiasrw
For static websites nothing beats the CLI experience of surge.sh - one
(simple) command and its deployed. Its so smooth that I forget its there.

The way the API has been designed to make the usage natural/guessable has
inspired me a lot when I have made other CLI projects.

------
chindtooo
I prefer Google Cloud Run and it need not be 100% static though it should be
stateless.

------
shapeshed
Deploying static sites is the original and best candidate for engineers
overengineering

------
ttoinou
Anyone knows how I could measure website performance all over the world
averaged across multiple runs both for webpage and downloading huge file
(100Mo) ? To verify that the CDN is indeed faster than my current hosting
solution

------
vagab0nd
Why isn't this the 3rd option: Set the S3 bucket private and give CloudFront
access to it. I've been using it for a while and it seems to be working.

------
jposer
this was literally what I was doing today and if I'd just checked hacker news
it would have saved 3 hours of faffing with Lambda

------
manigandham
Static sites are overrated for most cases. Often you still need a backend for
editing with non-technical folks or just easier handling of media, etc so
you're now running a server-side instance of some blog or CMS while adding a
whole new detached frontend layer.

With things like Cloud Run that can run a container on-demand for every
request, it's easier to just stick with regular Wordpress or Ghost server-side
stacks.

~~~
zelly
> Cloud Run that can run a container on-demand for every request

People will bounce back. It will take far too long to load. The point of a
static site on a CDN is speed. If your goal is to get outside visitors, then
you definitely do not want to do this.

I can understand Cloud Run for demoing small apps though.

~~~
manigandham
Cloud Run just pauses the CPU, the container is still fully loaded and resumes
very quickly. You can also cache the pages with a CDN.

------
oxplot
Still can't do the same without paying hourly for a load balancer on Google
Cloud. C'moon Google!

------
sandGorgon
actually you should use Netlify or Firebase Hosting. Both have a CDN behind
them.

Frameworks like Nextjs Static Site export and Gatsbyjs have a lot of tooling
support for firebase hosting and netlify.

------
chindtooo
Use google Cloud Run though I love Netifly.

------
k__
Amplify really eases the pain with this.

------
interestingsoup
Great article!

