A couple of years ago I got some critique at Metosin regarding my blog in Medium - that as a software professional I should host my own blog. So, I moved my blog from Medium to Github Pages. You can read more about that project in my previous blog post Setting Up Blog in Github Pages.
This summer I got an idea to start a Finnish blog. I thought that I could experiment hosting a static website using Amazon S3. In this new blog post I explain how I set up the S3 static web site and later on provided support for https using AWS ACM and AWS CloudFront.
Hosting a Static Website Using Amazon S3
Hosting a static website using Amazon S3 is quite simple. I explain here the basic steps.
- You need an Amazon Web Services account.
- Choose an AWS Region for the bucket.
- Create a S3 bucket. Choose a descriptive name for the bucket, like blog.mydomain.com (mydomain.com is your domain).
- Use document hosting a static website using Amazon S3 how to set up the static hosting site.
Now you have the basic S3 infrastructure ready. Next you need to create your static website files. I use Jekyll for generating a static web site from markdown files.
Once you are content with the first version of your site you can deploy it to the AWS S3 bucket.
aws s3 sync _site s3://blog.mydomain.com
… in which the
_site is the local Jekyll generated site and
blog.mydomain.com is your bucket.
If you use AWS Console and navigate to your S3 bucket, choose
Properties tab and scroll down, you see
Static website hosting section and and url to
Bucket website endpoint. Try to click the url link and you should see your site in your browser. The url is a bit funny, something like
http://blog.mydomain.com.s3-website.some-aws-region.amazonaws.com. Therefore, the next job is to buy a domain name and create a CNAME for your domain.
Buy a Domain Name and Create a CNAME for Your Website
Once you have a domain, you should create a CNAME for binding your S3 website url to some more easier rememberable url.
Example. If your S3 website url is
http://blog.mydomain.com.s3-website.some-aws-region.amazonaws.com, and your domain is
mydomain, then you can create e.g. a CNAME record like:
Name: blog.mydomain.com. Type: CNAME Value: blog.mydomain.com.s3-website.some-aws-region.amazonaws.com
NOTE: Remember that the CNAME record is fully qualified DNS name: you need the dot at the end of the string (i.e.
blog.mydomain.com. => see the last dot).
Wait for a few minutes until your new DNS record propagates to various dns servers.
You can also try to
dig it to see whether the propagation is done:
dig +short blog.mydomain.com
Once you get the result from
dig you should be able to navigate to
http://blog.mydomain.com in your browser.
Basically you are ready now. If you don’t mind that the site does not support
Add HTTPS Support
Follow instructions in Requesting a public certificate how to create a certificate. One important thing to know is that you have to create the certificate in the
US East (N. Virginia), i.e.
us-east-1 region since the certificate needs to be hosted in that region for later on to be able to use that certificate with AWS CloudFront.
You should use dns validation as AWS recommends.
Provide the CNAME as your domain for the certificate (or use asterix, see the document for more information).
Once you have created your certificate, you need to dns validate it. Fetch the CSV file from the AWS Certificate you just created. In that file (or in the AWS Console / AWS ACM) you find the CNAME name and value you need to add using your domain provider’s web page. Create a new CNAME using the name and value provided. Once you have done this the certificate should change status from
Pending validation to
Issued (it may take some time, you could use
dig to see the propagation). The dns validation is a step to verify that you actually own the domain you are creating a certificate for.
The last step is to create an Amazon CloudFront distribution. AWS has an excellent document how to do this: How do I use CloudFront to serve HTTPS requests for my Amazon S3 bucket?. You should be good to go following that document. There are just two things that you really need to remember:
- You have created the certificate in the
US East (N. Virginia), i.e.
us-east-1region (since CloudFront won’t accept any other region for hosting the certificates).
- Do not use the bucket name as suggested by AWS Console, you should use the S3 static website url (see above how to get it). The reason for this is that certain urls won’t work with the bare bucket origin until you explicitely add the
index.htmlat the end of the url (Jekyll creates urls like this) - this way
blog.mydomain.com/author/index.htmland you won’t get
You are almost there. Next delete the CNAME record that binds your
blog.mydomain.com to your S3 bucket, and create instead a CNAME record that binds
blog.mydomain.com to your CloudFront distribution (see the distribution domain in AWS Console).
Now you should be able to use https procotol, try using your web browser:
Changing Content in Your Blog
There is one more thing to know if you are using CloudFront. You need to invalidate the files that have been changed in the S3 bucket. Find out your distribution id:
aws cloudfront list-distributions --output table | grep 'Id\|Comment'
… and then invalidate your site:
aws cloudfront create-invalidation --distribution-id YOUR_CF_DIST_ID --paths "/*"
You should soon see your updated blog in your browser using your url
Hosting a static website in AWS is a good option for your website if you have basic skills related to AWS and DNS.
The writer is working at a major international IT corporation building cloud infrastructures and implementing applications on top of those infrastructures.
- Kari Marttila’s Home Page in LinkedIn: https://www.linkedin.com/in/karimarttila/