diff --git a/examples/guardduty/complete/main.tf b/examples/guardduty/complete/main.tf index 474d64a..fa5788e 100644 --- a/examples/guardduty/complete/main.tf +++ b/examples/guardduty/complete/main.tf @@ -25,4 +25,4 @@ module "guardduty" { # Slack Alerts slack_enabled = false # Pass true to enable lambda -} \ No newline at end of file +} diff --git a/examples/guardduty/complete/outputs.tf b/examples/guardduty/complete/outputs.tf index 1dc0457..e292d1c 100644 --- a/examples/guardduty/complete/outputs.tf +++ b/examples/guardduty/complete/outputs.tf @@ -14,9 +14,4 @@ output "account_id" { output "s3_bucket_id" { value = module.guardduty.bucket_id description = "The bucket id of S3 for guardduty logs." -} - -output "s3_bucket_arn" { - value = module.guardduty.bucket_arn - description = "The bucket ARN of S3 for guardduty logs." } \ No newline at end of file diff --git a/examples/guardduty/organisation_account/main.tf b/examples/guardduty/organisation_account/main.tf index cc675c7..d05a2df 100644 --- a/examples/guardduty/organisation_account/main.tf +++ b/examples/guardduty/organisation_account/main.tf @@ -32,13 +32,13 @@ module "guardduty" { invite = true, email = "email@example.com" }, - { - account_id = "222222222222" # Member account id of the organization member account - invite = true, - email = "email@example.com" - } + # { + # account_id = "222222222222" # Member account id of the organization member account + # invite = true, + # email = "email@example.com" + # } ] # Slack Alerts slack_enabled = false # Pass true to enable lambda -} \ No newline at end of file +} diff --git a/examples/guardduty/organisation_account/outputs.tf b/examples/guardduty/organisation_account/outputs.tf index 1dc0457..e292d1c 100644 --- a/examples/guardduty/organisation_account/outputs.tf +++ b/examples/guardduty/organisation_account/outputs.tf @@ -14,9 +14,4 @@ output "account_id" { output "s3_bucket_id" { value = module.guardduty.bucket_id description = "The bucket id of S3 for guardduty logs." -} - -output "s3_bucket_arn" { - value = module.guardduty.bucket_arn - description = "The bucket ARN of S3 for guardduty logs." } \ No newline at end of file diff --git a/modules/cloudtrail/data.tf b/modules/cloudtrail/data.tf index 1eabbf7..802f449 100644 --- a/modules/cloudtrail/data.tf +++ b/modules/cloudtrail/data.tf @@ -2,14 +2,6 @@ data "aws_caller_identity" "current" {} data "aws_partition" "current" {} data "aws_region" "current" {} -#Data : S3 bucket -#Description : Terraform Data block to get an AWS S3 bucket information. -data "aws_s3_bucket" "bucket" { - count = var.s3_bucket_name != "" ? 1 : 0 - bucket = var.s3_bucket_name -} - - #Data : KMS #Description : Terraform Data block to read an AWS IAM policy document for kms. data "aws_iam_policy_document" "kms" { @@ -144,7 +136,7 @@ data "aws_iam_policy_document" "default" { identifiers = ["cloudtrail.amazonaws.com"] } actions = ["s3:GetBucketAcl"] - resources = ["arn:aws:s3:::${local.bucket_name}"] + resources = ["arn:aws:s3:::${var.bucket_name}"] } statement { @@ -155,7 +147,7 @@ data "aws_iam_policy_document" "default" { identifiers = ["cloudtrail.amazonaws.com"] } actions = ["s3:PutObject"] - resources = ["arn:aws:s3:::${local.bucket_name}/AWSLogs/*"] + resources = ["arn:aws:s3:::${var.bucket_name}/AWSLogs/*"] condition { test = "StringEquals" variable = "s3:x-amz-acl" diff --git a/modules/cloudtrail/main.tf b/modules/cloudtrail/main.tf index b2f76d4..feafdde 100644 --- a/modules/cloudtrail/main.tf +++ b/modules/cloudtrail/main.tf @@ -3,8 +3,8 @@ # Copyright @ CloudDrove. All Right Reserved. locals { - bucket_name = coalesce(var.s3_bucket_name, module.s3_logs.id) - bucket_id = coalesce(join("", data.aws_s3_bucket.bucket.*.arn), module.s3_logs.arn) + bucket_name = coalesce(var.bucket_name, module.s3_logs.id) + # bucket_id = coalesce(join("", data.aws_s3_bucket.bucket.*.arn), module.s3_logs.arn) } #Module : Labels @@ -34,26 +34,33 @@ locals { module "s3_logs" { source = "clouddrove/s3/aws" - version = "1.3.0" + version = "2.0.0" + + enabled = var.create_bucket + name = var.name + s3_name = var.bucket_name + environment = local.bucket_environment + label_order = var.label_order + logging = var.logging + versioning = var.bucket_versioning + acl = "log-delivery-write" + block_public_acls = var.block_public_acls + block_public_policy = var.block_public_policy + ignore_public_acls = var.ignore_public_acls + restrict_public_buckets = var.restrict_public_buckets + bucket_policy = var.bucket_policy && var.create_bucket + aws_iam_policy_document = data.aws_iam_policy_document.default.json + force_destroy = var.force_destroy + only_https_traffic = var.only_https_traffic +} - name = var.name - create_bucket = local.create_bucket - environment = local.bucket_environment - label_order = var.label_order - logging = var.logging - versioning = var.bucket_versioning - acl = "log-delivery-write" - block_public_acls = var.block_public_acls - block_public_policy = var.block_public_policy - ignore_public_acls = var.ignore_public_acls - restrict_public_buckets = var.restrict_public_buckets - bucket_policy = var.bucket_policy - aws_iam_policy_document = data.aws_iam_policy_document.default.json - lifecycle_expiration_enabled = var.lifecycle_expiration_enabled - lifecycle_days_to_expiration = var.lifecycle_days_to_expiration - force_destroy = var.force_destroy +resource "aws_s3_bucket_policy" "s3_default" { + count = var.bucket_policy && !var.create_bucket ? 1 : 0 + bucket = local.bucket_name + policy = data.aws_iam_policy_document.default.json } + ###--------------------------------------------------------------------------------------- #Resource : CloudWatch #Description : Terraform resource to create cloudwatch log with logging and encryption for cloudtrail. ( This role is used by CloudTrail to send logs to CloudWatch. ) @@ -125,8 +132,9 @@ resource "aws_cloudtrail" "default" { dynamic "event_selector" { for_each = var.event_selector content { - include_management_events = lookup(event_selector.value, "include_management_events", null) - read_write_type = lookup(event_selector.value, "read_write_type", null) + include_management_events = lookup(event_selector.value, "include_management_events", null) + read_write_type = lookup(event_selector.value, "read_write_type", null) + exclude_management_event_sources = event_selector.value.exclude_management_event_sources dynamic "data_resource" { for_each = lookup(event_selector.value, "data_resource", []) content { @@ -168,7 +176,7 @@ module "cloudtrail-slack-notification" { managedby = var.managedby label_order = var.label_order enabled = var.slack_webhook != "" && var.enabled_cloudtrail - bucket_arn = format("arn:aws:s3:::%s", local.bucket_id) + bucket_arn = format("arn:aws:s3:::%s", local.bucket_name) bucket_name = local.bucket_name variables = { slack_webhook = var.slack_webhook diff --git a/modules/cloudtrail/outputs.tf b/modules/cloudtrail/outputs.tf index 3ba2728..dee06b1 100644 --- a/modules/cloudtrail/outputs.tf +++ b/modules/cloudtrail/outputs.tf @@ -19,8 +19,8 @@ output "log_group_name" { description = "The CloudWatch Logs log group which stores CloudTrail events." } -output "s3_id" { - value = coalesce(join("", data.aws_s3_bucket.bucket.*.arn), module.s3_logs.arn) +output "bucket_id" { + value = try(local.bucket_name, "") # coalesce(join("", data.aws_s3_bucket.bucket.*.arn), module.s3_logs.arn) description = "The Name of S3 bucket." } diff --git a/modules/cloudtrail/variables.tf b/modules/cloudtrail/variables.tf index 53a49ce..3e889b4 100644 --- a/modules/cloudtrail/variables.tf +++ b/modules/cloudtrail/variables.tf @@ -128,7 +128,7 @@ variable "bucket_environment" { description = "Environment (e.g. `prod`, `dev`, `staging`, `test`)." } -variable "s3_bucket_name" { +variable "bucket_name" { type = string default = "" description = "The name of the S3 bucket which will store configuration snapshots." @@ -160,8 +160,13 @@ variable "source_list" { variable "event_selector" { type = list(object({ - include_management_events = bool - read_write_type = string + include_management_events = bool + read_write_type = string + exclude_management_event_sources = optional(set(string)) + data_resource = list(object({ + type = string + values = list(string) + })) })) description = "Specifies an event selector for enabling data event logging. See: https://www.terraform.io/docs/providers/aws/r/cloudtrail.html for details on this variable" @@ -203,7 +208,7 @@ variable "bucket_policy" { variable "logging" { type = bool - default = true + default = false description = "Logging Object to enable and disable logging" } @@ -235,6 +240,11 @@ variable "block_public_acls" { EOF } +variable "only_https_traffic" { + default = false + type = bool +} + variable "block_public_policy" { type = bool default = true diff --git a/modules/guardduty/main.tf b/modules/guardduty/main.tf index ddb8e19..47e950d 100644 --- a/modules/guardduty/main.tf +++ b/modules/guardduty/main.tf @@ -1,6 +1,7 @@ locals { ipset_key = "ipset.txt" threatintelset_key = "threatintelset.txt" + bucket_name = coalesce(var.bucket_name, try(aws_s3_bucket.bucket[0].id, "")) } data "aws_caller_identity" "current" {} @@ -20,8 +21,8 @@ module "labels" { #tfsec:ignore:aws-s3-enable-bucket-encryption #tfsec:ignore:aws-s3-encryption-customer-key resource "aws_s3_bucket" "bucket" { - count = var.enabled ? 1 : 0 - bucket = var.bucket_name + count = var.enabled && var.create_bucket ? 1 : 0 + bucket = coalesce(var.bucket_name, "secure-baseline-guardduty") force_destroy = true } @@ -29,6 +30,23 @@ resource "aws_guardduty_detector" "detector" { count = var.enabled ? 1 : 0 enable = var.guardduty_enable finding_publishing_frequency = var.finding_publishing_frequency + datasources { + s3_logs { + enable = var.enable_s3_protection + } + kubernetes { + audit_logs { + enable = var.enable_kubernetes_protection + } + } + malware_protection { + scan_ec2_instance_with_findings { + ebs_volumes { + enable = var.enable_malware_protection + } + } + } + } } resource "aws_guardduty_invite_accepter" "member_accepter" { @@ -42,14 +60,14 @@ resource "aws_s3_bucket_object" "ipset" { acl = "private" content = templatefile("${path.module}/templates/ipset.txt.tpl", { ipset_iplist = var.ipset_iplist }) - bucket = join("", aws_s3_bucket.bucket.*.id) + bucket = local.bucket_name key = local.ipset_key force_destroy = true tags = module.labels.tags } resource "aws_s3_bucket_public_access_block" "this" { - count = var.enabled ? 1 : 0 + count = var.enabled && var.create_bucket ? 1 : 0 bucket = aws_s3_bucket.bucket[0].id @@ -74,7 +92,7 @@ resource "aws_s3_bucket_object" "threatintelset" { acl = "private" content = templatefile("${path.module}/templates/threatintelset.txt.tpl", { threatintelset_iplist = var.threatintelset_iplist }) - bucket = join("", aws_s3_bucket.bucket.*.id) + bucket = local.bucket_name key = local.threatintelset_key force_destroy = true tags = module.labels.tags diff --git a/modules/guardduty/outputs.tf b/modules/guardduty/outputs.tf index a6fba95..16dadbb 100644 --- a/modules/guardduty/outputs.tf +++ b/modules/guardduty/outputs.tf @@ -17,11 +17,6 @@ output "tags" { # S3 Bucket output "bucket_id" { - value = aws_s3_bucket.bucket[0].id + value = local.bucket_name description = "The bucket id of S3 for guardduty logs." -} - -output "bucket_arn" { - value = aws_s3_bucket.bucket[0].arn - description = "The bucket ARN of S3 for guardduty logs." } \ No newline at end of file diff --git a/modules/guardduty/variables.tf b/modules/guardduty/variables.tf index b3d4b5d..1fe0757 100644 --- a/modules/guardduty/variables.tf +++ b/modules/guardduty/variables.tf @@ -85,9 +85,15 @@ variable "finding_publishing_frequency" { description = "Valid values for standalone and master accounts: `FIFTEEN_MINUTES`, `ONE_HOUR`, `SIX_HOURS`" } +variable "create_bucket" { + type = bool + default = true + description = "Conditionally create S3 bucket." +} + variable "bucket_name" { type = string - default = "secure-baseline-guardduty" + default = "" description = "Name of the S3 bucket to use" } @@ -150,6 +156,24 @@ variable "datasources" { } } +variable "enable_s3_protection" { + description = "Configure and enable S3 protection. Defaults to `true`." + type = bool + default = true +} + +variable "enable_kubernetes_protection" { + description = "Configure and enable Kubernetes audit logs as a data source for Kubernetes protection. Defaults to `true`." + type = bool + default = true +} + +variable "enable_malware_protection" { + description = "Configure and enable Malware Protection as data source for EC2 instances with findings for the detector. Defaults to `true`." + type = bool + default = true +} + ## S3 diff --git a/modules/guardduty/versions.tf b/modules/guardduty/versions.tf index f5b5724..3a1e8a9 100644 --- a/modules/guardduty/versions.tf +++ b/modules/guardduty/versions.tf @@ -6,6 +6,7 @@ terraform { aws = { source = "hashicorp/aws" version = ">= 5.10.0" + # configuration_aliases = [ aws.test ] } } } \ No newline at end of file