Skip to content

Commit

Permalink
add cloudfront function ability
Browse files Browse the repository at this point in the history
  • Loading branch information
aashari committed Apr 4, 2022
1 parent 7e5352f commit 4dfad44
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.terraform
*.tfstate*
*.tfvars
.idea
.idea
*.tfvars
44 changes: 28 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,42 @@ The code above will provide an S3 bucket and a Cloudfront Distribution serving s
### With Custom Domain Cloudflare
```
module "static-website" {
source = "git@github.com:aashari/terraform-aws-static-website.git"
name = "hello.ashari.me"
custom_domain_provider = "CLOUDFLARE"
custom_domain_records = ["hello", "www.hello"]
custom_domain_zone_id = "abcdefghijklmnopqrstuvwxyz12345"
cloudflare_api_token = "AaaA11AaaaAaaA1aa11AAa11A76aaAAa9aAAaa-a"
source = "git@github.com:aashari/terraform-aws-static-website.git"
name = "hello.ashari.me"
custom_domain_provider = "CLOUDFLARE"
custom_domain_records = ["hello", "www.hello"]
custom_domain_zone_id = "abcdefghijklmnopqrstuvwxyz12345"
cloudflare_api_token = "AaaA11AaaaAaaA1aa11AAa11A76aaAAa9aAAaa-a"
}
```
The code above will provide an S3 bucket and Cloudfront Distribution serving static assets in an S3 bucket with additional ACM certificates for the custom domains assigned to Cloudfront and creating new records in the Cloudflare Zone

### With Custom Domain Route53
```
module "static-website" {
source = "git@github.com:aashari/terraform-aws-static-website.git"
source = "git@github.com:aashari/terraform-aws-static-website.git"
name = "hello.ashari.me"
custom_domain_provider = "ROUTE53"
custom_domain_records = ["hello", "www.hello"]
custom_domain_zone_id = "Z0ABCDEFGHI1234567"
}
```
The code above will provide an S3 bucket and Cloudfront Distribution serving static assets in an S3 bucket with additional ACM certificates for the custom domains assigned to Cloudfront and creating new records in the Route53 Zone

name = "hello.ashari.me"
### With CloudFront Function

custom_domain_provider = "ROUTE53"
custom_domain_records = ["hello", "www.hello"]
custom_domain_zone_id = "Z0ABCDEFGHI1234567"
#### main.tf
```
module "static-website" {
source = "git@github.com:aashari/terraform-aws-static-website.git"
name = "ashari.tech"
cloudfront_function_file_path = "function.js"
cloudfront_function_runtime = "cloudfront-js-1.0"
cloudfront_function_type = "viewer-request"
}
```
The code above will provide an S3 bucket and Cloudfront Distribution serving static assets in an S3 bucket with additional ACM certificates for the custom domains assigned to Cloudfront and creating new records in the Route53 Zone
The code above will provide an S3 bucket and a Cloudfront Distribution serving static assets in an S3 bucket with additional CloudFront function ([function.js](examples/with-cloudfront-function/function.js)) which redirect www request to non-www request

## Requirements

Expand All @@ -67,6 +76,9 @@ The code above will provide an S3 bucket and Cloudfront Distribution serving sta
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | Default tags to apply to all resources | `map(string)` | `{}` | no |
| <a name="input_default_root_object"></a> [default\_root\_object](#input\_default\_root\_object) | Default root object to serve | `string` | `index.html` | no |
| <a name="input_default_not_found_page"></a> [default\_not\_found\_page](#input\_default\_not\_found\_page) | Default not found page | `string` | `index.html` | no |
| <a name="input_cloudfront_function_file_path"></a> [input\_cloudfront\_function\_file\_path](#input\_input\_cloudfront\_function\_file\_path) | Path to the CloudFront function file | `string` | `` | no |
| <a name="input_cloudfront_function_runtime"></a> [input\_cloudfront\_function\_runtime](#input\_input\_cloudfront\_function\_runtime) | CloudFront function runtime | `string` | `cloudfront-js-1.0` | no |
| <a name="input_cloudfront_function_type"></a> [input\_cloudfront\_function\_type](#input\_input\_cloudfront\_function\_type) | CloudFront function event type to trigger | `string` | `viewer-request` | no |
| <a name="input_custom_domain_provider"></a> [custom\_domain\_provider](#input\_custom\_domain\_provider) | Custom domain provider name. <br />Available values: `CLOUDFLARE`, `ROUTE53` | `string` | `""` | no |
| <a name="input_custom_domain_records"></a> [custom\_domain\_records](#input\_custom\_domain\_records) | Custom domain records name to use for CloudFront distribution, use `@` to use the zone domain name.<br />For example `["hello", "www.hello"]` which represent `hello.{{ROOT_DOMAIN}}` and `www.hello.{{ROOT_DOMAIN}}`<br />or `["@", "www"]` which represent `{{ROOT_DOMAIN}}` and `www.{{ROOT_DOMAIN}}`.<br />where `ROOT_DOMAIN` is coming from domain name from Zone provided in `custom_domain_zone_id` variable | `list(string)` | `[]` | yes if <a name="input_custom_domain_provider"></a> [custom\_domain\_provider](#input\_custom\_domain\_provider) is not empty |
| <a name="input_custom_domain_zone_id"></a> [custom\_domain\_zone\_id](#input\_custom\_domain\_zone\_id) | Domain Provider zone ID which custom domain is registered to.<br />In Cloudflare this is called Zone Id, in Route53 this is called Hosted Zone Id | `string` | `""` | yes if <a name="input_custom_domain_provider"></a> [custom\_domain\_provider](#input\_custom\_domain\_provider) is not empty |
Expand Down
1 change: 1 addition & 0 deletions examples/with-cloudfront-function/.terraform-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.1.7
64 changes: 64 additions & 0 deletions examples/with-cloudfront-function/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions examples/with-cloudfront-function/function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
*
* This is an example of a CloudFront Function to redirect www. access to non-www access.
*/
function handler(event) {

var requestPayload = event.request;
var requestHost = requestPayload.headers['host'].value;
var requestURI = requestPayload.uri;
var requestQueryString = requestPayload.querystring;

// if requestHost starts with www.
if (requestHost.startsWith('www.')) {

// generate new host without www.
var newHost = requestHost.replace('www.', '');

// if requestURI does not start with /
if (!requestURI.startsWith('/')) {
// add / to requestURI
requestURI = '/' + requestURI;
}
var redirectURL = newHost + requestURI;

// convert querystring object to string
var queryString = '';
for (var key in requestQueryString) {
queryString += key + '=' + requestQueryString[key].value + '&';
}

// if queryString is not empty
if (queryString.length > 0) {
// remove last &
queryString = queryString.substring(0, queryString.length - 1);
// add queryString to redirectURL
redirectURL += '?' + queryString;
}

// return redirect
return {
statusCode: 301,
statusDescription: 'Found',
headers: {
location: {
value: 'http://' + redirectURL
}
}
};
}

return requestPayload;
}
10 changes: 10 additions & 0 deletions examples/with-cloudfront-function/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module "static-website" {
source = "../../"
name = "ashari.tech"
custom_domain_provider = "ROUTE53"
custom_domain_records = ["test", "www.test"]
custom_domain_zone_id = var.custom_domain_zone_id
cloudfront_function_file_path = "function.js"
cloudfront_function_runtime = "cloudfront-js-1.0"
cloudfront_function_type = "viewer-request"
}
3 changes: 3 additions & 0 deletions examples/with-cloudfront-function/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
provider "aws" {
region = "ap-southeast-1"
}
4 changes: 4 additions & 0 deletions examples/with-cloudfront-function/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "custom_domain_zone_id" {
type = string
description = "Domain Provider zone ID which custom domain is registered to"
}
27 changes: 27 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ resource "aws_cloudfront_distribution" "this" {
cookies { forward = "all" }
}

dynamic "function_association" {
for_each = var.cloudfront_function_file_path != "" ? [{}] : []
content {
event_type = var.cloudfront_function_type
function_arn = aws_cloudfront_function.this.arn
}
}

}

restrictions {
Expand Down Expand Up @@ -182,3 +190,22 @@ resource "aws_route53_record" "this" {

}
# END: Custom Domain using ROUTE53

# START: CloudFront function implementation
resource "aws_cloudfront_function" "this" {
name = replace(local.resource_name, "{}", "function")
runtime = var.cloudfront_function_runtime
comment = replace(local.resource_name, "{}", "function")
publish = var.cloudfront_function_file_path != "" ? true : false

code = var.cloudfront_function_file_path != "" ? file(var.cloudfront_function_file_path) : <<-EOT
function handler(event) {
return event;
}
EOT

lifecycle {
create_before_destroy = true
}
}
# END: CloudFront function implementation
18 changes: 18 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ variable "default_not_found_page" {
description = "Default not found page"
}

variable "cloudfront_function_file_path" {
type = string
default = ""
description = "Path to the CloudFront function file"
}

variable "cloudfront_function_runtime" {
type = string
default = "cloudfront-js-1.0"
description = "CloudFront function runtime"
}

variable "cloudfront_function_type" {
type = string
default = "viewer-request"
description = "CloudFront function event type to trigger"
}

variable "custom_domain_provider" {
type = string
default = ""
Expand Down

0 comments on commit 4dfad44

Please sign in to comment.