Skip to content

Commit

Permalink
Make S3 website private; add S3 origin (#105)
Browse files Browse the repository at this point in the history
Co-authored-by: cloudpossebot <[email protected]>
Co-authored-by: John McGehee <[email protected]>
Co-authored-by: nitro <[email protected]>
Co-authored-by: Philippe M. Chiasson <[email protected]>
  • Loading branch information
5 people authored Apr 26, 2021
1 parent 096e355 commit d378e4b
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 17 deletions.
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ module "cdn" {
}
```

### Using an S3 Static Website Origin

When variable `website_enabled` is set to `true`, the S3 origin is configured
as a static website. The S3 static website has the advantage of redirecting
URL `subdir/` to `subdir/index.html` without requiring a
[Lambda@Edge function to perform the redirection](https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/).
The S3 static website responds only to CloudFront, preventing direct access to
S3.

In addition to setting `website_enabled=true`, you must also:

* Specify at least one `aliases`, like `["example.com"]` or
`["example.com", "www.example.com"]`
* Specify an ACM certificate

### Generating ACM Certificate

```hcl
Expand Down Expand Up @@ -176,8 +191,6 @@ Or use the AWS cli to [request new ACM certifiates](http://docs.aws.amazon.com/a
aws acm request-certificate --domain-name example.com --subject-alternative-names a.example.com b.example.com *.c.example.com
```



__NOTE__:

Although AWS Certificate Manager is supported in many AWS regions, to use an SSL certificate with CloudFront, it should be requested only in US East (N. Virginia) region.
Expand Down Expand Up @@ -218,12 +231,14 @@ Available targets:
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.0 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.2 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.0 |
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.2 |

## Modules

Expand All @@ -243,6 +258,7 @@ Available targets:
| [aws_s3_bucket.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
| [aws_s3_bucket_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [random_password.referer](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [aws_iam_policy_document.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.origin_website](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_s3_bucket.selected](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source |
Expand Down Expand Up @@ -272,7 +288,7 @@ Available targets:
| <a name="input_cors_max_age_seconds"></a> [cors\_max\_age\_seconds](#input\_cors\_max\_age\_seconds) | Time in seconds that browser can cache the response for S3 bucket | `number` | `3600` | no |
| <a name="input_custom_error_response"></a> [custom\_error\_response](#input\_custom\_error\_response) | List of one or more custom error response element maps | <pre>list(object({<br> error_caching_min_ttl = string<br> error_code = string<br> response_code = string<br> response_page_path = string<br> }))</pre> | `[]` | no |
| <a name="input_custom_origin_headers"></a> [custom\_origin\_headers](#input\_custom\_origin\_headers) | A list of origin header parameters that will be sent to origin | `list(object({ name = string, value = string }))` | `[]` | no |
| <a name="input_custom_origins"></a> [custom\_origins](#input\_custom\_origins) | One or more custom origins for this distribution (multiples allowed). See documentation for configuration options description https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments | <pre>list(object({<br> domain_name = string<br> origin_id = string<br> origin_path = string<br> custom_headers = list(object({<br> name = string<br> value = string<br> }))<br> custom_origin_config = object({<br> http_port = number<br> https_port = number<br> origin_protocol_policy = string<br> origin_ssl_protocols = list(string)<br> origin_keepalive_timeout = number<br> origin_read_timeout = number<br> })<br> }))</pre> | `[]` | no |
| <a name="input_custom_origins"></a> [custom\_origins](#input\_custom\_origins) | A list of custom origins (such as apps or S3 websites) for this distribution.<br>See the Terraform documentation for configuration options<br>https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments | <pre>list(object({<br> domain_name = string<br> origin_id = string<br> origin_path = string<br> custom_headers = list(object({<br> name = string<br> value = string<br> }))<br> custom_origin_config = object({<br> http_port = number<br> https_port = number<br> origin_protocol_policy = string<br> origin_ssl_protocols = list(string)<br> origin_keepalive_timeout = number<br> origin_read_timeout = number<br> })<br> }))</pre> | `[]` | no |
| <a name="input_default_root_object"></a> [default\_root\_object](#input\_default\_root\_object) | Object that CloudFront return when requests the root URL | `string` | `"index.html"` | no |
| <a name="input_default_ttl"></a> [default\_ttl](#input\_default\_ttl) | Default amount of time (in seconds) that an object is in a CloudFront cache | `number` | `60` | no |
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
Expand Down Expand Up @@ -321,14 +337,15 @@ Available targets:
| <a name="input_redirect_all_requests_to"></a> [redirect\_all\_requests\_to](#input\_redirect\_all\_requests\_to) | A hostname to redirect all website requests for this distribution to. If this is set, it overrides other website settings | `string` | `""` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_routing_rules"></a> [routing\_rules](#input\_routing\_rules) | A json array containing routing rules describing redirect behavior and when redirects are applied | `string` | `""` | no |
| <a name="input_s3_origins"></a> [s3\_origins](#input\_s3\_origins) | A list of S3 origins for this distribution. S3 buckets configured as websites<br>are custom\_origins, not s3\_origins. See the Terraform documentation for<br>configuration options<br>https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments | <pre>list(object({<br> domain_name = string<br> origin_id = string<br> origin_path = string<br> s3_origin_config = object({<br> origin_access_identity = string<br> })<br> }))</pre> | `[]` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |
| <a name="input_trusted_signers"></a> [trusted\_signers](#input\_trusted\_signers) | The AWS accounts, if any, that you want to allow to create signed URLs for private content. 'self' is acceptable. | `list(string)` | `[]` | no |
| <a name="input_versioning_enabled"></a> [versioning\_enabled](#input\_versioning\_enabled) | When set to 'true' the s3 origin bucket will have versioning enabled | `bool` | `true` | no |
| <a name="input_viewer_protocol_policy"></a> [viewer\_protocol\_policy](#input\_viewer\_protocol\_policy) | allow-all, redirect-to-https | `string` | `"redirect-to-https"` | no |
| <a name="input_wait_for_deployment"></a> [wait\_for\_deployment](#input\_wait\_for\_deployment) | When set to 'true' the resource will wait for the distribution status to change from InProgress to Deployed | `bool` | `true` | no |
| <a name="input_web_acl_id"></a> [web\_acl\_id](#input\_web\_acl\_id) | ID of the AWS WAF web ACL that is associated with the distribution | `string` | `""` | no |
| <a name="input_website_enabled"></a> [website\_enabled](#input\_website\_enabled) | Set to true to use an S3 static website as origin | `bool` | `false` | no |
| <a name="input_website_enabled"></a> [website\_enabled](#input\_website\_enabled) | Set to true to use an S3 static website as origin. If you set this to true, see<br>README for more important instructions. | `bool` | `false` | no |

## Outputs

Expand Down Expand Up @@ -496,8 +513,8 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
### Contributors

<!-- markdownlint-disable -->
| [![Erik Osterman][osterman_avatar]][osterman_homepage]<br/>[Erik Osterman][osterman_homepage] | [![Andriy Knysh][aknysh_avatar]][aknysh_homepage]<br/>[Andriy Knysh][aknysh_homepage] | [![Jamie Nelson][Jamie-BitFlight_avatar]][Jamie-BitFlight_homepage]<br/>[Jamie Nelson][Jamie-BitFlight_homepage] | [![Clive Zagno][cliveza_avatar]][cliveza_homepage]<br/>[Clive Zagno][cliveza_homepage] | [![David Mattia][dmattia_avatar]][dmattia_homepage]<br/>[David Mattia][dmattia_homepage] | [![RB][nitrocode_avatar]][nitrocode_homepage]<br/>[RB][nitrocode_homepage] |
|---|---|---|---|---|---|
| [![Erik Osterman][osterman_avatar]][osterman_homepage]<br/>[Erik Osterman][osterman_homepage] | [![Andriy Knysh][aknysh_avatar]][aknysh_homepage]<br/>[Andriy Knysh][aknysh_homepage] | [![Jamie Nelson][Jamie-BitFlight_avatar]][Jamie-BitFlight_homepage]<br/>[Jamie Nelson][Jamie-BitFlight_homepage] | [![Clive Zagno][cliveza_avatar]][cliveza_homepage]<br/>[Clive Zagno][cliveza_homepage] | [![David Mattia][dmattia_avatar]][dmattia_homepage]<br/>[David Mattia][dmattia_homepage] | [![RB][nitrocode_avatar]][nitrocode_homepage]<br/>[RB][nitrocode_homepage] | [![John McGehee][jmcgeheeiv_avatar]][jmcgeheeiv_homepage]<br/>[John McGehee][jmcgeheeiv_homepage] |
|---|---|---|---|---|---|---|
<!-- markdownlint-restore -->

[osterman_homepage]: https://github.com/osterman
Expand All @@ -512,6 +529,8 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
[dmattia_avatar]: https://img.cloudposse.com/150x150/https://github.com/dmattia.png
[nitrocode_homepage]: https://github.com/nitrocode
[nitrocode_avatar]: https://img.cloudposse.com/150x150/https://github.com/nitrocode.png
[jmcgeheeiv_homepage]: https://github.com/jmcgeheeiv
[jmcgeheeiv_avatar]: https://img.cloudposse.com/150x150/https://github.com/jmcgeheeiv.png

[![README Footer][readme_footer_img]][readme_footer_link]
[![Beacon][beacon]][website]
Expand Down
25 changes: 21 additions & 4 deletions README.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
#
# This is the canonical configuration for the `README.md`
# Run `make readme` to rebuild the `README.md`
#
# To rebuild `README.md`:
# 1) Make all changes to `README.yaml`
# 2) Run `make init` (you only need to do this once)
# 3) Run`make readme` to rebuild this file.

# Name of this project
name: terraform-aws-cloudfront-s3-cdn
Expand Down Expand Up @@ -93,6 +95,21 @@ usage: |-
}
```
### Using an S3 Static Website Origin
When variable `website_enabled` is set to `true`, the S3 origin is configured
as a static website. The S3 static website has the advantage of redirecting
URL `subdir/` to `subdir/index.html` without requiring a
[Lambda@Edge function to perform the redirection](https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/).
The S3 static website responds only to CloudFront, preventing direct access to
S3.
In addition to setting `website_enabled=true`, you must also:
* Specify at least one `aliases`, like `["example.com"]` or
`["example.com", "www.example.com"]`
* Specify an ACM certificate
### Generating ACM Certificate
```hcl
Expand Down Expand Up @@ -139,8 +156,6 @@ usage: |-
aws acm request-certificate --domain-name example.com --subject-alternative-names a.example.com b.example.com *.c.example.com
```
__NOTE__:
Although AWS Certificate Manager is supported in many AWS regions, to use an SSL certificate with CloudFront, it should be requested only in US East (N. Virginia) region.
Expand Down Expand Up @@ -175,3 +190,5 @@ contributors:
github: "dmattia"
- name: "RB"
github: "nitrocode"
- name: "John McGehee"
github: "jmcgeheeiv"
Loading

0 comments on commit d378e4b

Please sign in to comment.