GuardDuty Bucket
This module creates an S3 bucket for storing GuardDuty findings and optionally a KMS Customer Master Key (CMK) for encrypting that data, including all the appropriate lifecycle, encryption, and permission settings for GuardDuty.
It is particularly useful when configuring cross account access, for example when it is desirable to export findings from multiple accounts and regions to a central location such as the security account.
Sample Usage
- Terraform
- Terragrunt
# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S GUARDDUTY-BUCKET MODULE
# ------------------------------------------------------------------------------------------------------
module "guardduty_bucket" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/guardduty-bucket?ref=v1.1.0"
  # ----------------------------------------------------------------------------------------------------
  # REQUIRED VARIABLES
  # ----------------------------------------------------------------------------------------------------
  # The name of the S3 Bucket where GuardDuty findings will be stored.
  s3_bucket_name = <string>
  # ----------------------------------------------------------------------------------------------------
  # OPTIONAL VARIABLES
  # ----------------------------------------------------------------------------------------------------
  # Additional IAM policies to apply to this S3 bucket. You can use this to
  # grant read/write access. This should be a map, where each key is a unique
  # statement ID (SID), and each value is an object that contains the parameters
  # defined in the comment above.
  additional_bucket_policy_statements = {}
  # If true, an IAM Policy that grants access to the key will be honored. If
  # false, only the ARNs listed in var.kms_key_user_iam_arns will have access to
  # the key and any IAM Policy grants will be ignored. (true or false)
  allow_kms_access_with_iam = true
  # The AWS regions that are allowed to write to the GuardDuty findings S3
  # bucket. This is needed to configure the bucket and CMK policy to allow
  # writes from manually-enabled regions. See
  # https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_exportfindings.html#guardduty_exportfindings-s3-policies
  allowed_regions = []
  # Prefix directory to create in the bucket. Must contain a trailing '/'. If
  # you use a prefix for S3 findings publishing, you must pre-create the prefix
  # in the findings bucket. See
  # https://github.com/hashicorp/terraform-provider-aws/issues/16750.
  bucket_prefix = null
  # Whether or not to enable automatic annual rotation of the KMS key. Defaults
  # to true.
  enable_key_rotation = true
  # A list of external AWS accounts that should be given write access for
  # GuardDuty findings to this S3 bucket. This is useful when aggregating
  # findings for multiple AWS accounts in one common S3 bucket.
  external_aws_account_ids_with_write_access = []
  # If set to true, when you run 'terraform destroy', delete all objects from
  # the bucket so that the bucket can be destroyed without error. Warning: these
  # objects are not recoverable so only use this if you're absolutely sure you
  # want to permanently delete everything!
  force_destroy = false
  # All GuardDuty findings will be encrypted with a KMS Key (a Customer Master
  # Key). The IAM Users specified in this list will have rights to change who
  # can access the data.
  kms_key_administrator_iam_arns = []
  # Override KMS key alias. Defaults to var.s3_bucket_name.
  kms_key_alias = null
  # If set to true, that means the KMS key you're using already exists, and does
  # not need to be created.
  kms_key_already_exists = false
  # All GuardDuty findings will be encrypted with a KMS CMK (Customer Master
  # Key). If that CMK already exists (e.g., if this is the stage or prod account
  # and you want to use a CMK that already exists in the security account), set
  # this to the ARN of that CMK. Otherwise (e.g., if this is the security
  # account), set this to null, and a new CMK will be created.
  kms_key_arn = null
  # The number of days to keep the created KMS Key (a Customer Master Key)
  # around after it has been marked for deletion.
  kms_key_deletion_window_in_days = 15
  # Additional service principals beyond GuardDuty that should have access to
  # the KMS key used to encrypt the logs.
  kms_key_service_principals = []
  # All GuardDuty findings will be encrypted with a KMS Key (a Customer Master
  # Key). The IAM Users specified in this list will have read-only access to the
  # data.
  kms_key_user_iam_arns = []
  # After this number of days, findings should be transitioned from S3 to
  # Glacier. Enter 0 to never archive findings.
  num_days_after_which_archive_findings_data = 30
  # After this number of days, log files should be deleted from S3. Enter 0 to
  # never delete log data.
  num_days_after_which_delete_findings_data = null
  # Enable MFA delete for either 'Change the versioning state of your bucket' or
  # 'Permanently delete an object version'. This setting only applies to the
  # bucket used to storage GuardDuty findings. This cannot be used to toggle
  # this setting but is available to allow managed buckets to reflect the state
  # in AWS. For instructions on how to enable MFA Delete, check out the README
  # from the terraform-aws-security/private-s3-bucket module.
  s3_mfa_delete = false
  # Tags to apply to the GuardDuty findings resources (S3 bucket and CMK).
  tags = {}
}
# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S GUARDDUTY-BUCKET MODULE
# ------------------------------------------------------------------------------------------------------
terraform {
  source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/guardduty-bucket?ref=v1.1.0"
}
inputs = {
  # ----------------------------------------------------------------------------------------------------
  # REQUIRED VARIABLES
  # ----------------------------------------------------------------------------------------------------
  # The name of the S3 Bucket where GuardDuty findings will be stored.
  s3_bucket_name = <string>
  # ----------------------------------------------------------------------------------------------------
  # OPTIONAL VARIABLES
  # ----------------------------------------------------------------------------------------------------
  # Additional IAM policies to apply to this S3 bucket. You can use this to
  # grant read/write access. This should be a map, where each key is a unique
  # statement ID (SID), and each value is an object that contains the parameters
  # defined in the comment above.
  additional_bucket_policy_statements = {}
  # If true, an IAM Policy that grants access to the key will be honored. If
  # false, only the ARNs listed in var.kms_key_user_iam_arns will have access to
  # the key and any IAM Policy grants will be ignored. (true or false)
  allow_kms_access_with_iam = true
  # The AWS regions that are allowed to write to the GuardDuty findings S3
  # bucket. This is needed to configure the bucket and CMK policy to allow
  # writes from manually-enabled regions. See
  # https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_exportfindings.html#guardduty_exportfindings-s3-policies
  allowed_regions = []
  # Prefix directory to create in the bucket. Must contain a trailing '/'. If
  # you use a prefix for S3 findings publishing, you must pre-create the prefix
  # in the findings bucket. See
  # https://github.com/hashicorp/terraform-provider-aws/issues/16750.
  bucket_prefix = null
  # Whether or not to enable automatic annual rotation of the KMS key. Defaults
  # to true.
  enable_key_rotation = true
  # A list of external AWS accounts that should be given write access for
  # GuardDuty findings to this S3 bucket. This is useful when aggregating
  # findings for multiple AWS accounts in one common S3 bucket.
  external_aws_account_ids_with_write_access = []
  # If set to true, when you run 'terraform destroy', delete all objects from
  # the bucket so that the bucket can be destroyed without error. Warning: these
  # objects are not recoverable so only use this if you're absolutely sure you
  # want to permanently delete everything!
  force_destroy = false
  # All GuardDuty findings will be encrypted with a KMS Key (a Customer Master
  # Key). The IAM Users specified in this list will have rights to change who
  # can access the data.
  kms_key_administrator_iam_arns = []
  # Override KMS key alias. Defaults to var.s3_bucket_name.
  kms_key_alias = null
  # If set to true, that means the KMS key you're using already exists, and does
  # not need to be created.
  kms_key_already_exists = false
  # All GuardDuty findings will be encrypted with a KMS CMK (Customer Master
  # Key). If that CMK already exists (e.g., if this is the stage or prod account
  # and you want to use a CMK that already exists in the security account), set
  # this to the ARN of that CMK. Otherwise (e.g., if this is the security
  # account), set this to null, and a new CMK will be created.
  kms_key_arn = null
  # The number of days to keep the created KMS Key (a Customer Master Key)
  # around after it has been marked for deletion.
  kms_key_deletion_window_in_days = 15
  # Additional service principals beyond GuardDuty that should have access to
  # the KMS key used to encrypt the logs.
  kms_key_service_principals = []
  # All GuardDuty findings will be encrypted with a KMS Key (a Customer Master
  # Key). The IAM Users specified in this list will have read-only access to the
  # data.
  kms_key_user_iam_arns = []
  # After this number of days, findings should be transitioned from S3 to
  # Glacier. Enter 0 to never archive findings.
  num_days_after_which_archive_findings_data = 30
  # After this number of days, log files should be deleted from S3. Enter 0 to
  # never delete log data.
  num_days_after_which_delete_findings_data = null
  # Enable MFA delete for either 'Change the versioning state of your bucket' or
  # 'Permanently delete an object version'. This setting only applies to the
  # bucket used to storage GuardDuty findings. This cannot be used to toggle
  # this setting but is available to allow managed buckets to reflect the state
  # in AWS. For instructions on how to enable MFA Delete, check out the README
  # from the terraform-aws-security/private-s3-bucket module.
  s3_mfa_delete = false
  # Tags to apply to the GuardDuty findings resources (S3 bucket and CMK).
  tags = {}
}
Reference
- Inputs
- Outputs
Required
s3_bucket_namestringThe name of the S3 Bucket where GuardDuty findings will be stored.
Optional
Additional IAM policies to apply to this S3 bucket. You can use this to grant read/write access. This should be a map, where each key is a unique statement ID (SID), and each value is an object that contains the parameters defined in the comment above.
Any types represent complex values of variable type. For details, please consult `variables.tf` in the source repo.
{}Example
   {
      AllIamUsersReadAccess = {
        effect     = "Allow"
        actions    = ["s3:GetObject"]
        principals = {
          AWS = ["arn:aws:iam::111111111111:user/ann", "arn:aws:iam::111111111111:user/bob"]
        }
        condition = {
          SourceVPCCheck = {
            test = "StringEquals"
            variable = "aws:SourceVpc"
            values = ["vpc-abcd123"]
          }
        }
      }
   }
Details
   Ideally, this would be a map(object({...})), but the Terraform object type constraint doesn't support optional
   parameters, whereas IAM policy statements have many optional params. And we can't even use map(any), as the
   Terraform map type constraint requires all values to have the same type ("shape"), but as each object in the map
   may specify different optional params, this won't work either. So, sadly, we are forced to fall back to "any."
If true, an IAM Policy that grants access to the key will be honored. If false, only the ARNs listed in kms_key_user_iam_arns will have access to the key and any IAM Policy grants will be ignored. (true or false)
trueallowed_regionslist(string)The AWS regions that are allowed to write to the GuardDuty findings S3 bucket. This is needed to configure the bucket and CMK policy to allow writes from manually-enabled regions. See https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_exportfindings.html#guardduty_exportfindings-s3-policies
[]bucket_prefixstringPrefix directory to create in the bucket. Must contain a trailing '/'. If you use a prefix for S3 findings publishing, you must pre-create the prefix in the findings bucket. See https://github.com/hashicorp/terraform-provider-aws/issues/16750.
nullWhether or not to enable automatic annual rotation of the KMS key. Defaults to true.
trueexternal_aws_account_ids_with_write_accesslist(string)A list of external AWS accounts that should be given write access for GuardDuty findings to this S3 bucket. This is useful when aggregating findings for multiple AWS accounts in one common S3 bucket.
[]force_destroyboolIf set to true, when you run 'terraform destroy', delete all objects from the bucket so that the bucket can be destroyed without error. Warning: these objects are not recoverable so only use this if you're absolutely sure you want to permanently delete everything!
falsekms_key_administrator_iam_arnslist(string)All GuardDuty findings will be encrypted with a KMS Key (a Customer Master Key). The IAM Users specified in this list will have rights to change who can access the data.
[]kms_key_aliasstringOverride KMS key alias. Defaults to s3_bucket_name.
nullIf set to true, that means the KMS key you're using already exists, and does not need to be created.
falsekms_key_arnstringAll GuardDuty findings will be encrypted with a KMS CMK (Customer Master Key). If that CMK already exists (e.g., if this is the stage or prod account and you want to use a CMK that already exists in the security account), set this to the ARN of that CMK. Otherwise (e.g., if this is the security account), set this to null, and a new CMK will be created.
nullThe number of days to keep the created KMS Key (a Customer Master Key) around after it has been marked for deletion.
15kms_key_service_principalslist(object(…))Additional service principals beyond GuardDuty that should have access to the KMS key used to encrypt the logs.
list(object({
    # The name of the service principal (e.g.: s3.amazonaws.com).
    name = string
    # The list of actions that the given service principal is allowed to perform (e.g. ["kms:DescribeKey",
    # "kms:GenerateDataKey"]).
    actions = list(string)
    # List of additional service principals. Useful when, for example, granting
    # access to opt-in region service endpoints (e.g. guardduty.us-east-1.amazonaws.com).
    additional_principals = list(string)
    # List of conditions to apply to the permissions for the service principal. Use this to apply conditions on the
    # permissions for accessing the KMS key (e.g., only allow access for certain encryption contexts).
    conditions = list(object({
      # Name of the IAM condition operator to evaluate.
      test = string
      # Name of a Context Variable to apply the condition to. Context variables may either be standard AWS variables
      # starting with aws: or service-specific variables prefixed with the service name.
      variable = string
      # Values to evaluate the condition against. If multiple values are provided, the condition matches if at least one
      # of them applies. That is, AWS evaluates multiple values as though using an "OR" boolean operation.
      values = list(string)
    }))
  }))
[]Details
     The list of actions that the given service principal is allowed to perform (e.g. ["kms:DescribeKey",
     "kms:GenerateDataKey"]).
Details
     List of additional service principals. Useful when, for example, granting
     access to opt-in region service endpoints (e.g. guardduty.us-east-1.amazonaws.com).
Details
     List of conditions to apply to the permissions for the service principal. Use this to apply conditions on the
     permissions for accessing the KMS key (e.g., only allow access for certain encryption contexts).
Details
       Name of a Context Variable to apply the condition to. Context variables may either be standard AWS variables
       starting with aws: or service-specific variables prefixed with the service name.
Details
       Values to evaluate the condition against. If multiple values are provided, the condition matches if at least one
       of them applies. That is, AWS evaluates multiple values as though using an "OR" boolean operation.
kms_key_user_iam_arnslist(string)All GuardDuty findings will be encrypted with a KMS Key (a Customer Master Key). The IAM Users specified in this list will have read-only access to the data.
[]After this number of days, findings should be transitioned from S3 to Glacier. Enter 0 to never archive findings.
30After this number of days, log files should be deleted from S3. Enter 0 to never delete log data.
nulls3_mfa_deleteboolEnable MFA delete for either 'Change the versioning state of your bucket' or 'Permanently delete an object version'. This setting only applies to the bucket used to storage GuardDuty findings. This cannot be used to toggle this setting but is available to allow managed buckets to reflect the state in AWS. For instructions on how to enable MFA Delete, check out the README from the terraform-aws-security/private-s3-bucket module.
falsetagsmap(string)Tags to apply to the GuardDuty findings resources (S3 bucket and CMK).
{}The alias of the KMS key used by the S3 bucket to encrypt GuardDuty findings.
The ARN of the KMS key used by the S3 bucket to encrypt GuardDuty findings.
The ARN of the S3 bucket where GuardDuty findings are delivered.
The name of the S3 bucket where GuardDuty findings are delivered.