Migrating This Website to AWSSeptember 7, 2022
- Secure website hosted at https://jcazevedo.net/ with a valid SSL certificate;
- Requests to http://jcazevedo.net/ are redirected to https://jcazevedo.net/;
- Requests with the
wwwsubdomain (https://www.jcazevedo.net/) are redirected to https://jcazevedo.net/.
I also wanted to keep everything managed from within AWS, so that I could get
some infrastructure automation (Terraform) to help me with setting
everything up. Keeping everything managed from within AWS meant that I had to
jcazevedo.net domain transferred and have an SSL certificate
provisioned by AWS (I was previously using Let’s Encrypt). I also
didn’t mind downtime (again, this is a very low traffic website).
Setting Up Terraform
It wasn’t absolutely necessary to use Terraform (or any tool allowing for infrastructure as code) for this. I don’t predict wanting to have this infrastructure reproducible nor frequently modified. Still, it serves as documentation on what is set up on AWS, so I figured it would be a good idea.
The first step was to get Terraform set up and the providers defined. I didn’t
want to keep Terraform’s state locally, so I decided to also use S3 as a state
backend. I don’t need locks on the state (it’s only going to be me deploying
this), so a single file on a S3 bucket would suffice. So, I created an
folder on the root of the directory tree of this website and placed a
providers.tf file in it:
The required version is set to 1.0.11 because that’s the one I’m currently using
$WORK. Setting up the state backend required manually creating a bucket for
it. Using Terraform to manage that bucket would lead us to the problem of
remotely managing state that we were trying to avoid with it in the first place.
With this set up, a call to
terraform init should complete successfully.
Setting Up the S3 Bucket(s)
The next step was to set up the S3 buckets. I actually went with 2 buckets: one
for the root domain (
jcazevedo.net) and another for the
www.jcazevedo.net). The reason for it was to set up a redirect on the
subdomain, which S3 supports. To set the buckets up, I
s3.tf file under the
_infra_ folder with the following contents:
Most of the configuration is the same for both buckets. We want both buckets to allow GET requests from the public. The main difference is in the website configuration. The root bucket specifies an index and error document (to be served in case of errors), whereas the www bucket just configures the redirection policy.
Once this was set up, I pushed this website contents to root S3 bucket by
bundle exec jekyll build followed by an
aws s3 sync _site/
s3://jcazevedo.net/ --delete. The site was already available via the root
bucket website endpoint
and the redirection was already working via the www bucket website endpoint
At this point the domain wasn’t yet migrated, so this was still redirecting to
the DreamHost instance.
Setting Up the Domain
I had never transferred a domain before, so I followed AWS
This would take a while to complete, so I figured I would create the
Route53 zone before and have the domain already transferred to the
new zone. For that purpose I created a
route53.tf file under the
folder with the following contents:
While the domain had its tranfer in progress, I proceeded to set up the SSL certificates.
Provisioning the SSL Certificates
I had to search how to define ACM certificates in Terraform and to intregate them with CloudFront. Fortunately, I found this blog post by Alex Hyett: Hosting a Secure Static Website on AWS S3 using Terraform (Step By Step Guide). The blog post covered pretty much what I had already done thus far, and was extremely helpful on the next steps: setting up SSL and the CloudFront distribution.
To set up SSL, I created the
acm.tf file under the
_infra folder with the
For the validation method I used email instead of DNS since at that time I didn’t have the DNS moved yet. The email validation is performed while we’re applying the Terraform diff, so it’s quite fast.
Setting Up the CloudFront Distributions
CloudFront speeds up the distribution of static (and dynamic) web
content. It can handle caching, compression and can require viewers to use HTTPS
so that connections are encrypted. The previously mentioned blog
post by Alex Hyett provided
instructions to set CloudFront distributions pointing to existing S3 buckets and
using HTTPS, so I almost blindly copied the Terraform definitions. Similar to
what had been done before, we needed two distributions: one for the root bucket
and one for the
The configurations are similar, except for the caching settings, since the
second distribution only points to the S3 bucket that redirects to the non-
Adding Route53 Records Pointing to the CloudFront Distributions
The last part of the process involved creating new Route53 A records pointing to
the CloudFront distributions created previously. For this, I’ve added the
following to the
route53.tf file mentioned previously:
There’s one record for each of the distributions (
www and non-
Waiting for the Domain Transfer
The domain transfer from DreamHost to Route53 took around 8 days. I was notified by email when it was completed. Since everything was already pre-configured and the website contents had already been pushed to S3, the website continued to be served as expected from https://jcazevedo.net/.