Skip to content

Commit 6ddaa3c

Browse files
authored
Merge branch 'main' into main
2 parents fe0a188 + f3b5145 commit 6ddaa3c

File tree

8 files changed

+203
-356
lines changed

8 files changed

+203
-356
lines changed

.github/mergify.yml

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1 @@
1-
# https://docs.mergify.io/conditions.html
2-
# https://docs.mergify.io/actions.html
3-
pull_request_rules:
4-
- name: "approve automated PRs that have passed checks"
5-
conditions:
6-
- "author~=^(cloudpossebot|renovate\\[bot\\])$"
7-
- "-closed"
8-
- "head~=^(auto-update|renovate)/.*"
9-
- "check-success=test/bats"
10-
- "check-success=test/readme"
11-
- "check-success=test/terratest"
12-
- "check-success=validate-codeowners"
13-
- or:
14-
- "base=master"
15-
- "base=main"
16-
- "base~=^release/v\\d{1,2}$"
17-
18-
actions:
19-
review:
20-
type: "APPROVE"
21-
bot_account: "cloudposse-mergebot"
22-
message: "We've automatically approved this PR because the checks from the automated Pull Request have passed."
23-
24-
- name: "merge automated PRs when approved and tests pass"
25-
conditions:
26-
- "author~=^(cloudpossebot|renovate\\[bot\\])$"
27-
- "-closed"
28-
- "head~=^(auto-update|renovate)/.*"
29-
- "check-success=test/bats"
30-
- "check-success=test/readme"
31-
- "check-success=test/terratest"
32-
- "check-success=validate-codeowners"
33-
- "#approved-reviews-by>=1"
34-
- "#changes-requested-reviews-by=0"
35-
- "#commented-reviews-by=0"
36-
- or:
37-
- "base=master"
38-
- "base=main"
39-
- "base~=^release/v\\d{1,2}$"
40-
41-
actions:
42-
merge:
43-
method: "squash"
44-
45-
- name: "delete the head branch after merge"
46-
conditions:
47-
- "merged"
48-
actions:
49-
delete_head_branch: {}
50-
51-
- name: "ask to resolve conflict"
52-
conditions:
53-
- "conflict"
54-
- "-closed"
55-
actions:
56-
comment:
57-
message: "This pull request is now in conflict. Could you fix it @{{author}}? 🙏"
58-
59-
- name: "remove outdated reviews"
60-
conditions:
61-
- or:
62-
- "base=master"
63-
- "base=main"
64-
- "base~=^release/v\\d{1,2}$"
65-
actions:
66-
dismiss_reviews:
67-
changes_requested: true
68-
approved: true
69-
message: "This Pull Request has been updated, so we're dismissing all reviews."
70-
71-
- name: "close Pull Requests without files changed"
72-
conditions:
73-
- "#files=0"
74-
actions:
75-
close:
76-
message: "This pull request has been automatically closed by Mergify because there are no longer any changes."
1+
extends: .github

.github/settings.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Upstream changes from _extends are only recognized when modifications are made to this file in the default branch.
2+
_extends: .github
3+
repository:
4+
name: terraform-aws-cloudfront-s3-cdn
5+
description: Terraform module to easily provision CloudFront CDN backed by an S3 origin
6+
homepage: https://cloudposse.com/accelerate
7+
topics: terraform, terraform-module, cloudfront, aws, cloudfront-logs, s3, cdn, hcl2

README.md

Lines changed: 106 additions & 210 deletions
Large diffs are not rendered by default.

README.yaml

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
---
21
#
32
# This is the canonical configuration for the `README.md`
43
# To rebuild `README.md`:
@@ -34,16 +33,17 @@ github_repo: cloudposse/terraform-aws-cloudfront-s3-cdn
3433

3534
# Badges to display
3635
badges:
37-
- name: "Codefresh Build Status"
38-
image: "https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-cloudfront-s3-cdn?type=cf-1"
39-
url: "https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d169121757962ff25679794"
40-
- name: "Latest Release"
41-
image: "https://img.shields.io/github/release/cloudposse/terraform-aws-cloudfront-s3-cdn.svg"
42-
url: "https://travis-ci.org/cloudposse/terraform-aws-cloudfront-s3-cdn/releases"
43-
- name: "Slack Community"
44-
image: "https://slack.cloudposse.com/badge.svg"
45-
url: "https://slack.cloudposse.com"
46-
36+
- name: Latest Release
37+
image: https://img.shields.io/github/release/cloudposse/terraform-aws-cloudfront-s3-cdn.svg?style=for-the-badge
38+
url: https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn/releases/latest
39+
- name: Last Updated
40+
image: https://img.shields.io/github/last-commit/cloudposse/terraform-aws-cloudfront-s3-cdn.svg?style=for-the-badge
41+
url: https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn/commits
42+
- name: Slack Community
43+
image: https://slack.cloudposse.com/for-the-badge.svg
44+
url: https://slack.cloudposse.com
45+
46+
# List any related terraform modules that this module may be used with or that this module depends on.
4747
related:
4848
- name: "terraform-aws-cloudfront-cdn"
4949
description: "Terraform Module that implements a CloudFront Distribution (CDN) for a custom origin."
@@ -57,7 +57,7 @@ description: |-
5757
Terraform module to provision an AWS CloudFront CDN with an S3 origin.
5858
5959
# How to use this project
60-
usage: |-
60+
usage: |2-
6161
6262
For a complete example, see [examples/complete](examples/complete).
6363
@@ -143,57 +143,57 @@ usage: |-
143143
```
144144
145145
### Background on CDNs, "Origins", S3 Buckets, and Web Servers
146-
146+
147147
#### CDNs and Origin Servers
148-
148+
149149
There are some settings you need to be aware of when using this module. In order to understand the settings,
150150
you need to understand some of the basics of CDNs and web servers, so we are providing this _highly simplified_
151151
explanation of how they work in order for you to understand the implications of the settings you are providing.
152-
152+
153153
A "**CDN**" ([Content Distribution Network](https://www.cloudflare.com/learning/cdn/what-is-a-cdn/)) is a collection of
154154
servers scattered around the internet with the aim of making it faster for people to retrieve content from a website.
155155
The details of why that is wanted/needed are beyond the scope of this document, as are most of the details of how
156156
a CDN is implemented. For this discussion, we will simply treat a CDN as a set of web servers all serving
157157
the same content to different users.
158-
158+
159159
In a normal web server (again, greatly simplified), you place files on the server and the web server software receives
160160
requests from browsers and responds with the contents of the files.
161-
161+
162162
For a variety of reasons, the web servers in a CDN do not work the way normal web servers work. Instead of getting
163163
their content from files on the local server, the CDN web servers get their content by acting like web browsers
164164
(proxies). When they get a request from a browser, they make the same request to what is called an "**Origin Server**".
165165
It is called an origin server because it _serves_ the original content of the website, and thus is the _origin_
166166
of the content.
167-
167+
168168
As a website publisher, you put content on an Origin Server (which users usually should be prevented from accessing)
169169
and configure your CDN to use your Origin Server. Then you direct users to a URL hosted by your CDN provider, the
170170
users' browsers connect to the CDN, the CDN gets the content from your Origin Server, your Origin Server gets the
171171
content from a file on the server, and the data gets sent back hop by hop to the user. (The reason this ends up
172172
being a good idea is that the CDN can cache the content for a while, serving multiple users the same content while
173173
only contacting the origin server once.)
174-
174+
175175
#### S3 Buckets: file storage and web server
176-
176+
177177
S3 buckets were originally designed just to store files, and they are still most often used for that. The have a lot
178178
of access controls to make it possible to strictly limit who can read what files in the bucket, so that companies
179179
can store sensitive information there. You may have heard of a number of "data breaches" being caused by misconfigured
180180
permissions on S3 buckets, making them publicly accessible. As a result of that, Amazon has some extra settings on
181181
top of everything else to keep S3 buckets from being publicly accessible, which is usually a good thing.
182-
182+
183183
However, at some point someone realized that since these files were in the cloud, and Amazon already had these web servers
184184
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.
185185
So now S3 buckets [can be published as websites](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html)
186186
with a few configuration settings, including making the contents publicly accessible.
187-
187+
188188
#### Web servers, files, and the different modes of S3 buckets
189-
189+
190190
In the simplest websites, the URL "path" (the part after the site name) corresponds directly to the path (under
191191
a special directory we will call `/webroot`) and name
192192
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
193193
look for a file `/webroot/foo/bar/baz.html`. If it exists, the server will return its contents, and if it does not exist,
194194
the server will return a `Not Found` error. An S3 bucket, whether configured as a file store or a website, will
195195
always do both of these things.
196-
196+
197197
Web servers, however, do some helpful extra things. To name a few:
198198
- If the URL ends with a `/`, as in `http://example.com/foo/bar/`, the web server (depending on how it is configured)
199199
will either return a list of files in the directory or it will return the contents of a file in the directory with
@@ -204,41 +204,41 @@ usage: |-
204204
turns out to be quite helpful.
205205
- If the URL does not point to a directory or a file, instead of just sending back a cryptic `Not Found` error code,
206206
it can return the contents of a special file called an "error document".
207-
207+
208208
#### Your Critical Decision: S3 bucket or website?
209-
209+
210210
All of this background is to help you decide how to set `website_enabled` and `s3_website_password_enabled`.
211211
The default for `website_enabled` is `false` which is the easiest to configure and the most secure, and with
212212
this setting, `s3_website_password_enabled` is ignored.
213-
213+
214214
S3 buckets, in file storage mode (`website_enabled = false`), do none of these extra things that web servers do.
215215
If the URL points to a file, it will return the file, and if it does not _exactly_ match a file, it will return
216216
`Not Found`. One big advantage, though, is that the S3 bucket can remain private (not publicly accessible). A second,
217217
related advantage is that you can limit the website to a portion of the S3 bucket (everything under a certain prefix)
218218
and keep the contents under the the other prefixes private.
219-
219+
220220
S3 buckets configured as static websites (`website_enabled = true`), however, have these extra web server features like redirects, `index.html`,
221221
and error documents. The disadvantage is that you have to make the entire bucket public (although you can still
222222
restrict access to some portions of the bucket).
223-
223+
224224
Another feature or drawback (depending on your point of view) of S3 buckets configured as static websites is that
225225
they are directly accessible via their [website endpoint](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteEndpoints.html)
226226
as well as through Cloudfront. This module has a feature, `s3_website_password_enabled`, that requires a password
227227
be passed in the HTTP request header and configures the CDN to do that, which will make it much harder to access
228228
the S3 website directly. So set `s3_website_password_enabled = true` to limit direct access to the S3 website
229229
or set it to false if you want to be able to bypass Cloudfront when you want to.
230-
230+
231231
In addition to setting `website_enabled=true`, you must also:
232232
233233
* Specify at least one `aliases`, like `["example.com"]` or
234234
`["example.com", "www.example.com"]`
235235
* Specify an ACM certificate
236236
237237
### Custom Domain Names and Generating a TLS Certificate with ACM
238-
238+
239239
When you set up Cloudfront, Amazon will generate a domain name for your website. You amost certainly will not
240240
want to publish that. Instead, you will want to use a custom domain name. This module refers to them as "aliases".
241-
241+
242242
To use the custom domain names, you need to
243243
- Pass them in as `aliases` so that Cloudfront will respond to them with your content
244244
- Create CNAMEs for the aliases to point to the Cloudfront domain name. If your alias domains are hosted by
@@ -383,22 +383,4 @@ include:
383383
- "docs/terraform.md"
384384

385385
# Contributors to this project
386-
contributors:
387-
- name: "Erik Osterman"
388-
github: "osterman"
389-
- name: "Andriy Knysh"
390-
github: "aknysh"
391-
- name: "Jamie Nelson"
392-
github: "Jamie-BitFlight"
393-
- name: "Clive Zagno"
394-
github: "cliveza"
395-
- name: "David Mattia"
396-
github: "dmattia"
397-
- name: "RB"
398-
github: "nitrocode"
399-
- name: "John McGehee"
400-
github: "jmcgeheeiv"
401-
- name: "Yonatan Koren"
402-
github: "korenyoni"
403-
- name: "Lucas Caparelli"
404-
github: "lcaparelli"
386+
contributors: []

docs/terraform.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@
3232
| [aws_cloudfront_distribution.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |
3333
| [aws_cloudfront_origin_access_identity.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_identity) | resource |
3434
| [aws_s3_bucket.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
35+
| [aws_s3_bucket_acl.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource |
36+
| [aws_s3_bucket_cors_configuration.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_cors_configuration) | resource |
3537
| [aws_s3_bucket_ownership_controls.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource |
3638
| [aws_s3_bucket_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
3739
| [aws_s3_bucket_public_access_block.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
40+
| [aws_s3_bucket_server_side_encryption_configuration.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
41+
| [aws_s3_bucket_versioning.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
3842
| [random_password.referer](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
3943
| [time_sleep.wait_for_aws_s3_bucket_settings](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
4044
| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
@@ -60,6 +64,7 @@
6064
| <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 |
6165
| <a name="input_attributes"></a> [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,<br>in the order they appear in the list. New attributes are appended to the<br>end of the list. The elements of the list are joined by the `delimiter`<br>and treated as a single ID element. | `list(string)` | `[]` | no |
6266
| <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 |
67+
| <a name="input_bucket_versioning"></a> [bucket\_versioning](#input\_bucket\_versioning) | State of bucket versioning option | `string` | `"Disabled"` | no |
6368
| <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 |
6469
| <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 |
6570
| <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 |

main.tf

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -254,26 +254,9 @@ resource "aws_s3_bucket" "origin" {
254254
count = local.create_s3_origin_bucket ? 1 : 0
255255

256256
bucket = module.origin_label.id
257-
acl = "private"
258257
tags = module.origin_label.tags
259258
force_destroy = var.origin_force_destroy
260259

261-
dynamic "server_side_encryption_configuration" {
262-
for_each = var.encryption_enabled ? ["true"] : []
263-
264-
content {
265-
rule {
266-
apply_server_side_encryption_by_default {
267-
sse_algorithm = "AES256"
268-
}
269-
}
270-
}
271-
}
272-
273-
versioning {
274-
enabled = var.versioning_enabled
275-
}
276-
277260
dynamic "logging" {
278261
for_each = local.s3_access_logging_enabled ? [1] : []
279262
content {
@@ -291,6 +274,35 @@ resource "aws_s3_bucket" "origin" {
291274
routing_rules = lookup(website.value, "routing_rules", null)
292275
}
293276
}
277+
}
278+
279+
280+
resource "aws_s3_bucket_versioning" "origin" {
281+
count = local.create_s3_origin_bucket ? 1 : 0
282+
283+
bucket = one(aws_s3_bucket.origin).id
284+
285+
versioning_configuration {
286+
status = var.bucket_versioning
287+
}
288+
}
289+
290+
resource "aws_s3_bucket_server_side_encryption_configuration" "origin" {
291+
count = var.encryption_enabled && local.create_s3_origin_bucket ? 1 : 0
292+
293+
bucket = one(aws_s3_bucket.origin).id
294+
295+
rule {
296+
apply_server_side_encryption_by_default {
297+
sse_algorithm = "AES256"
298+
}
299+
}
300+
}
301+
302+
resource "aws_s3_bucket_cors_configuration" "origin" {
303+
count = local.create_s3_origin_bucket ? 1 : 0
304+
305+
bucket = one(aws_s3_bucket.origin).id
294306

295307
dynamic "cors_rule" {
296308
for_each = distinct(compact(concat(var.cors_allowed_origins, var.aliases, var.external_aliases)))
@@ -304,6 +316,15 @@ resource "aws_s3_bucket" "origin" {
304316
}
305317
}
306318

319+
resource "aws_s3_bucket_acl" "origin" {
320+
depends_on = [aws_s3_bucket_ownership_controls.origin]
321+
count = local.create_s3_origin_bucket && var.s3_object_ownership != "BucketOwnerEnforced" ? 1 : 0
322+
323+
bucket = one(aws_s3_bucket.origin).id
324+
acl = "private"
325+
}
326+
327+
307328
resource "aws_s3_bucket_public_access_block" "origin" {
308329
count = (local.create_s3_origin_bucket || local.override_origin_bucket_policy) ? 1 : 0
309330

modules/lambda@edge/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module "role" {
4848
for_each = local.functions
4949

5050
source = "cloudposse/iam-role/aws"
51-
version = "0.16.0"
51+
version = "0.19.0"
5252

5353
use_fullname = true
5454
policy_description = "Allow ${module.function_label[each.key].id} Lambda function to write to CloudWatch Logs"

0 commit comments

Comments
 (0)