Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add Support for Origin Groups (Failover Origins) #174

Merged
merged 19 commits into from
Jul 2, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,47 @@ module "cdn" {
}
```

The following will create an Origin Group with the origin created by this module as a primary origin and an additional
S3 bucket as a failover origin.

```hcl
module "s3_bucket" {
source = "cloudposse/s3-bucket/aws"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"

attributes = ["failover-assets"]
}

module "cdn" {
source = "cloudposse/cloudfront-s3-cdn/aws"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"

aliases = ["assets.cloudposse.com"]
dns_alias_enabled = true
parent_zone_name = "cloudposse.com"
s3_origins = {
domain_name = module.s3_bucket.bucket_regional_domain_name
origin_id = module.s3_bucket.bucket_id
origin_path = null
s3_origin_config = {
origin_access_identity = null # will get translated to the origin_access_identity used by the origin created by this module.
}
}
origin_groups = {
primary_origin_id = null # will get translated to the origin id of the origin created by this module.
failover_origin_id = module.s3_bucket.bucket_id
failover_criteria = [
403,
404,
500,
502
]
}
}
```

### Background on CDNs, "Origins", S3 Buckets, and Web Servers

#### CDNs and Origin Servers
Expand Down Expand Up @@ -435,6 +476,7 @@ Available targets:
| <a name="input_ordered_cache"></a> [ordered\_cache](#input\_ordered\_cache) | An ordered list of [cache behaviors](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#cache-behavior-arguments) resource for this distribution.<br>List in order of precedence (first match wins). This is in addition to the default cache policy.<br>Set `target_origin_id` to `""` to specify the S3 bucket origin created by this module. | <pre>list(object({<br> target_origin_id = string<br> path_pattern = string<br><br> allowed_methods = list(string)<br> cached_methods = list(string)<br> compress = bool<br><br> cache_policy_id = string<br> origin_request_policy_id = string<br><br> viewer_protocol_policy = string<br> min_ttl = number<br> default_ttl = number<br> max_ttl = number<br><br> forward_query_string = bool<br> forward_header_values = list(string)<br> forward_cookies = string<br><br> lambda_function_association = list(object({<br> event_type = string<br> include_body = bool<br> lambda_arn = string<br> }))<br><br> function_association = list(object({<br> event_type = string<br> function_arn = string<br> }))<br> }))</pre> | `[]` | no |
| <a name="input_origin_bucket"></a> [origin\_bucket](#input\_origin\_bucket) | Name of an existing S3 bucket to use as the origin. If this is not provided, it will create a new s3 bucket using `var.name` and other context related inputs | `string` | `null` | no |
| <a name="input_origin_force_destroy"></a> [origin\_force\_destroy](#input\_origin\_force\_destroy) | Delete all objects from the bucket so that the bucket can be destroyed without error (e.g. `true` or `false`) | `bool` | `false` | no |
| <a name="input_origin_groups"></a> [origin\_groups](#input\_origin\_groups) | List of [Origin Groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#origin-group-arguments) to create in the distribution.<br>The values of `primary_origin_id` and `failover_origin_id` must correspond to origin IDs existing in `var.s3_origins` or `var.custom_origins`.<br><br>If `primary_origin_id` is set to `null` or `""`, then the origin id of the origin created by this module will be used in its place.<br>This is to allow for the use case of making the origin created by this module the primary origin in an origin group. | <pre>list(object({<br> primary_origin_id = string<br> failover_origin_id = string<br> failover_criteria = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_origin_path"></a> [origin\_path](#input\_origin\_path) | An optional element that causes CloudFront to request your content from a directory in your Amazon S3 bucket or your custom origin. It must begin with a /. Do not add a / at the end of the path. | `string` | `""` | no |
| <a name="input_origin_ssl_protocols"></a> [origin\_ssl\_protocols](#input\_origin\_ssl\_protocols) | The SSL/TLS protocols that you want CloudFront to use when communicating with your origin over HTTPS. | `list(string)` | <pre>[<br> "TLSv1",<br> "TLSv1.1",<br> "TLSv1.2"<br>]</pre> | no |
| <a name="input_override_origin_bucket_policy"></a> [override\_origin\_bucket\_policy](#input\_override\_origin\_bucket\_policy) | When using an existing origin bucket (through var.origin\_bucket), setting this to 'false' will make it so the existing bucket policy will not be overriden | `bool` | `true` | no |
Expand All @@ -449,7 +491,7 @@ Available targets:
| <a name="input_s3_access_log_bucket_name"></a> [s3\_access\_log\_bucket\_name](#input\_s3\_access\_log\_bucket\_name) | Name of the existing S3 bucket where S3 Access Logs will be delivered. Default is not to enable S3 Access Logging. | `string` | `""` | no |
| <a name="input_s3_access_log_prefix"></a> [s3\_access\_log\_prefix](#input\_s3\_access\_log\_prefix) | Prefix to use for S3 Access Log object keys. Defaults to `logs/${module.this.id}` | `string` | `""` | no |
| <a name="input_s3_access_logging_enabled"></a> [s3\_access\_logging\_enabled](#input\_s3\_access\_logging\_enabled) | Set `true` to deliver S3 Access Logs to the `s3_access_log_bucket_name` bucket.<br>Defaults to `false` if `s3_access_log_bucket_name` is empty (the default), `true` otherwise.<br>Must be set explicitly if the access log bucket is being created at the same time as this module is being invoked. | `bool` | `null` | no |
| <a name="input_s3_origins"></a> [s3\_origins](#input\_s3\_origins) | A list of S3 [origins](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments) (in addition to the one created by this module) for this distribution.<br>S3 buckets configured as websites are `custom_origins`, not `s3_origins`. | <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_s3_origins"></a> [s3\_origins](#input\_s3\_origins) | A list of S3 [origins](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments) (in addition to the one created by this module) for this distribution.<br>S3 buckets configured as websites are `custom_origins`, not `s3_origins`.<br>Specifying `s3_origin_config.origin_access_identity` as `null` or `""` will have it translated to the `origin_access_identity` used by the origin created by the module. | <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_s3_website_password_enabled"></a> [s3\_website\_password\_enabled](#input\_s3\_website\_password\_enabled) | If set to true, and `website_enabled` is also true, a password will be required in the `Referrer` field of the<br>HTTP request in order to access the website, and Cloudfront will be configured to pass this password in its requests.<br>This will make it much harder for people to bypass Cloudfront and access the S3 website directly via its website endpoint. | `bool` | `false` | 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 |
Expand All @@ -465,13 +507,16 @@ Available targets:

| Name | Description |
|------|-------------|
| <a name="output_aliases"></a> [aliases](#output\_aliases) | Aliases of the CloudFront distibution |
| <a name="output_aliases"></a> [aliases](#output\_aliases) | Aliases of the CloudFront distribution. |
| <a name="output_cf_arn"></a> [cf\_arn](#output\_cf\_arn) | ARN of AWS CloudFront distribution |
| <a name="output_cf_domain_name"></a> [cf\_domain\_name](#output\_cf\_domain\_name) | Domain name corresponding to the distribution |
| <a name="output_cf_etag"></a> [cf\_etag](#output\_cf\_etag) | Current version of the distribution's information |
| <a name="output_cf_hosted_zone_id"></a> [cf\_hosted\_zone\_id](#output\_cf\_hosted\_zone\_id) | CloudFront Route 53 zone ID |
| <a name="output_cf_id"></a> [cf\_id](#output\_cf\_id) | ID of AWS CloudFront distribution |
| <a name="output_cf_identity_iam_arn"></a> [cf\_identity\_iam\_arn](#output\_cf\_identity\_iam\_arn) | CloudFront Origin Access Identity IAM ARN |
| <a name="output_cf_origin_groups"></a> [cf\_origin\_groups](#output\_cf\_origin\_groups) | List of Origin Groups in the CloudFront distribution. |
| <a name="output_cf_origin_ids"></a> [cf\_origin\_ids](#output\_cf\_origin\_ids) | List of Origin IDs in the CloudFront distribution. |
| <a name="output_cf_primary_origin_id"></a> [cf\_primary\_origin\_id](#output\_cf\_primary\_origin\_id) | The ID of the origin created by this module. |
| <a name="output_cf_s3_canonical_user_id"></a> [cf\_s3\_canonical\_user\_id](#output\_cf\_s3\_canonical\_user\_id) | Canonical user ID for CloudFront Origin Access Identity |
| <a name="output_cf_status"></a> [cf\_status](#output\_cf\_status) | Current status of the distribution |
| <a name="output_logs"></a> [logs](#output\_logs) | Log bucket resource |
Expand Down
41 changes: 41 additions & 0 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,47 @@ usage: |-
}
```

The following will create an Origin Group with the origin created by this module as a primary origin and an additional
S3 bucket as a failover origin.

```hcl
module "s3_bucket" {
source = "cloudposse/s3-bucket/aws"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"

attributes = ["failover-assets"]
}

module "cdn" {
source = "cloudposse/cloudfront-s3-cdn/aws"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"

aliases = ["assets.cloudposse.com"]
dns_alias_enabled = true
parent_zone_name = "cloudposse.com"
s3_origins = {
domain_name = module.s3_bucket.bucket_regional_domain_name
origin_id = module.s3_bucket.bucket_id
origin_path = null
s3_origin_config = {
origin_access_identity = null # will get translated to the origin_access_identity used by the origin created by this module.
}
}
origin_groups = {
primary_origin_id = null # will get translated to the origin id of the origin created by this module.
failover_origin_id = module.s3_bucket.bucket_id
failover_criteria = [
403,
404,
500,
502
]
}
}
```

### Background on CDNs, "Origins", S3 Buckets, and Web Servers

#### CDNs and Origin Servers
Expand Down
8 changes: 6 additions & 2 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
| <a name="input_ordered_cache"></a> [ordered\_cache](#input\_ordered\_cache) | An ordered list of [cache behaviors](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#cache-behavior-arguments) resource for this distribution.<br>List in order of precedence (first match wins). This is in addition to the default cache policy.<br>Set `target_origin_id` to `""` to specify the S3 bucket origin created by this module. | <pre>list(object({<br> target_origin_id = string<br> path_pattern = string<br><br> allowed_methods = list(string)<br> cached_methods = list(string)<br> compress = bool<br><br> cache_policy_id = string<br> origin_request_policy_id = string<br><br> viewer_protocol_policy = string<br> min_ttl = number<br> default_ttl = number<br> max_ttl = number<br><br> forward_query_string = bool<br> forward_header_values = list(string)<br> forward_cookies = string<br><br> lambda_function_association = list(object({<br> event_type = string<br> include_body = bool<br> lambda_arn = string<br> }))<br><br> function_association = list(object({<br> event_type = string<br> function_arn = string<br> }))<br> }))</pre> | `[]` | no |
| <a name="input_origin_bucket"></a> [origin\_bucket](#input\_origin\_bucket) | Name of an existing S3 bucket to use as the origin. If this is not provided, it will create a new s3 bucket using `var.name` and other context related inputs | `string` | `null` | no |
| <a name="input_origin_force_destroy"></a> [origin\_force\_destroy](#input\_origin\_force\_destroy) | Delete all objects from the bucket so that the bucket can be destroyed without error (e.g. `true` or `false`) | `bool` | `false` | no |
| <a name="input_origin_groups"></a> [origin\_groups](#input\_origin\_groups) | List of [Origin Groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#origin-group-arguments) to create in the distribution.<br>The values of `primary_origin_id` and `failover_origin_id` must correspond to origin IDs existing in `var.s3_origins` or `var.custom_origins`.<br><br>If `primary_origin_id` is set to `null` or `""`, then the origin id of the origin created by this module will be used in its place.<br>This is to allow for the use case of making the origin created by this module the primary origin in an origin group. | <pre>list(object({<br> primary_origin_id = string<br> failover_origin_id = string<br> failover_criteria = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_origin_path"></a> [origin\_path](#input\_origin\_path) | An optional element that causes CloudFront to request your content from a directory in your Amazon S3 bucket or your custom origin. It must begin with a /. Do not add a / at the end of the path. | `string` | `""` | no |
| <a name="input_origin_ssl_protocols"></a> [origin\_ssl\_protocols](#input\_origin\_ssl\_protocols) | The SSL/TLS protocols that you want CloudFront to use when communicating with your origin over HTTPS. | `list(string)` | <pre>[<br> "TLSv1",<br> "TLSv1.1",<br> "TLSv1.2"<br>]</pre> | no |
| <a name="input_override_origin_bucket_policy"></a> [override\_origin\_bucket\_policy](#input\_override\_origin\_bucket\_policy) | When using an existing origin bucket (through var.origin\_bucket), setting this to 'false' will make it so the existing bucket policy will not be overriden | `bool` | `true` | no |
Expand All @@ -129,7 +130,7 @@
| <a name="input_s3_access_log_bucket_name"></a> [s3\_access\_log\_bucket\_name](#input\_s3\_access\_log\_bucket\_name) | Name of the existing S3 bucket where S3 Access Logs will be delivered. Default is not to enable S3 Access Logging. | `string` | `""` | no |
| <a name="input_s3_access_log_prefix"></a> [s3\_access\_log\_prefix](#input\_s3\_access\_log\_prefix) | Prefix to use for S3 Access Log object keys. Defaults to `logs/${module.this.id}` | `string` | `""` | no |
| <a name="input_s3_access_logging_enabled"></a> [s3\_access\_logging\_enabled](#input\_s3\_access\_logging\_enabled) | Set `true` to deliver S3 Access Logs to the `s3_access_log_bucket_name` bucket.<br>Defaults to `false` if `s3_access_log_bucket_name` is empty (the default), `true` otherwise.<br>Must be set explicitly if the access log bucket is being created at the same time as this module is being invoked. | `bool` | `null` | no |
| <a name="input_s3_origins"></a> [s3\_origins](#input\_s3\_origins) | A list of S3 [origins](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments) (in addition to the one created by this module) for this distribution.<br>S3 buckets configured as websites are `custom_origins`, not `s3_origins`. | <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_s3_origins"></a> [s3\_origins](#input\_s3\_origins) | A list of S3 [origins](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin-arguments) (in addition to the one created by this module) for this distribution.<br>S3 buckets configured as websites are `custom_origins`, not `s3_origins`.<br>Specifying `s3_origin_config.origin_access_identity` as `null` or `""` will have it translated to the `origin_access_identity` used by the origin created by the module. | <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_s3_website_password_enabled"></a> [s3\_website\_password\_enabled](#input\_s3\_website\_password\_enabled) | If set to true, and `website_enabled` is also true, a password will be required in the `Referrer` field of the<br>HTTP request in order to access the website, and Cloudfront will be configured to pass this password in its requests.<br>This will make it much harder for people to bypass Cloudfront and access the S3 website directly via its website endpoint. | `bool` | `false` | 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 |
Expand All @@ -145,13 +146,16 @@

| Name | Description |
|------|-------------|
| <a name="output_aliases"></a> [aliases](#output\_aliases) | Aliases of the CloudFront distibution |
| <a name="output_aliases"></a> [aliases](#output\_aliases) | Aliases of the CloudFront distribution. |
| <a name="output_cf_arn"></a> [cf\_arn](#output\_cf\_arn) | ARN of AWS CloudFront distribution |
| <a name="output_cf_domain_name"></a> [cf\_domain\_name](#output\_cf\_domain\_name) | Domain name corresponding to the distribution |
| <a name="output_cf_etag"></a> [cf\_etag](#output\_cf\_etag) | Current version of the distribution's information |
| <a name="output_cf_hosted_zone_id"></a> [cf\_hosted\_zone\_id](#output\_cf\_hosted\_zone\_id) | CloudFront Route 53 zone ID |
| <a name="output_cf_id"></a> [cf\_id](#output\_cf\_id) | ID of AWS CloudFront distribution |
| <a name="output_cf_identity_iam_arn"></a> [cf\_identity\_iam\_arn](#output\_cf\_identity\_iam\_arn) | CloudFront Origin Access Identity IAM ARN |
| <a name="output_cf_origin_groups"></a> [cf\_origin\_groups](#output\_cf\_origin\_groups) | List of Origin Groups in the CloudFront distribution. |
| <a name="output_cf_origin_ids"></a> [cf\_origin\_ids](#output\_cf\_origin\_ids) | List of Origin IDs in the CloudFront distribution. |
| <a name="output_cf_primary_origin_id"></a> [cf\_primary\_origin\_id](#output\_cf\_primary\_origin\_id) | The ID of the origin created by this module. |
| <a name="output_cf_s3_canonical_user_id"></a> [cf\_s3\_canonical\_user\_id](#output\_cf\_s3\_canonical\_user\_id) | Canonical user ID for CloudFront Origin Access Identity |
| <a name="output_cf_status"></a> [cf\_status](#output\_cf\_status) | Current status of the distribution |
| <a name="output_logs"></a> [logs](#output\_logs) | Log bucket resource |
Expand Down
Loading