{"id":24698954,"url":"https://github.com/artioml/aws-cloudfront-s3","last_synced_at":"2025-10-09T07:32:28.002Z","repository":{"id":202348086,"uuid":"180629149","full_name":"ArtiomL/aws-cloudfront-s3","owner":"ArtiomL","description":":globe_with_meridians: Terraform module to provision CloudFront and securely serve HTTPS requests to a static website hosted on S3","archived":false,"fork":false,"pushed_at":"2020-08-06T08:14:24.000Z","size":1351,"stargazers_count":8,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2023-10-20T10:39:39.842Z","etag":null,"topics":["acm","aws","cloudfront","http2","infrastructure-as-code","lambda-edge","route53","s3","terraform-modules","tls"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ArtiomL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-04-10T17:17:21.000Z","updated_at":"2023-10-20T11:43:21.494Z","dependencies_parsed_at":null,"dependency_job_id":"e9946168-ee41-4964-b7fa-44fa769ce72d","html_url":"https://github.com/ArtiomL/aws-cloudfront-s3","commit_stats":null,"previous_names":["artioml/aws-cloudfront-s3"],"tags_count":2,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArtiomL%2Faws-cloudfront-s3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArtiomL%2Faws-cloudfront-s3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArtiomL%2Faws-cloudfront-s3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArtiomL%2Faws-cloudfront-s3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ArtiomL","download_url":"https://codeload.github.com/ArtiomL/aws-cloudfront-s3/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235801802,"owners_count":19047126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acm","aws","cloudfront","http2","infrastructure-as-code","lambda-edge","route53","s3","terraform-modules","tls"],"created_at":"2025-01-27T04:34:57.580Z","updated_at":"2025-10-09T07:32:22.498Z","avatar_url":"https://github.com/ArtiomL.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg align=\"center\" src=\"img/cf.svg\"\u003e\u0026nbsp;\u0026nbsp; aws-cloudfront-s3\u0026nbsp;\u0026nbsp;\u003cimg align=\"center\" src=\"img/s3.svg\"\u003e\n[![Releases](https://img.shields.io/github/release/ArtiomL/aws-cloudfront-s3.svg)](https://github.com/ArtiomL/aws-cloudfront-s3/releases)\n[![Commits](https://img.shields.io/github/commits-since/ArtiomL/aws-cloudfront-s3/latest.svg?label=commits%20since)](https://github.com/ArtiomL/aws-cloudfront-s3/commits/master)\n[![Maintenance](https://img.shields.io/maintenance/yes/2020.svg)](https://github.com/ArtiomL/aws-cloudfront-s3/graphs/code-frequency)\n[![Issues](https://img.shields.io/github/issues/ArtiomL/aws-cloudfront-s3.svg)](https://github.com/ArtiomL/aws-cloudfront-s3/issues)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE)\n\n\u0026nbsp;\u0026nbsp;\n\n## Table of Contents\n- [Description](#description)\n\t- [Architecture](#architecture)\n\t- [Security](#security)\n- [Input Variables](#input-variables)\n- [Output Values](#output-values)\n- [Example](#example)\n- [License](LICENSE)\n\n\u0026nbsp;\u0026nbsp;\n\n## Description\n\nTerraform AWS module to provision CloudFront CDN and securely serve HTTPS requests to a static website hosted on Amazon S3. \n\n### Architecture\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"img/arc.png\"\u003e\u003c/p\u003e\n\nThe module creates:\n\n- [S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html) to host static website content\n- S3 bucket to store CloudFront [access log](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html) files in\n- [Block Public Access](https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) settings for both S3 buckets (all four settings set to `true`)\n- CloudFront [origin access identity](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)\n- S3 bucket policy to ensure CloudFront OAI has permissions to read files in the S3 bucket, but users don't\n- ACM public SSL/TLS certificate for your domain, using [DNS validation](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate-dns.html)\n- Route 53 CNAME record for ACM validation\n- CloudFront [distribution](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html) with IPv6, TLS, SNI and [HTTP/2](https://css-tricks.com/http2-real-world-performance-test-analysis/) support targeting an S3 origin\n- Lambda@Edge [function](index.js) to [customize](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html) the content CloudFront delivers\n- Route 53 A and AAAA alias records to the CloudFront distribution\n\n### Security\n\nThe default Lambda@Edge [function](index.js) is used to add the following [HTTP security](https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/) response headers, triggered by the [Origin Response](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html) CloudFront event:\n\n```http\nStrict-Transport-Security: max-age=63072000; includeSubDomains; preload\nX-XSS-Protection: 1; mode=block\nX-Content-Type-Options: nosniff\nX-Frame-Options: DENY\nReferrer-Policy: no-referrer\nContent-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self';\nFeature-Policy: geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'self'; vibrate 'none'; fullscreen 'self'; payment 'none';\n```\n\nScanning the website with [HTTP Observatory](https://observatory.mozilla.org/) results in:\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"img/ap.png\" width=\"500\"\u003e\u003c/p\u003e\n\nUse the module input variables to specify a filename with custom function code (`source_file`) and the CloudFront event to trigger it (`event_type`).\n\n\u0026nbsp;\u0026nbsp;\n\n## Input Variables\n\n| Name | Description | Type | Default | Required |\n|------|-------------|:----:|:-----:|:-----:|\n| allowed\\_methods | Controls which HTTP methods CloudFront processes and forwards to your S3 bucket | list | `\u003clist\u003e` | no |\n| aws\\_region | AWS region | string | `\"eu-west-1\"` | no |\n| cached\\_methods | Controls whether CloudFront caches responses to requests using the specified HTTP methods | list | `\u003clist\u003e` | no |\n| comment | Distribution comments | string | `\"Managed by Terraform\"` | no |\n| compress | Compress content for web requests that include Accept-Encoding: gzip in the request header | string | `\"true\"` | no |\n| default\\_root\\_object | An object CloudFront returns when the end user requests the root URL | string | `\"index.html\"` | no |\n| default\\_ttl | Default amount of time (in seconds) an object is in a CloudFront cache | string | `\"3600\"` | no |\n| domain\\_name | DNS domain name | string | n/a | yes |\n| enabled | Whether the distribution is enabled to accept end user requests for content | string | `\"true\"` | no |\n| event\\_type | The specific event to trigger the function | string | `\"origin-response\"` | no |\n| force\\_destroy | All objects should be deleted from the bucket so that the bucket can be destroyed without error | string | `\"true\"` | no |\n| geo\\_restriction\\_locations | ISO 3166-1-alpha-2 country codes | list | `\u003clist\u003e` | no |\n| geo\\_restriction\\_type | The method to restrict distribution of your content by country (none, whitelist, blacklist) | string | `\"none\"` | no |\n| handler | The function entrypoint in your code | string | `\"index.handler\"` | no |\n| include\\_body | Expose the request body to the Lambda function | string | `\"false\"` | no |\n| is\\_ipv6\\_enabled | Whether IPv6 is enabled for the distribution | string | `\"true\"` | no |\n| log\\_days | The number of days to keep the log files | string | `\"7\"` | no |\n| max\\_ttl | Maximum amount of time an object is in a CloudFront cache | string | `\"86400\"` | no |\n| min\\_ttl | Minimum amount of time you want objects to stay in CloudFront caches | string | `\"0\"` | no |\n| minimum\\_protocol\\_version | The minimum TLS version that you want CloudFront to use for HTTPS connections | string | `\"TLSv1.2_2018\"` | no |\n| origin\\_path | Causes CloudFront to request content from a directory in your S3 bucket | string | `\"\"` | no |\n| price\\_class | The price class for this distribution (PriceClass_All, PriceClass_200, PriceClass_100) | string | `\"PriceClass_All\"` | no |\n| runtime | Function runtime identifier | string | `\"nodejs10.x\"` | no |\n| source\\_file | Package this file into the function archive (index.js local to the module path is used by default) | string | `\"\"` | no |\n| tag\\_environment | Environment tag | string | `\"Prod\"` | no |\n| tag\\_name | Name tag | string | `\"AWSLabs\"` | no |\n| tags\\_shared | Other tags assigned to all resources | map | `\u003cmap\u003e` | no |\n| viewer\\_protocol\\_policy | The protocol users can use to access the origin files (allow-all, https-only, redirect-to-https) | string | `\"redirect-to-https\"` | no |\n| wait\\_for\\_deployment | Wait for the distribution status to change from InProgress to Deployed | string | `\"false\"` | no |\n| web\\_acl\\_id | AWS WAFv2 Web ACL ARN | string | `\"\"` | no |\n| zone\\_id | Route 53 zone ID | string | n/a | yes |\n\n\u0026nbsp;\u0026nbsp;\n\n## Output Values\n\n| Name | Description |\n|------|-------------|\n| alias\\_fqdn | DNS alias record FQDN |\n| bucket\\_id | S3 bucket name |\n| bucket\\_regional | S3 bucket region-specific domain name, also used as CloudFront Origin ID |\n| cert\\_arn | ACM certificate ARN |\n| dist\\_arn | CloudFront distribution ARN |\n| dist\\_domain | CloudFront distribution domain name |\n| dist\\_id | CloudFront distribution ID |\n| dist\\_zone\\_id | CloudFront zone ID that can be used to point Route 53 alias records to |\n\n\u0026nbsp;\u0026nbsp;\n\n## Example\n\n```hcl\n# S3, IAM, ACM, CloudFront\nmodule \"aws_cloudfront_s3\" {\n  source          = \"github.com/ArtiomL/aws-cloudfront-s3\"\n  aws_region      = \"eu-north-1\"\n  domain_name     = \"artl.dev\"\n  source_file     = \"custom.js\"\n  zone_id         = aws_route53_zone.main.zone_id\n  tag_name        = \"AWSLabs\"\n  tag_environment = \"Dev\"\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartioml%2Faws-cloudfront-s3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartioml%2Faws-cloudfront-s3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartioml%2Faws-cloudfront-s3/lists"}