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

Remove static bucket hack #143

Merged
merged 15 commits into from
Mar 31, 2021
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ Available targets:
| <a name="input_allowed_methods"></a> [allowed\_methods](#input\_allowed\_methods) | List of allowed methods (e.g. GET, PUT, POST, DELETE, HEAD) for AWS CloudFront | `list(string)` | <pre>[<br> "DELETE",<br> "GET",<br> "HEAD",<br> "OPTIONS",<br> "PATCH",<br> "POST",<br> "PUT"<br>]</pre> | no |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
| <a name="input_block_origin_public_access_enabled"></a> [block\_origin\_public\_access\_enabled](#input\_block\_origin\_public\_access\_enabled) | When set to 'true' the s3 origin bucket will have public access block enabled | `bool` | `false` | no |
| <a name="input_bucket_domain_format"></a> [bucket\_domain\_format](#input\_bucket\_domain\_format) | Format of bucket domain name | `string` | `"%s.s3.amazonaws.com"` | no |
| <a name="input_cached_methods"></a> [cached\_methods](#input\_cached\_methods) | List of cached methods (e.g. GET, PUT, POST, DELETE, HEAD) | `list(string)` | <pre>[<br> "GET",<br> "HEAD"<br>]</pre> | no |
| <a name="input_cloudfront_origin_access_identity_iam_arn"></a> [cloudfront\_origin\_access\_identity\_iam\_arn](#input\_cloudfront\_origin\_access\_identity\_iam\_arn) | Existing cloudfront origin access identity iam arn that is supplied in the s3 bucket policy | `string` | `""` | no |
| <a name="input_cloudfront_origin_access_identity_path"></a> [cloudfront\_origin\_access\_identity\_path](#input\_cloudfront\_origin\_access\_identity\_path) | Existing cloudfront origin access identity path used in the cloudfront distribution's s3\_origin\_config content | `string` | `""` | no |
Expand Down Expand Up @@ -254,7 +253,7 @@ Available targets:
| <a name="input_name"></a> [name](#input\_name) | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no |
| <a name="input_ordered_cache"></a> [ordered\_cache](#input\_ordered\_cache) | An ordered list of cache behaviors resource for this distribution. List from top to bottom in order of precedence. The topmost cache behavior will have precedence 0.<br>The fields can be described by the other variables in this file. For example, the field 'lambda\_function\_association' in this object has<br>a description in var.lambda\_function\_association variable earlier in this file. The only difference is that fields on this object are in ordered caches, whereas the rest<br>of the vars in this file apply only to the default cache. Put value `""` on field `target_origin_id` to specify default s3 bucket origin. | <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> 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> }))</pre> | `[]` | no |
| <a name="input_origin_bucket"></a> [origin\_bucket](#input\_origin\_bucket) | Origin S3 bucket name | `string` | `""` | no |
| <a name="input_origin_bucket"></a> [origin\_bucket](#input\_origin\_bucket) | Origin S3 bucket name | `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_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 |
Expand All @@ -266,10 +265,8 @@ Available targets:
| <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_stage"></a> [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_static_s3_bucket"></a> [static\_s3\_bucket](#input\_static\_s3\_bucket) | aws-cli is a bucket owned by amazon that will perminantly exist.<br>It allows for the data source to be called during the destruction process without failing.<br>It doesn't get used for anything else, this is a safe workaround for handling the fact that<br>if a data source like the one `aws_s3_bucket.selected` gets an error, you can't continue the terraform process<br>which also includes the 'destroy' command, where is doesn't even need this data source!<br>Don't change this bucket name, it's a variable so that we can provide this description.<br>And this works around a problem that is an edge case. | `string` | `"aws-cli"` | 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_use_regional_s3_endpoint"></a> [use\_regional\_s3\_endpoint](#input\_use\_regional\_s3\_endpoint) | When set to 'true' the s3 origin\_bucket will use the regional endpoint address instead of the global endpoint address | `bool` | `false` | 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 |
Expand Down
5 changes: 1 addition & 4 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
| <a name="input_allowed_methods"></a> [allowed\_methods](#input\_allowed\_methods) | List of allowed methods (e.g. GET, PUT, POST, DELETE, HEAD) for AWS CloudFront | `list(string)` | <pre>[<br> "DELETE",<br> "GET",<br> "HEAD",<br> "OPTIONS",<br> "PATCH",<br> "POST",<br> "PUT"<br>]</pre> | no |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
| <a name="input_block_origin_public_access_enabled"></a> [block\_origin\_public\_access\_enabled](#input\_block\_origin\_public\_access\_enabled) | When set to 'true' the s3 origin bucket will have public access block enabled | `bool` | `false` | no |
| <a name="input_bucket_domain_format"></a> [bucket\_domain\_format](#input\_bucket\_domain\_format) | Format of bucket domain name | `string` | `"%s.s3.amazonaws.com"` | no |
| <a name="input_cached_methods"></a> [cached\_methods](#input\_cached\_methods) | List of cached methods (e.g. GET, PUT, POST, DELETE, HEAD) | `list(string)` | <pre>[<br> "GET",<br> "HEAD"<br>]</pre> | no |
| <a name="input_cloudfront_origin_access_identity_iam_arn"></a> [cloudfront\_origin\_access\_identity\_iam\_arn](#input\_cloudfront\_origin\_access\_identity\_iam\_arn) | Existing cloudfront origin access identity iam arn that is supplied in the s3 bucket policy | `string` | `""` | no |
| <a name="input_cloudfront_origin_access_identity_path"></a> [cloudfront\_origin\_access\_identity\_path](#input\_cloudfront\_origin\_access\_identity\_path) | Existing cloudfront origin access identity path used in the cloudfront distribution's s3\_origin\_config content | `string` | `""` | no |
Expand Down Expand Up @@ -97,7 +96,7 @@
| <a name="input_name"></a> [name](#input\_name) | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no |
| <a name="input_ordered_cache"></a> [ordered\_cache](#input\_ordered\_cache) | An ordered list of cache behaviors resource for this distribution. List from top to bottom in order of precedence. The topmost cache behavior will have precedence 0.<br>The fields can be described by the other variables in this file. For example, the field 'lambda\_function\_association' in this object has<br>a description in var.lambda\_function\_association variable earlier in this file. The only difference is that fields on this object are in ordered caches, whereas the rest<br>of the vars in this file apply only to the default cache. Put value `""` on field `target_origin_id` to specify default s3 bucket origin. | <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> 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> }))</pre> | `[]` | no |
| <a name="input_origin_bucket"></a> [origin\_bucket](#input\_origin\_bucket) | Origin S3 bucket name | `string` | `""` | no |
| <a name="input_origin_bucket"></a> [origin\_bucket](#input\_origin\_bucket) | Origin S3 bucket name | `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_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 |
Expand All @@ -109,10 +108,8 @@
| <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_stage"></a> [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_static_s3_bucket"></a> [static\_s3\_bucket](#input\_static\_s3\_bucket) | aws-cli is a bucket owned by amazon that will perminantly exist.<br>It allows for the data source to be called during the destruction process without failing.<br>It doesn't get used for anything else, this is a safe workaround for handling the fact that<br>if a data source like the one `aws_s3_bucket.selected` gets an error, you can't continue the terraform process<br>which also includes the 'destroy' command, where is doesn't even need this data source!<br>Don't change this bucket name, it's a variable so that we can provide this description.<br>And this works around a problem that is an edge case. | `string` | `"aws-cli"` | 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_use_regional_s3_endpoint"></a> [use\_regional\_s3\_endpoint](#input\_use\_regional\_s3\_endpoint) | When set to 'true' the s3 origin\_bucket will use the regional endpoint address instead of the global endpoint address | `bool` | `false` | 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 |
Expand Down
19 changes: 9 additions & 10 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ provider "aws" {
}

module "cloudfront_s3_cdn" {
source = "../../"
context = module.this.context
parent_zone_name = var.parent_zone_name
dns_alias_enabled = true
use_regional_s3_endpoint = true
origin_force_destroy = true
cors_allowed_headers = ["*"]
cors_allowed_methods = ["GET", "HEAD", "PUT"]
cors_allowed_origins = ["*.cloudposse.com"]
cors_expose_headers = ["ETag"]
source = "../../"
context = module.this.context
parent_zone_name = var.parent_zone_name
dns_alias_enabled = true
origin_force_destroy = true
cors_allowed_headers = ["*"]
cors_allowed_methods = ["GET", "HEAD", "PUT"]
cors_allowed_origins = ["*.cloudposse.com"]
cors_expose_headers = ["ETag"]
}

resource "aws_s3_bucket_object" "index" {
Expand Down
23 changes: 4 additions & 19 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ locals {
}
]
}

regions_s3_website_use_dash = [
"us-east-1",
"us-west-1",
"us-west-2",
"ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1",
"sa-east-1"
]
}

module "origin_label" {
Expand Down Expand Up @@ -173,11 +163,12 @@ module "logs" {
}

data "aws_s3_bucket" "selected" {
bucket = local.bucket == "" ? var.static_s3_bucket : local.bucket
count = local.using_existing_origin ? 1 : 0
bucket = var.origin_bucket
}

locals {
using_existing_origin = signum(length(var.origin_bucket)) == 1
using_existing_origin = var.origin_bucket != null

using_existing_cloudfront_origin = var.cloudfront_origin_access_identity_iam_arn != "" && var.cloudfront_origin_access_identity_path != ""

Expand All @@ -190,13 +181,7 @@ locals {
concat([var.origin_bucket], concat([""], aws_s3_bucket.origin.*.id))
)
)

bucket_domain_name = (var.use_regional_s3_endpoint || var.website_enabled) ? format(
var.website_enabled ? "%s.s3-website%s%s.amazonaws.com" : "%s.s3%s%s.amazonaws.com",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nitrocode This change seems to have broken the "s3-website" functionality. It now wants to change the origin domain_name from
XXXXX.s3-website.eu-west-1.amazonaws.com to XXXXX.s3.eu-west-1.amazonaws.com which results in an AccessDenied when loading the domain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created this ticket #148 after reviewing your comment. Good catch.

local.bucket,
(var.website_enabled && contains(local.regions_s3_website_use_dash, data.aws_s3_bucket.selected.region)) ? "-" : ".",
data.aws_s3_bucket.selected.region,
) : format(var.bucket_domain_format, local.bucket)
bucket_domain_name = local.using_existing_origin ? try(data.aws_s3_bucket.selected[0].bucket_regional_domain_name, "") : try(aws_s3_bucket.origin[0].bucket_regional_domain_name, "")
}

resource "aws_cloudfront_distribution" "default" {
Expand Down
29 changes: 1 addition & 28 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ variable "aliases" {
default = []
}

variable "use_regional_s3_endpoint" {
type = bool
description = "When set to 'true' the s3 origin_bucket will use the regional endpoint address instead of the global endpoint address"
default = false
}

variable "additional_bucket_policy" {
type = string
default = "{}"
Expand All @@ -48,7 +42,7 @@ variable "override_origin_bucket_policy" {

variable "origin_bucket" {
type = string
default = ""
default = null
description = "Origin S3 bucket name"
}

Expand All @@ -65,12 +59,6 @@ variable "origin_force_destroy" {
description = "Delete all objects from the bucket so that the bucket can be destroyed without error (e.g. `true` or `false`)"
}

variable "bucket_domain_format" {
type = string
default = "%s.s3.amazonaws.com"
description = "Format of bucket domain name"
}

variable "compress" {
type = bool
default = false
Expand Down Expand Up @@ -261,21 +249,6 @@ variable "dns_alias_enabled" {
description = "Create a DNS alias for the CDN. Requires `parent_zone_id` or `parent_zone_name`"
}

variable "static_s3_bucket" {
type = string
default = "aws-cli"

description = <<DOC
aws-cli is a bucket owned by amazon that will perminantly exist.
It allows for the data source to be called during the destruction process without failing.
It doesn't get used for anything else, this is a safe workaround for handling the fact that
if a data source like the one `aws_s3_bucket.selected` gets an error, you can't continue the terraform process
which also includes the 'destroy' command, where is doesn't even need this data source!
Don't change this bucket name, it's a variable so that we can provide this description.
And this works around a problem that is an edge case.
DOC
}

variable "custom_error_response" {
# http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/custom-error-pages.html#custom-error-pages-procedure
# https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#custom-error-response-arguments
Expand Down