Skip to content

Commit 19b011a

Browse files
authored
Enforce the usage of modern TLS versions (1.2 or higher) for S3 connections (#237)
* fix: Update Terraform version to match the version in variables.tf * feat: Enforce the usage of modern TLS versions (1.2 or higher) * refactor: Change input to minimum_tls_version * fix: Correct for_each * fix: Correct tests and add var.minimum_tls_version
1 parent 12da3ea commit 19b011a

File tree

8 files changed

+42
-3
lines changed

8 files changed

+42
-3
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
SHELL := /bin/bash
2-
export TERRAFORM_VERSION = 1.1.6
2+
export TERRAFORM_VERSION = 1.3.0
33

44
# List of targets the `readme` target should call before generating the readme
55
export README_DEPS ?= docs/targets.md docs/terraform.md
@@ -14,5 +14,5 @@ lint:
1414
test/%:
1515
@cd examples/complete && \
1616
terraform init && \
17-
terraform $* -var-file=fixtures.us-west-1.tfvars && \
18-
terraform $* -var-file=grants.us-west-1.tfvars
17+
terraform $* -var-file=fixtures.us-east-2.tfvars && \
18+
terraform $* -var-file=grants.us-east-2.tfvars

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ Available targets:
293293
| <a name="input_lifecycle_rule_ids"></a> [lifecycle\_rule\_ids](#input\_lifecycle\_rule\_ids) | DEPRECATED (use `lifecycle_configuration_rules`): A list of IDs to assign to corresponding `lifecycle_rules` | `list(string)` | `[]` | no |
294294
| <a name="input_lifecycle_rules"></a> [lifecycle\_rules](#input\_lifecycle\_rules) | DEPRECATED (`use lifecycle_configuration_rules`): A list of lifecycle rules | <pre>list(object({<br> prefix = string<br> enabled = bool<br> tags = map(string)<br><br> enable_glacier_transition = bool<br> enable_deeparchive_transition = bool<br> enable_standard_ia_transition = bool<br> enable_current_object_expiration = bool<br> enable_noncurrent_version_expiration = bool<br><br> abort_incomplete_multipart_upload_days = number<br> noncurrent_version_glacier_transition_days = number<br> noncurrent_version_deeparchive_transition_days = number<br> noncurrent_version_expiration_days = number<br><br> standard_transition_days = number<br> glacier_transition_days = number<br> deeparchive_transition_days = number<br> expiration_days = number<br> }))</pre> | `null` | no |
295295
| <a name="input_logging"></a> [logging](#input\_logging) | Bucket access logging configuration. Empty list for no logging, list of 1 to enable logging. | <pre>list(object({<br> bucket_name = string<br> prefix = string<br> }))</pre> | `[]` | no |
296+
| <a name="input_minimum_tls_version"></a> [minimum\_tls\_version](#input\_minimum\_tls\_version) | Set the minimum TLS version for in-transit traffic | `string` | `null` | no |
296297
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
297298
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
298299
| <a name="input_object_lock_configuration"></a> [object\_lock\_configuration](#input\_object\_lock\_configuration) | A configuration for S3 object locking. With S3 Object Lock, you can store objects using a `write once, read many` (WORM) model. Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. | <pre>object({<br> mode = string # Valid values are GOVERNANCE and COMPLIANCE.<br> days = number<br> years = number<br> })</pre> | `null` | no |

docs/terraform.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
| <a name="input_lifecycle_rule_ids"></a> [lifecycle\_rule\_ids](#input\_lifecycle\_rule\_ids) | DEPRECATED (use `lifecycle_configuration_rules`): A list of IDs to assign to corresponding `lifecycle_rules` | `list(string)` | `[]` | no |
8686
| <a name="input_lifecycle_rules"></a> [lifecycle\_rules](#input\_lifecycle\_rules) | DEPRECATED (`use lifecycle_configuration_rules`): A list of lifecycle rules | <pre>list(object({<br> prefix = string<br> enabled = bool<br> tags = map(string)<br><br> enable_glacier_transition = bool<br> enable_deeparchive_transition = bool<br> enable_standard_ia_transition = bool<br> enable_current_object_expiration = bool<br> enable_noncurrent_version_expiration = bool<br><br> abort_incomplete_multipart_upload_days = number<br> noncurrent_version_glacier_transition_days = number<br> noncurrent_version_deeparchive_transition_days = number<br> noncurrent_version_expiration_days = number<br><br> standard_transition_days = number<br> glacier_transition_days = number<br> deeparchive_transition_days = number<br> expiration_days = number<br> }))</pre> | `null` | no |
8787
| <a name="input_logging"></a> [logging](#input\_logging) | Bucket access logging configuration. Empty list for no logging, list of 1 to enable logging. | <pre>list(object({<br> bucket_name = string<br> prefix = string<br> }))</pre> | `[]` | no |
88+
| <a name="input_minimum_tls_version"></a> [minimum\_tls\_version](#input\_minimum\_tls\_version) | Set the minimum TLS version for in-transit traffic | `string` | `null` | no |
8889
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
8990
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
9091
| <a name="input_object_lock_configuration"></a> [object\_lock\_configuration](#input\_object\_lock\_configuration) | A configuration for S3 object locking. With S3 Object Lock, you can store objects using a `write once, read many` (WORM) model. Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. | <pre>object({<br> mode = string # Valid values are GOVERNANCE and COMPLIANCE.<br> days = number<br> years = number<br> })</pre> | `null` | no |

examples/complete/fixtures.us-east-2.tfvars

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ allowed_bucket_actions = [
2828
]
2929

3030
bucket_key_enabled = true
31+
32+
minimum_tls_version = "1.2"

examples/complete/main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module "s3_bucket" {
3434
block_public_policy = var.block_public_policy
3535
ignore_public_acls = var.ignore_public_acls
3636
restrict_public_buckets = var.restrict_public_buckets
37+
minimum_tls_version = var.minimum_tls_version
3738

3839
access_key_enabled = var.access_key_enabled
3940
store_access_key_in_ssm = var.store_access_key_in_ssm

examples/complete/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,9 @@ variable "transfer_acceleration_enabled" {
315315
default = true
316316
description = "Set true to enable Transfer Acceleration (many regions not supported)"
317317
}
318+
319+
variable "minimum_tls_version" {
320+
type = string
321+
default = null
322+
description = "Set the minimum TLS version for in-transit traffic"
323+
}

main.tf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,28 @@ data "aws_iam_policy_document" "bucket_policy" {
424424
}
425425
}
426426

427+
dynamic "statement" {
428+
for_each = var.minimum_tls_version != null ? toset([var.minimum_tls_version]) : toset([])
429+
430+
content {
431+
sid = "EnforceTLSVersion"
432+
effect = "Deny"
433+
actions = ["s3:*"]
434+
resources = [local.bucket_arn, "${local.bucket_arn}/*"]
435+
436+
principals {
437+
identifiers = ["*"]
438+
type = "*"
439+
}
440+
441+
condition {
442+
test = "NumericLessThan"
443+
values = [statement.value]
444+
variable = "s3:TlsVersion"
445+
}
446+
}
447+
}
448+
427449
dynamic "statement" {
428450
for_each = length(var.s3_replication_source_roles) > 0 ? [1] : []
429451

variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ variable "allow_ssl_requests_only" {
139139
nullable = false
140140
}
141141

142+
variable "minimum_tls_version" {
143+
type = string
144+
default = null
145+
description = "Set the minimum TLS version for in-transit traffic"
146+
}
147+
142148
variable "lifecycle_configuration_rules" {
143149
type = list(object({
144150
enabled = optional(bool, true)

0 commit comments

Comments
 (0)