diff --git a/_example/complete/example.tf b/_example/complete/example.tf index 2f9332e..d68cf5a 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -93,7 +93,7 @@ module "s3_bucket" { name = "arcx-13" environment = local.environment label_order = local.label_order - s3_name = "" + s3_name = "sedfdrg" #acceleration and request payer enable or disable. acceleration_status = true @@ -132,6 +132,60 @@ module "s3_bucket" { } ] + intelligent_tiering = { + general = { + status = "Enabled" + filter = { + prefix = "/" + tags = { + Environment = "dev" + } + } + tiering = { + ARCHIVE_ACCESS = { + days = 180 + } + } + }, + documents = { + status = false + filter = { + prefix = "documents/" + } + tiering = { + ARCHIVE_ACCESS = { + days = 125 + } + DEEP_ARCHIVE_ACCESS = { + days = 200 + } + } + } + } + + metric_configuration = [ + { + name = "documents" + filter = { + prefix = "documents/" + tags = { + priority = "high" + } + } + }, + { + name = "other" + filter = { + tags = { + production = "true" + } + } + }, + { + name = "all" + } + ] + #cross replicaton of s3 cors_rule = [{ allowed_headers = ["*"], @@ -221,5 +275,4 @@ module "s3_bucket" { } }] } - } diff --git a/_example/cors_s3/example.tf b/_example/cors_s3/example.tf index f3516fe..8abe526 100644 --- a/_example/cors_s3/example.tf +++ b/_example/cors_s3/example.tf @@ -19,7 +19,7 @@ module "s3_bucket" { name = "clouddrove-secure-bucket" environment = local.environment label_order = local.label_order - s3_name = "ghehgfrehfg" + s3_name = "sdfdfg" versioning = true diff --git a/_example/default-s3/example.tf b/_example/default-s3/example.tf index 32991f5..edb86d4 100644 --- a/_example/default-s3/example.tf +++ b/_example/default-s3/example.tf @@ -19,7 +19,7 @@ module "s3_bucket" { name = "clouddrove-secure-bucket" environment = local.environment label_order = local.label_order - s3_name = "" + s3_name = "cdkc" acl = "private" versioning = true } \ No newline at end of file diff --git a/_example/encryption-s3/example.tf b/_example/encryption-s3/example.tf index 5fc9bc0..e64b212 100644 --- a/_example/encryption-s3/example.tf +++ b/_example/encryption-s3/example.tf @@ -52,7 +52,7 @@ module "s3_bucket" { source = "./../../" name = "clouddrove-encryption-bucket" - s3_name = "" + s3_name = "dmzx" environment = local.environment label_order = local.label_order diff --git a/_example/logging-encryption-s3/example.tf b/_example/logging-encryption-s3/example.tf index 682f542..09020ba 100644 --- a/_example/logging-encryption-s3/example.tf +++ b/_example/logging-encryption-s3/example.tf @@ -17,7 +17,7 @@ module "logging_bucket" { source = "./../../" name = "logging" - s3_name = "" + s3_name = "quya" environment = local.environment label_order = local.label_order acl = "log-delivery-write" @@ -65,7 +65,7 @@ module "s3_bucket" { source = "./../../" name = "clouddrove-logging-encryption-bucket" - s3_name = "" + s3_name = "aqua" environment = local.environment label_order = local.label_order diff --git a/_example/logging-s3/example.tf b/_example/logging-s3/example.tf index b3ad817..2446874 100644 --- a/_example/logging-s3/example.tf +++ b/_example/logging-s3/example.tf @@ -17,7 +17,7 @@ module "logging_bucket" { source = "./../../" name = "logging-s3-test" - s3_name = "" + s3_name = "zanq" environment = local.environment label_order = local.label_order acl = "log-delivery-write" @@ -30,7 +30,7 @@ module "s3_bucket" { source = "./../../" name = "clouddrove-logging-bucket" - s3_name = "" + s3_name = "wewrrt" environment = local.environment label_order = local.label_order diff --git a/_example/s3-replication/example.tf b/_example/s3-replication/example.tf index 2542fb7..be4e5df 100644 --- a/_example/s3-replication/example.tf +++ b/_example/s3-replication/example.tf @@ -36,7 +36,7 @@ module "replica_bucket" { aws = aws.replica } name = "clouddrov-s3-replica" - s3_name = "" + s3_name = "antil" environment = local.environment label_order = local.label_order acl = "private" @@ -49,7 +49,7 @@ module "s3_bucket" { source = "../../" name = "clouddrov-s3" - s3_name = "" + s3_name = "poxord" environment = local.environment label_order = local.label_order diff --git a/_example/website-s3/example.tf b/_example/website-s3/example.tf index 31b0b76..1585b69 100644 --- a/_example/website-s3/example.tf +++ b/_example/website-s3/example.tf @@ -17,7 +17,7 @@ module "s3_bucket" { source = "./../../" name = "clouddrove-website-bucket" - s3_name = "" + s3_name = "doxrd" environment = local.environment label_order = local.label_order diff --git a/main.tf b/main.tf index f88d78a..f0e8541 100644 --- a/main.tf +++ b/main.tf @@ -14,6 +14,10 @@ module "labels" { ##---------------------------------------------------------------------------------- ## Terraform resource to create S3 bucket with different combination type specific features. ##---------------------------------------------------------------------------------- +#tfsec:ignore:aws-s3-enable-bucket-encryption +#tfsec:ignore:aws-s3-encryption-customer-key +#tfsec:ignore:aws-s3-enable-bucket-logging +#tfsec:ignore:aws-s3-enable-versioning resource "aws_s3_bucket" "s3_default" { count = var.enabled == true ? 1 : 0 @@ -22,7 +26,6 @@ resource "aws_s3_bucket" "s3_default" { force_destroy = var.force_destroy object_lock_enabled = var.object_lock_enabled tags = module.labels.tags - } ##---------------------------------------------------------------------------------- @@ -38,6 +41,32 @@ resource "aws_s3_bucket_policy" "s3_default" { ] } +resource "aws_s3_bucket_policy" "block-http" { + count = var.enabled && var.only_https_traffic ? 1 : 0 + bucket = aws_s3_bucket.s3_default[0].id + + policy = jsonencode({ + Version = "2012-10-17" + Id = "Blockhttp" + Statement = [ + { + "Sid" : "AllowSSLRequestsOnly", + "Effect" : "Deny", + "Principal" : "*", + "Action" : "s3:*", + "Resource" : [ + aws_s3_bucket.s3_default[0].arn, + "${aws_s3_bucket.s3_default[0].arn}/*", + ], + "Condition" : { + "Bool" : { + "aws:SecureTransport" : "false" + } + } + }, + ] + }) +} ##---------------------------------------------------------------------------------- ## Provides an S3 bucket accelerate configuration resource. ##---------------------------------------------------------------------------------- @@ -45,8 +74,7 @@ resource "aws_s3_bucket_accelerate_configuration" "example" { count = var.enabled && var.acceleration_status == true ? 1 : 0 bucket = join("", aws_s3_bucket.s3_default[*].id) expected_bucket_owner = var.expected_bucket_owner - - status = var.configuration_status + status = var.configuration_status } ##---------------------------------------------------------------------------------- @@ -69,9 +97,10 @@ resource "aws_s3_bucket_versioning" "example" { bucket = join("", aws_s3_bucket.s3_default[*].id) expected_bucket_owner = var.expected_bucket_owner + mfa = var.mfa versioning_configuration { - status = var.versioning_status - + status = var.versioning_status + mfa_delete = var.mfa_delete } } @@ -134,6 +163,7 @@ resource "aws_s3_bucket_cors_configuration" "example" { for_each = var.cors_rule == null ? [] : var.cors_rule content { + id = try(cors_rule.value.id, null) allowed_headers = cors_rule.value.allowed_headers allowed_methods = cors_rule.value.allowed_methods allowed_origins = cors_rule.value.allowed_origins @@ -347,7 +377,9 @@ resource "aws_s3_bucket_lifecycle_configuration" "default" { for_each = rule.value.enable_current_object_expiration ? [1] : [] content { - days = rule.value.expiration_days + days = rule.value.expiration_days + date = try(expiration.value.date, null) + expired_object_delete_marker = try(expiration.value.expired_object_delete_marker, null) } } } @@ -526,19 +558,12 @@ resource "aws_s3_bucket_replication_configuration" "this" { depends_on = [aws_s3_bucket_versioning.example] } -locals { - attach_policy = var.attach_require_latest_tls_policy || var.attach_elb_log_delivery_policy || var.attach_lb_log_delivery_policy || var.attach_deny_insecure_transport_policy || var.attach_policy - -} - ##---------------------------------------------------------------------------------- ## Manages S3 bucket-level Public Access Block configuration. ##---------------------------------------------------------------------------------- resource "aws_s3_bucket_public_access_block" "this" { - count = var.enabled && var.attach_public_policy ? 1 : 0 - - bucket = local.attach_policy ? aws_s3_bucket_policy.s3_default[0].id : aws_s3_bucket.s3_default[0].id - + count = var.enabled && var.attach_public_policy ? 1 : 0 + bucket = aws_s3_bucket.s3_default[0].id block_public_acls = var.block_public_acls block_public_policy = var.block_public_policy ignore_public_acls = var.ignore_public_acls @@ -551,7 +576,7 @@ resource "aws_s3_bucket_public_access_block" "this" { resource "aws_s3_bucket_ownership_controls" "this" { count = var.enabled && var.control_object_ownership ? 1 : 0 - bucket = local.attach_policy ? aws_s3_bucket_policy.s3_default[0].id : aws_s3_bucket.s3_default[0].id + bucket = aws_s3_bucket.s3_default[0].id rule { object_ownership = var.object_ownership @@ -564,6 +589,104 @@ resource "aws_s3_bucket_ownership_controls" "this" { ] } +##---------------------------------------------------------------------------------- +## Tiering automatically stores objects in three access tiers: one tier optimized for frequent access, a lower-cost tier optimized for infrequent access, and a very-low-cost tier optimized for rarely accessed data. +##---------------------------------------------------------------------------------- +resource "aws_s3_bucket_intelligent_tiering_configuration" "this" { + for_each = { for k, v in var.intelligent_tiering : k => v if var.enabled } + + name = module.labels.id + bucket = aws_s3_bucket.s3_default[0].id + status = try(tobool(each.value.status) ? "Enabled" : "Disabled", title(lower(each.value.status)), null) + + # Max 1 block - filter + dynamic "filter" { + for_each = length(try(flatten([each.value.filter]), [])) == 0 ? [] : [true] + + content { + prefix = try(each.value.filter.prefix, null) + tags = try(each.value.filter.tags, null) + } + } + + dynamic "tiering" { + for_each = each.value.tiering + + content { + access_tier = tiering.key + days = tiering.value.days + } + } +} + +resource "aws_s3_bucket_metric" "this" { + for_each = { for k, v in var.metric_configuration : k => v if var.enabled } + + name = module.labels.id + bucket = aws_s3_bucket.s3_default[0].id + + dynamic "filter" { + for_each = length(try(flatten([each.value.filter]), [])) == 0 ? [] : [true] + content { + prefix = try(each.value.filter.prefix, null) + tags = try(each.value.filter.tags, null) + } + } +} + +resource "aws_s3_bucket_inventory" "this" { + for_each = { for k, v in var.inventory_configuration : k => v if var.enabled } + + name = module.labels.id + bucket = aws_s3_bucket.s3_default[0].id + included_object_versions = each.value.included_object_versions + enabled = try(each.value.enabled, true) + optional_fields = try(each.value.optional_fields, null) + + destination { + bucket { + bucket_arn = try(each.value.destination.bucket_arn, aws_s3_bucket.s3_default[0].arn) + format = try(each.value.destination.format, null) + account_id = try(each.value.destination.account_id, null) + prefix = try(each.value.destination.prefix, null) + + dynamic "encryption" { + for_each = length(try(flatten([each.value.destination.encryption]), [])) == 0 ? [] : [true] + + content { + + dynamic "sse_kms" { + for_each = each.value.destination.encryption.encryption_type == "sse_kms" ? [true] : [] + + content { + key_id = try(each.value.destination.encryption.kms_key_id, null) + } + } + + dynamic "sse_s3" { + for_each = each.value.destination.encryption.encryption_type == "sse_s3" ? [true] : [] + + content { + } + } + } + } + } + } + + schedule { + frequency = each.value.frequency + } + + dynamic "filter" { + for_each = length(try(flatten([each.value.filter]), [])) == 0 ? [] : [true] + + content { + prefix = try(each.value.filter.prefix, null) + } + } +} + resource "aws_s3_bucket_analytics_configuration" "default" { for_each = { for k, v in var.analytics_configuration : k => v if var.enabled } diff --git a/variables.tf b/variables.tf index 8fca2d4..3be0a4a 100644 --- a/variables.tf +++ b/variables.tf @@ -246,53 +246,28 @@ variable "attach_public_policy" { description = "Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket)" } -variable "attach_elb_log_delivery_policy" { - type = bool - default = false - description = "Controls if S3 bucket should have ELB log delivery policy attached" -} - -variable "attach_lb_log_delivery_policy" { - description = "Controls if S3 bucket should have ALB/NLB log delivery policy attached" - type = bool - default = false -} - -variable "attach_deny_insecure_transport_policy" { - description = "Controls if S3 bucket should have deny non-SSL transport policy attached" - type = bool - default = false -} - -variable "attach_require_latest_tls_policy" { - description = "Controls if S3 bucket should require the latest version of TLS" - type = bool - default = false -} - variable "block_public_acls" { - description = "Whether Amazon S3 should block public ACLs for this bucket." type = bool - default = false + default = true + description = "Whether Amazon S3 should block public ACLs for this bucket." } variable "block_public_policy" { type = bool - default = false + default = true description = "Whether Amazon S3 should block public bucket policies for this bucket." } variable "ignore_public_acls" { description = "Whether Amazon S3 should ignore public ACLs for this bucket." type = bool - default = false + default = true } variable "restrict_public_buckets" { description = "Whether Amazon S3 should restrict public bucket policies for this bucket." type = bool - default = false - + default = true } variable "control_object_ownership" { @@ -306,11 +281,6 @@ variable "object_ownership" { type = string default = "ObjectWriter" } -variable "attach_policy" { - description = "Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy)" - type = bool - default = false -} variable "configuration_status" { type = string @@ -351,4 +321,40 @@ variable "s3_name" { type = string default = null description = "name of s3 bucket" +} + +variable "only_https_traffic" { + type = bool + default = true + description = "This veriables use for only https traffic." +} + +variable "mfa_delete" { + type = string + default = "Disabled" + description = "Specifies whether MFA delete is enabled in the bucket versioning configuration. Valid values: Enabled or Disabled." +} + +variable "intelligent_tiering" { + type = any + default = {} + description = "Map containing intelligent tiering configuration." +} + +variable "metric_configuration" { + type = any + default = [] + description = "Map containing bucket metric configuration." +} + +variable "inventory_configuration" { + type = any + default = {} + description = "Map containing S3 inventory configuration." +} + +variable "mfa" { + type = string + default = null + description = "Optional, Required if versioning_configuration mfa_delete is enabled) Concatenation of the authentication device's serial number, a space, and the value that is displayed on your authentication device." } \ No newline at end of file