Skip to content

Commit 7e5a104

Browse files
authored
Greater control over Access Logging (#161)
1 parent 7342c2e commit 7e5a104

File tree

10 files changed

+305
-98
lines changed

10 files changed

+305
-98
lines changed

README.md

Lines changed: 24 additions & 15 deletions
Large diffs are not rendered by default.

README.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ usage: |-
121121
For a variety of reasons, the web servers in a CDN do not work the way normal web servers work. Instead of getting
122122
their content from files on the local server, the CDN web servers get their content by acting like web browsers
123123
(proxies). When they get a request from a browser, they make the same request to what is called an "**Origin Server**".
124-
It is called an origin server because it _serves_ the original content of the web site, and thus is the _origin_
124+
It is called an origin server because it _serves_ the original content of the website, and thus is the _origin_
125125
of the content.
126126
127-
As a web site publisher, you put content on an Origin Server (which users usually should be prevented from accessing)
127+
As a website publisher, you put content on an Origin Server (which users usually should be prevented from accessing)
128128
and configure your CDN to use your Origin Server. Then you direct users to a URL hosted by your CDN provider, the
129129
users' browsers connect to the CDN, the CDN gets the content from your Origin Server, your Origin Server gets the
130130
content from a file on the server, and the data gets sent back hop by hop to the user. (The reason this ends up
@@ -141,16 +141,16 @@ usage: |-
141141
142142
However, at some point someone realized that since these files were in the cloud, and Amazon already had these web servers
143143
running to provide access to the files in the cloud, it was only a tiny leap to turn an S3 bucket into a web server.
144-
So now S3 buckets [can be published as web sites](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html)
144+
So now S3 buckets [can be published as websites](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html)
145145
with a few configuration settings, including making the contents publicly accessible.
146146
147147
#### Web servers, files, and the different modes of S3 buckets
148148
149-
In the simplest web sites, the URL "path" (the part after the site name) corresponds directly to the path (under
149+
In the simplest websites, the URL "path" (the part after the site name) corresponds directly to the path (under
150150
a special directory we will call `/webroot`) and name
151151
of a file on the web server. So if the web server gets a request for "http://example.com/foo/bar/baz.html" it will
152152
look for a file `/webroot/foo/bar/baz.html`. If it exists, the server will return its contents, and if it does not exist,
153-
the server will return a `Not Found` error. An S3 bucket, whether configured as a file store or a web site, will
153+
the server will return a `Not Found` error. An S3 bucket, whether configured as a file store or a website, will
154154
always do both of these things.
155155
156156
Web servers, however, do some helpful extra things. To name a few:
@@ -180,7 +180,7 @@ usage: |-
180180
and error documents. The disadvantage is that you have to make the entire bucket public (although you can still
181181
restrict access to some portions of the bucket).
182182
183-
Another feature or drawback (depending on your point of view) of S3 buckets configured as static web sites is that
183+
Another feature or drawback (depending on your point of view) of S3 buckets configured as static websites is that
184184
they are directly accessible via their [website endpoint](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteEndpoints.html)
185185
as well as through Cloudfront. This module has a feature, `s3_website_password_enabled`, that requires a password
186186
be passed in the HTTP request header and configures the CDN to do that, which will make it much harder to access

deprecated.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Phase out variables by changing the default to `null` and using the replacement variables when they are `null`
2+
locals {
3+
4+
s3_access_log_bucket_name = var.access_log_bucket_name == null ? var.s3_access_log_bucket_name : var.access_log_bucket_name
5+
6+
cloudfront_access_logging_enabled = local.enabled && (var.logging_enabled == null ? var.cloudfront_access_logging_enabled : var.logging_enabled)
7+
cloudfront_access_log_include_cookies = var.log_include_cookies == null ? var.cloudfront_access_log_include_cookies : var.log_include_cookies
8+
cloudfront_access_log_prefix = var.log_prefix == null ? var.cloudfront_access_log_prefix : var.log_prefix
9+
10+
# New variables, but declare them here for consistency
11+
cloudfront_access_log_create_bucket = var.cloudfront_access_log_create_bucket
12+
}
13+

docs/terraform.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737
| [aws_iam_policy_document.deployment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
3838
| [aws_iam_policy_document.s3_origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
3939
| [aws_iam_policy_document.s3_website_origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
40+
| [aws_s3_bucket.cf_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source |
4041
| [aws_s3_bucket.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source |
4142

4243
## Inputs
4344

4445
| Name | Description | Type | Default | Required |
4546
|------|-------------|------|---------|:--------:|
46-
| <a name="input_access_log_bucket_name"></a> [access\_log\_bucket\_name](#input\_access\_log\_bucket\_name) | Name of the S3 bucket where s3 access log will be sent to | `string` | `""` | no |
47+
| <a name="input_access_log_bucket_name"></a> [access\_log\_bucket\_name](#input\_access\_log\_bucket\_name) | DEPRECATED. Use `s3_access_log_bucket_name` instead. | `string` | `null` | no |
4748
| <a name="input_acm_certificate_arn"></a> [acm\_certificate\_arn](#input\_acm\_certificate\_arn) | Existing ACM Certificate ARN | `string` | `""` | no |
4849
| <a name="input_additional_bucket_policy"></a> [additional\_bucket\_policy](#input\_additional\_bucket\_policy) | Additional policies for the bucket. If included in the policies, the variables `${bucket_name}`, `${origin_path}` and `${cloudfront_origin_access_identity_iam_arn}` will be substituted. It is also possible to override the default policy statements by providing statements with `S3GetObjectForCloudFront` and `S3ListBucketForCloudFront` sid. | `string` | `"{}"` | no |
4950
| <a name="input_additional_tag_map"></a> [additional\_tag\_map](#input\_additional\_tag\_map) | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
@@ -53,6 +54,11 @@
5354
| <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 |
5455
| <a name="input_cache_policy_id"></a> [cache\_policy\_id](#input\_cache\_policy\_id) | The unique identifier of the existing cache policy to attach to the default cache behavior.<br>If not provided, this module will add a default cache policy using other provided inputs. | `string` | `null` | no |
5556
| <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 |
57+
| <a name="input_cloudfront_access_log_bucket_name"></a> [cloudfront\_access\_log\_bucket\_name](#input\_cloudfront\_access\_log\_bucket\_name) | When `cloudfront_access_log_create_bucket` is `false`, this is the name of the existing S3 Bucket where<br>Cloudfront Access Logs are to be delivered and is required. IGNORED when `cloudfront_access_log_create_bucket` is `true`. | `string` | `""` | no |
58+
| <a name="input_cloudfront_access_log_create_bucket"></a> [cloudfront\_access\_log\_create\_bucket](#input\_cloudfront\_access\_log\_create\_bucket) | When `true` and `cloudfront_access_logging_enabled` is also true, this module will create a new,<br>separate S3 bucket to receive Cloudfront Access Logs. | `bool` | `true` | no |
59+
| <a name="input_cloudfront_access_log_include_cookies"></a> [cloudfront\_access\_log\_include\_cookies](#input\_cloudfront\_access\_log\_include\_cookies) | Set true to include cookies in Cloudfront Access Logs | `bool` | `false` | no |
60+
| <a name="input_cloudfront_access_log_prefix"></a> [cloudfront\_access\_log\_prefix](#input\_cloudfront\_access\_log\_prefix) | Prefix to use for Cloudfront Access Log object keys. Defaults to no prefix. | `string` | `""` | no |
61+
| <a name="input_cloudfront_access_logging_enabled"></a> [cloudfront\_access\_logging\_enabled](#input\_cloudfront\_access\_logging\_enabled) | Set true to enable delivery of Cloudfront Access Logs to an S3 bucket | `bool` | `true` | no |
5662
| <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 |
5763
| <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 |
5864
| <a name="input_comment"></a> [comment](#input\_comment) | Comment for the origin access identity | `string` | `"Managed by Terraform"` | no |
@@ -77,7 +83,7 @@
7783
| <a name="input_encryption_enabled"></a> [encryption\_enabled](#input\_encryption\_enabled) | When set to 'true' the resource will have aes256 encryption enabled by default | `bool` | `true` | no |
7884
| <a name="input_environment"></a> [environment](#input\_environment) | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
7985
| <a name="input_error_document"></a> [error\_document](#input\_error\_document) | An absolute path to the document to return in case of a 4XX error | `string` | `""` | no |
80-
| <a name="input_extra_logs_attributes"></a> [extra\_logs\_attributes](#input\_extra\_logs\_attributes) | Additional attributes to put onto the log bucket label | `list(string)` | <pre>[<br> "logs"<br>]</pre> | no |
86+
| <a name="input_extra_logs_attributes"></a> [extra\_logs\_attributes](#input\_extra\_logs\_attributes) | Additional attributes to add to the end of the generated Cloudfront Access Log S3 Bucket name.<br>Only effective if `cloudfront_access_log_create_bucket` is `true`. | `list(string)` | <pre>[<br> "logs"<br>]</pre> | no |
8187
| <a name="input_extra_origin_attributes"></a> [extra\_origin\_attributes](#input\_extra\_origin\_attributes) | Additional attributes to put onto the origin label | `list(string)` | <pre>[<br> "origin"<br>]</pre> | no |
8288
| <a name="input_forward_cookies"></a> [forward\_cookies](#input\_forward\_cookies) | Specifies whether you want CloudFront to forward all or no cookies to the origin. Can be 'all' or 'none' | `string` | `"none"` | no |
8389
| <a name="input_forward_header_values"></a> [forward\_header\_values](#input\_forward\_header\_values) | A list of whitelisted header values to forward to the origin (incompatible with `cache_policy_id`) | `list(string)` | <pre>[<br> "Access-Control-Request-Headers",<br> "Access-Control-Request-Method",<br> "Origin"<br>]</pre> | no |
@@ -91,13 +97,13 @@
9197
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The naming order of the id output and Name tag.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no |
9298
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | The letter case of output label values (also used in `tags` and `id`).<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Default value: `lower`. | `string` | `null` | no |
9399
| <a name="input_lambda_function_association"></a> [lambda\_function\_association](#input\_lambda\_function\_association) | A config block that triggers a lambda function with specific actions | <pre>list(object({<br> event_type = string<br> include_body = bool<br> lambda_arn = string<br> }))</pre> | `[]` | no |
94-
| <a name="input_log_expiration_days"></a> [log\_expiration\_days](#input\_log\_expiration\_days) | Number of days after which to expunge the objects | `number` | `90` | no |
95-
| <a name="input_log_glacier_transition_days"></a> [log\_glacier\_transition\_days](#input\_log\_glacier\_transition\_days) | Number of days after which to move the data to the glacier storage tier | `number` | `60` | no |
96-
| <a name="input_log_include_cookies"></a> [log\_include\_cookies](#input\_log\_include\_cookies) | Include cookies in access logs | `bool` | `false` | no |
97-
| <a name="input_log_prefix"></a> [log\_prefix](#input\_log\_prefix) | Path of logs in S3 bucket | `string` | `""` | no |
98-
| <a name="input_log_standard_transition_days"></a> [log\_standard\_transition\_days](#input\_log\_standard\_transition\_days) | Number of days to persist in the standard storage tier before moving to the glacier tier | `number` | `30` | no |
99-
| <a name="input_log_versioning_enabled"></a> [log\_versioning\_enabled](#input\_log\_versioning\_enabled) | When true, the access logs bucket will be versioned | `bool` | `false` | no |
100-
| <a name="input_logging_enabled"></a> [logging\_enabled](#input\_logging\_enabled) | When true, access logs will be sent to a newly created s3 bucket | `bool` | `true` | no |
100+
| <a name="input_log_expiration_days"></a> [log\_expiration\_days](#input\_log\_expiration\_days) | Number of days after object creation to expire Cloudfront Access Log objects.<br>Only effective if `cloudfront_access_log_create_bucket` is `true`. | `number` | `90` | no |
101+
| <a name="input_log_glacier_transition_days"></a> [log\_glacier\_transition\_days](#input\_log\_glacier\_transition\_days) | Number of days after object creation to move Cloudfront Access Log objects to the glacier tier.<br>Only effective if `cloudfront_access_log_create_bucket` is `true`. | `number` | `60` | no |
102+
| <a name="input_log_include_cookies"></a> [log\_include\_cookies](#input\_log\_include\_cookies) | DEPRECATED. Use `cloudfront_access_log_include_cookies` instead. | `bool` | `null` | no |
103+
| <a name="input_log_prefix"></a> [log\_prefix](#input\_log\_prefix) | DEPRECATED. Use `cloudfront_access_log_prefix` instead. | `string` | `null` | no |
104+
| <a name="input_log_standard_transition_days"></a> [log\_standard\_transition\_days](#input\_log\_standard\_transition\_days) | Number of days after object creation to move Cloudfront Access Log objects to the infrequent access tier.<br>Only effective if `cloudfront_access_log_create_bucket` is `true`. | `number` | `30` | no |
105+
| <a name="input_log_versioning_enabled"></a> [log\_versioning\_enabled](#input\_log\_versioning\_enabled) | Set `true` to enable object versioning in the created Cloudfront Access Log S3 Bucket.<br>Only effective if `cloudfront_access_log_create_bucket` is `true`. | `bool` | `false` | no |
106+
| <a name="input_logging_enabled"></a> [logging\_enabled](#input\_logging\_enabled) | DEPRECATED. Use `cloudfront_access_logging_enabled` instead. | `bool` | `null` | no |
101107
| <a name="input_max_ttl"></a> [max\_ttl](#input\_max\_ttl) | Maximum amount of time (in seconds) that an object is in a CloudFront cache | `number` | `31536000` | no |
102108
| <a name="input_min_ttl"></a> [min\_ttl](#input\_min\_ttl) | Minimum amount of time that you want objects to stay in CloudFront caches | `number` | `0` | no |
103109
| <a name="input_minimum_protocol_version"></a> [minimum\_protocol\_version](#input\_minimum\_protocol\_version) | Cloudfront TLS minimum protocol version. See [Supported protocols and ciphers between viewers and CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/secure-connections-supported-viewer-protocols-ciphers.html#secure-connections-supported-ciphers) for more information. | `string` | `"TLSv1.2_2019"` | no |
@@ -116,6 +122,9 @@
116122
| <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 |
117123
| <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 |
118124
| <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 |
125+
| <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` | `"foo"` | no |
126+
| <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 |
127+
| <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 |
119128
| <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 |
120129
| <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 |
121130
| <a name="input_stage"></a> [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |

0 commit comments

Comments
 (0)