Super simple AWS static website using Terraform

Short word on static websites
I’m not going to scratch the surface on the debate between static and dynamic sites. They both are tools and have their respective use cases.
I will, however, assume here that you want (or need) to deploy some static code using the simplest solution as possible.
Note on Terraform: The management of a Terraform stack is a bit out of scope for this article, I will not comment on state management. It is totally possible to use template code as a run-once solution.
Requirements
- AWS Account
- Route53 Domain
- Code to deploy
- Terraform installed
Make sure you can run aws sts get-caller-identity
successfully on you shell.
Architecture
CDN included. Versioning on the bucket in case you mess up something.
+------+ +----------+ +---------+
|Client| ==> |Cloudfront| ==> |S3 Bucket|
+------+ +----------+ +---------+
Cost
- Domain annual cost.
- S3 storage, generally pretty low, depends on the size of your site.
- Traffic, Cloudfront is the cheapest way of getting data out of AWS.
The code
Using two modules:
Make sure to replace the < >
fields with what suits you.
provider "aws" {
alias = "global"
# Has to be us-east-1
region = "us-east-1"
}
provider "aws" {
region = <YOUR_REGION>
}
data "aws_route53_zone" "dns_zone" {
# Like: example.com
name = <YOUR_DOMAIN>
}
module "s3-static-website" {
source = "cn-terraform/s3-static-website/aws"
version = "1.0.10"
providers = {
aws.main = aws
aws.acm_provider = aws.global
}
# Like: blog.example.com
name_prefix = <YOUR_SUBDOMAIN>
website_domain_name = <YOUR_SUBDOMAIN>
create_route53_hosted_zone = false
route53_hosted_zone_id = data.aws_route53_zone.dns_zone.zone_id
}
module "sync-dir" {
source = "MarioMoura/syncdir/aws"
version = "~> 0.0"
# The directory where the static code is
directory = <LOCAL_DIR>
bucket = module.s3-static-website.website_bucket_id
cache_control_default = "max-age=3600"
cache_control_by_extension = {
html = "max-age=7200"
}
}
The next few commands will differ depending on your setup, generally a terraform init && terraform apply
enough.
Warning: Notice that I left out the backend and provider version configuration. If you need guidance look here.
Probably something like this:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = <VERSION>
}
}
backend "<TYPE>" {
"<ARGUMENTS>"
}
}