diff --git a/README.md b/README.md
index 951bb6a..a8bb61c 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,30 @@
# terraform-aws-publii-hosting
+
Terraform module to host a static site generated by Publii
[](https://github.com/chris-qa-org/terraform-aws-publii-hosting/actions/workflows/main.yml?branch=main)
[](https://github.com/chris-qa-org/terraform-aws-publii-hosting/releases/)
+This module launches static hosting resources (eg. S3 bucket, Cloudfront) specifically for sites generated by the Static Site Generator [Publii][1]
+
+It can in most cases be used to host any static site, however this module adds some configurations for the features of [Publii][1]
+
+## Key features:
+
+ - Creates an S3 bucket along with an IAM user which has the minimum required permissions to sync from [Publii][1]
+ - Creates a CloudFront endpoint (And optionally ACM certificates and Route53 records in an existing Hosted Zone)
+ - Creates a Lambda function to run a Cloudfront Invalidation when `files.publii.json` is created/updated (This file is updated on every sync)
+ - Optionally have CloudFront do the right thing when 'Pretty URLs' are enabled (This is achieved via a CloudFront function which adds `index.html` to the URI if there is no extention)
+ - Optionally redirect from the apex domain (eg. example.com) to www (www.example.com). If this is enabled (`var.cloudfront_enable_apex_to_www_redirect`), the 'Website Url' within 'Server' options should be set to www.yourdomain.com - [Publii S3 Server Settings docs (point 26)]
+ - Optionally enable WAF
+ - Optionally add custom origins and cache behaviours
+
+## Usage
+
+ - [Full launch with existing Route53 Zone](./examples/full-launch-with-existing-route53-zone/README.tf)
+ - [Use existing certificate and create own Route53 records](./examples/use-existing-certificate-and-create-own-route53-records/README.tf)
+ - [Adding custom origins and cache behaviours](./examples/adding-custom-origins-and-cache-behaviours/README.tf)
+
## Requirements
@@ -107,3 +128,7 @@ Terraform module to host a static site generated by Publii
| [project\_random\_id](#output\_project\_random\_id) | The random ID generated to ensure unique resource names |
| [s3\_bucket\_frontend](#output\_s3\_bucket\_frontend) | S3 bucket frontend attributes |
+
+
+[1]: https://getpublii.com/
+[2]: https://getpublii.com/docs/setup-static-website-hosting-amazon-s3.html
diff --git a/examples/adding-custom-origins-and-cache-behaviours/README.md b/examples/adding-custom-origins-and-cache-behaviours/README.md
new file mode 100644
index 0000000..91b9550
--- /dev/null
+++ b/examples/adding-custom-origins-and-cache-behaviours/README.md
@@ -0,0 +1,71 @@
+# Adding custom origins and cache behaviours
+
+ - [main.tf](./main.tf)
+
+```
+provider "aws" {
+ region = "us-east-1"
+ alias = "useast1"
+ default_tags {
+ tags = {
+ Project = "my-project"
+ }
+ }
+}
+
+resource "aws_route53_zone" "example" {
+ name = "example.com"
+}
+
+module "aws_publii_hosting" {
+ source = "chris-qa-org/terraform-aws-publii-hosting/aws"
+ version = "v1.0.0"
+
+ providers = {
+ aws.useast1 = aws.useast1
+ }
+
+ site_url = "example.com"
+ s3_bucket_acl = "private"
+ cloudfront_enable_ipv6 = true
+ cloudfront_enable_waf = true // Note: This will cost at least $5.00/month - https://aws.amazon.com/waf/pricing/ (default: false)
+ cloudfront_enable_apex_to_www_redirect = true
+ enable_publii_pretty_urls = true
+ route53_hosted_zone_options = {
+ id = aws_route53_zone.example.id
+ create_certificate_dns_validation_records = true
+ create_site_url_dns_records = true
+ }
+
+ cloudfront_origins = [
+ {
+ domain_name = aws_s3_bucket.example.bucket_regional_domain_name
+ origin_id = "example-custom-origin"
+
+ s3_origin_config = {
+ origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path
+ }
+ }
+ ]
+
+ cloudfront_ordered_cache_behaviors = [
+ {
+ path_pattern = "/example/*"
+ allowed_methods = ["GET", "HEAD"]
+ cached_methods = ["GET", "HEAD"]
+ target_origin_id = "example-custom-origin"
+
+ use_forwarded_values = true
+ query_string = false
+ headers = ["Origin"]
+ cookies_forward = "none"
+
+ min_ttl = 0
+ default_ttl = 86400
+ max_ttl = 31536000
+ compress = true
+ viewer_protocol_policy = "redirect-to-https"
+ }
+ ]
+}
+```
diff --git a/examples/adding-custom-origins-and-cache-behaviours/main.tf b/examples/adding-custom-origins-and-cache-behaviours/main.tf
new file mode 100644
index 0000000..046cba7
--- /dev/null
+++ b/examples/adding-custom-origins-and-cache-behaviours/main.tf
@@ -0,0 +1,65 @@
+provider "aws" {
+ region = "us-east-1"
+ alias = "useast1"
+ default_tags {
+ tags = {
+ Project = "my-project"
+ }
+ }
+}
+
+resource "aws_route53_zone" "example" {
+ name = "example.com"
+}
+
+module "aws_publii_hosting" {
+ source = "chris-qa-org/terraform-aws-publii-hosting/aws"
+ version = "v1.0.0"
+
+ providers = {
+ aws.useast1 = aws.useast1
+ }
+
+ site_url = "example.com"
+ s3_bucket_acl = "private"
+ cloudfront_enable_ipv6 = true
+ cloudfront_enable_waf = true // Note: This will cost at least $5.00/month - https://aws.amazon.com/waf/pricing/ (default: false)
+ cloudfront_enable_apex_to_www_redirect = true
+ enable_publii_pretty_urls = true
+ route53_hosted_zone_options = {
+ id = aws_route53_zone.example.id
+ create_certificate_dns_validation_records = true
+ create_site_url_dns_records = true
+ }
+
+ cloudfront_origins = [
+ {
+ domain_name = aws_s3_bucket.example.bucket_regional_domain_name
+ origin_id = "example-custom-origin"
+
+ s3_origin_config = {
+ origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path
+ }
+ }
+ ]
+
+ cloudfront_ordered_cache_behaviors = [
+ {
+ path_pattern = "/example/*"
+ allowed_methods = ["GET", "HEAD"]
+ cached_methods = ["GET", "HEAD"]
+ target_origin_id = "example-custom-origin"
+
+ use_forwarded_values = true
+ query_string = false
+ headers = ["Origin"]
+ cookies_forward = "none"
+
+ min_ttl = 0
+ default_ttl = 86400
+ max_ttl = 31536000
+ compress = true
+ viewer_protocol_policy = "redirect-to-https"
+ }
+ ]
+}
diff --git a/examples/full-launch-with-existing-route53-zone/README.md b/examples/full-launch-with-existing-route53-zone/README.md
new file mode 100644
index 0000000..a68bdf9
--- /dev/null
+++ b/examples/full-launch-with-existing-route53-zone/README.md
@@ -0,0 +1,40 @@
+# Full launch with existing Route53 Zone
+
+ - [main.tf](./main.tf)
+
+```
+provider "aws" {
+ region = "us-east-1"
+ alias = "useast1"
+ default_tags {
+ tags = {
+ Project = "my-project"
+ }
+ }
+}
+
+resource "aws_route53_zone" "example" {
+ name = "example.com"
+}
+
+module "aws_publii_hosting" {
+ source = "chris-qa-org/terraform-aws-publii-hosting/aws"
+ version = "v1.0.0"
+
+ providers = {
+ aws.useast1 = aws.useast1
+ }
+
+ site_url = "example.com"
+ s3_bucket_acl = "private"
+ cloudfront_enable_ipv6 = true
+ cloudfront_enable_waf = true // Note: This will cost at least $5.00/month - https://aws.amazon.com/waf/pricing/ (default: false)
+ cloudfront_enable_apex_to_www_redirect = true
+ enable_publii_pretty_urls = true
+ route53_hosted_zone_options = {
+ id = aws_route53_zone.example.id
+ create_certificate_dns_validation_records = true
+ create_site_url_dns_records = true
+ }
+}
+```
diff --git a/examples/full-launch-with-existing-route53-zone/main.tf b/examples/full-launch-with-existing-route53-zone/main.tf
new file mode 100644
index 0000000..97711a6
--- /dev/null
+++ b/examples/full-launch-with-existing-route53-zone/main.tf
@@ -0,0 +1,34 @@
+provider "aws" {
+ region = "us-east-1"
+ alias = "useast1"
+ default_tags {
+ tags = {
+ Project = "my-project"
+ }
+ }
+}
+
+resource "aws_route53_zone" "example" {
+ name = "example.com"
+}
+
+module "aws_publii_hosting" {
+ source = "chris-qa-org/terraform-aws-publii-hosting/aws"
+ version = "v1.0.0"
+
+ providers = {
+ aws.useast1 = aws.useast1
+ }
+
+ site_url = "example.com"
+ s3_bucket_acl = "private"
+ cloudfront_enable_ipv6 = true
+ cloudfront_enable_waf = true // Note: This will cost at least $5.00/month - https://aws.amazon.com/waf/pricing/ (default: false)
+ cloudfront_enable_apex_to_www_redirect = true
+ enable_publii_pretty_urls = true
+ route53_hosted_zone_options = {
+ id = aws_route53_zone.example.id
+ create_certificate_dns_validation_records = true
+ create_site_url_dns_records = true
+ }
+}
diff --git a/examples/use-existing-certificate-and-create-own-route53-records/README.md b/examples/use-existing-certificate-and-create-own-route53-records/README.md
new file mode 100644
index 0000000..7792b69
--- /dev/null
+++ b/examples/use-existing-certificate-and-create-own-route53-records/README.md
@@ -0,0 +1,60 @@
+# Use existing certificate and create own Route53 records
+
+ - [main.tf](./main.tf)
+
+```
+provider "aws" {
+ region = "us-east-1"
+ alias = "useast1"
+ default_tags {
+ tags = {
+ Project = "my-project"
+ }
+ }
+}
+
+module "aws_publii_hosting" {
+ source = "chris-qa-org/terraform-aws-publii-hosting/aws"
+ version = "v1.0.0"
+
+ providers = {
+ aws.useast1 = aws.useast1
+ }
+
+ site_url = "example.com"
+ s3_bucket_acl = "private"
+ cloudfront_tls_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ cloudfront_enable_ipv6 = true
+ cloudfront_enable_waf = true // Note: This will cost at least $5.00/month - https://aws.amazon.com/waf/pricing/ (default: false)
+ cloudfront_enable_apex_to_www_redirect = true
+ enable_publii_pretty_urls = true
+}
+
+resource "aws_route53_zone" "example" {
+ name = "example.com"
+}
+
+resource "aws_route53_record" "frontend" {
+ zone_id = aws_route53_zone.example.zone_id
+ name = "www.example.com"
+ type = "A"
+
+ alias {
+ name = module.aws_publii_hosting.aws_cloudfront_distribution_frontend.domain_name
+ zone_id = module.aws_publii_hosting.aws_cloudfront_distribution_frontend.hosted_zone_id
+ evaluate_target_health = true
+ }
+}
+
+resource "aws_route53_record" "apex_redirect" {
+ zone_id = aws_route53_zone.example.zone_id
+ name = "example.com"
+ type = "A"
+
+ alias {
+ name = module.aws_publii_hosting.aws_cloudfront_distribution_frontend_www_redirect.domain_name
+ zone_id = module.aws_publii_hosting.aws_cloudfront_distribution_frontend_www_redirect.hosted_zone_id
+ evaluate_target_health = true
+ }
+}
+```
diff --git a/examples/use-existing-certificate-and-create-own-route53-records/main.tf b/examples/use-existing-certificate-and-create-own-route53-records/main.tf
new file mode 100644
index 0000000..fc1e055
--- /dev/null
+++ b/examples/use-existing-certificate-and-create-own-route53-records/main.tf
@@ -0,0 +1,54 @@
+provider "aws" {
+ region = "us-east-1"
+ alias = "useast1"
+ default_tags {
+ tags = {
+ Project = "my-project"
+ }
+ }
+}
+
+module "aws_publii_hosting" {
+ source = "chris-qa-org/terraform-aws-publii-hosting/aws"
+ version = "v1.0.0"
+
+ providers = {
+ aws.useast1 = aws.useast1
+ }
+
+ site_url = "example.com"
+ s3_bucket_acl = "private"
+ cloudfront_tls_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ cloudfront_enable_ipv6 = true
+ cloudfront_enable_waf = true // Note: This will cost at least $5.00/month - https://aws.amazon.com/waf/pricing/ (default: false)
+ cloudfront_enable_apex_to_www_redirect = true
+ enable_publii_pretty_urls = true
+}
+
+resource "aws_route53_zone" "example" {
+ name = "example.com"
+}
+
+resource "aws_route53_record" "frontend" {
+ zone_id = aws_route53_zone.example.zone_id
+ name = "www.example.com"
+ type = "A"
+
+ alias {
+ name = module.aws_publii_hosting.aws_cloudfront_distribution_frontend.domain_name
+ zone_id = module.aws_publii_hosting.aws_cloudfront_distribution_frontend.hosted_zone_id
+ evaluate_target_health = true
+ }
+}
+
+resource "aws_route53_record" "apex_redirect" {
+ zone_id = aws_route53_zone.example.zone_id
+ name = "example.com"
+ type = "A"
+
+ alias {
+ name = module.aws_publii_hosting.aws_cloudfront_distribution_frontend_www_redirect.domain_name
+ zone_id = module.aws_publii_hosting.aws_cloudfront_distribution_frontend_www_redirect.hosted_zone_id
+ evaluate_target_health = true
+ }
+}