Skip to content

Commit 911db9b

Browse files
Feat: Add Support for S3 Object Ownership Controls (#209)
- Add support for S3 object ownership controls. - Misc: add BridgeCrew exceptions. Co-authored-by: cloudpossebot <[email protected]>
1 parent 69ce9db commit 911db9b

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,13 +438,15 @@ Available targets:
438438
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
439439
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.41.0 |
440440
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.2 |
441+
| <a name="requirement_time"></a> [time](#requirement\_time) | >= 0.7 |
441442

442443
## Providers
443444

444445
| Name | Version |
445446
|------|---------|
446447
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.41.0 |
447448
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.2 |
449+
| <a name="provider_time"></a> [time](#provider\_time) | >= 0.7 |
448450

449451
## Modules
450452

@@ -462,9 +464,11 @@ Available targets:
462464
| [aws_cloudfront_distribution.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |
463465
| [aws_cloudfront_origin_access_identity.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_identity) | resource |
464466
| [aws_s3_bucket.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
467+
| [aws_s3_bucket_ownership_controls.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource |
465468
| [aws_s3_bucket_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
466469
| [aws_s3_bucket_public_access_block.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
467470
| [random_password.referer](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
471+
| [time_sleep.wait_for_aws_s3_bucket_settings](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
468472
| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
469473
| [aws_iam_policy_document.deployment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
470474
| [aws_iam_policy_document.s3_origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
@@ -568,6 +572,7 @@ Available targets:
568572
| <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 |
569573
| <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 |
570574
| <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 |
575+
| <a name="input_s3_object_ownership"></a> [s3\_object\_ownership](#input\_s3\_object\_ownership) | Specifies the S3 object ownership control on the origin bucket. Valid values are `ObjectWriter`, `BucketOwnerPreferred`, and 'BucketOwnerEnforced'. | `string` | `"ObjectWriter"` | no |
571576
| <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 |
572577
| <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 |
573578
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |

docs/terraform.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
77
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.41.0 |
88
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.2 |
9+
| <a name="requirement_time"></a> [time](#requirement\_time) | >= 0.7 |
910

1011
## Providers
1112

1213
| Name | Version |
1314
|------|---------|
1415
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.41.0 |
1516
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.2 |
17+
| <a name="provider_time"></a> [time](#provider\_time) | >= 0.7 |
1618

1719
## Modules
1820

@@ -30,9 +32,11 @@
3032
| [aws_cloudfront_distribution.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |
3133
| [aws_cloudfront_origin_access_identity.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_identity) | resource |
3234
| [aws_s3_bucket.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
35+
| [aws_s3_bucket_ownership_controls.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource |
3336
| [aws_s3_bucket_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
3437
| [aws_s3_bucket_public_access_block.origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
3538
| [random_password.referer](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
39+
| [time_sleep.wait_for_aws_s3_bucket_settings](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
3640
| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
3741
| [aws_iam_policy_document.deployment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
3842
| [aws_iam_policy_document.s3_origin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
@@ -136,6 +140,7 @@
136140
| <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 |
137141
| <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 |
138142
| <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 |
143+
| <a name="input_s3_object_ownership"></a> [s3\_object\_ownership](#input\_s3\_object\_ownership) | Specifies the S3 object ownership control on the origin bucket. Valid values are `ObjectWriter`, `BucketOwnerPreferred`, and 'BucketOwnerEnforced'. | `string` | `"ObjectWriter"` | no |
139144
| <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 |
140145
| <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 |
141146
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |

main.tf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,28 @@ resource "aws_s3_bucket_public_access_block" "origin" {
300300
depends_on = [aws_s3_bucket_policy.default]
301301
}
302302

303+
resource "aws_s3_bucket_ownership_controls" "origin" {
304+
count = local.create_s3_origin_bucket ? 1 : 0
305+
306+
bucket = local.bucket
307+
308+
rule {
309+
object_ownership = var.s3_object_ownership
310+
}
311+
312+
depends_on = [time_sleep.wait_for_aws_s3_bucket_settings]
313+
}
314+
315+
# Workaround for S3 eventual consistency for settings relating to objects
316+
resource "time_sleep" "wait_for_aws_s3_bucket_settings" {
317+
count = local.create_s3_origin_bucket ? 1 : 0
318+
319+
create_duration = "30s"
320+
destroy_duration = "30s"
321+
322+
depends_on = [aws_s3_bucket_public_access_block.origin, aws_s3_bucket_policy.default]
323+
}
324+
303325
module "logs" {
304326
source = "cloudposse/s3-log-storage/aws"
305327
version = "0.26.0"
@@ -327,6 +349,8 @@ data "aws_s3_bucket" "cf_logs" {
327349

328350
resource "aws_cloudfront_distribution" "default" {
329351
#bridgecrew:skip=BC_AWS_GENERAL_27:Skipping `Ensure CloudFront distribution has WAF enabled` because AWS WAF is indeed configurable and is managed via `var.web_acl_id`.
352+
#bridgecrew:skip=BC_AWS_NETWORKING_63:Skipping `Verify CloudFront Distribution Viewer Certificate is using TLS v1.2` because the minimum TLS version for the viewer certificate is indeed configurable and is managed via `var.minimum_protocol_version`.
353+
#bridgecrew:skip=BC_AWS_NETWORKING_65:Skipping `Ensure CloudFront distribution has a strict security headers policy attached` because the response header policy is indeed configurable and is managed via `var.response_headers_policy_id`.
330354
count = local.enabled ? 1 : 0
331355

332356
enabled = var.distribution_enabled

variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,12 @@ variable "s3_access_log_prefix" {
540540
description = "Prefix to use for S3 Access Log object keys. Defaults to `logs/$${module.this.id}`"
541541
}
542542

543+
variable "s3_object_ownership" {
544+
type = string
545+
default = "ObjectWriter"
546+
description = "Specifies the S3 object ownership control on the origin bucket. Valid values are `ObjectWriter`, `BucketOwnerPreferred`, and 'BucketOwnerEnforced'."
547+
}
548+
543549
variable "cloudfront_access_logging_enabled" {
544550
type = bool
545551
default = true

versions.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@ terraform {
1010
source = "hashicorp/random"
1111
version = ">= 2.2"
1212
}
13+
time = {
14+
source = "hashicorp/time"
15+
version = ">= 0.7"
16+
}
1317
}
1418
}

0 commit comments

Comments
 (0)