Skip to content

Files

189 lines (170 loc) · 11.8 KB

README.md

File metadata and controls

189 lines (170 loc) · 11.8 KB

s3-generic

Creates a s3 bucket with policies to allow using it, for attaching to other roles/users

Example

module "s3-generic" {
  source = "../..//"
  object_ownership = "BucketOwnerEnforced" # Optional, defaults to BucketOwnerEnforced
  s3_buckets = {
    backups = {
      bucket               = "my-backups"
      permissions_boundary = "arn:aws:iam::${get_aws_account_id()}:policy/MyBoundary"
      region               = "ap-southeast-1"
      acl                  = "private"
      object_ownership     = "BucketOwnerPreferred" # Optional, overrides the module-level setting
      log_bucket_for_s3    = "my-access-logs"
      malware_protection   = true                   # Optional, enables GuardDuty Malware Protection for this bucket
      policies = [jsonencode(
        {
          "Version" : "2012-10-17",
          "Statement" : [
            {
              Action : "s3:GetBucketAcl",
              Effect : "Allow",
              Resource : "arn:aws:s3:::my-backups",
              Principal : { "Service" : "logs.ap-southeast-1.amazonaws.com" }
            },
            {
              Action : "s3:PutObject",
              Effect : "Allow",
              Resource : "arn:aws:s3:::my-backups/**",
              Condition : { "StringEquals" : { "s3:x-amz-acl" : "bucket-owner-full-control" } },
              Principal : { "Service" : "logs.ap-southeast-1.amazonaws.com" }
            }
          ]
        }
      )]
      server_side_encryption_configuration = {
        rule = {
          bucket_key_enabled = true
          apply_server_side_encryption_by_default = {
            sse_algorithm = "aws:kms"
          }
        }
      }
    }
  }
}

Features

GuardDuty Malware Protection

When malware_protection = true is set for a bucket, this module will:

  1. Create a dedicated IAM role with the appropriate permissions for GuardDuty to scan objects
  2. Configure an AWS GuardDuty Malware Protection Plan to monitor the bucket
  3. Enable object tagging to mark scanned objects

The IAM role follows the principle of least privilege with permissions based on AWS recommended policies for GuardDuty Malware Protection.

Inputs

Name Description Type Default Required
force_destroy When destroying this user, destroy even if it has non-Terraform-managed IAM access keys, login profile or MFA devices. Without force_destroy a user with non-Terraform-managed access keys and login profile will fail to be destroyed. bool false no
path Desired path for the IAM user string "/" no
s3_buckets A map of bucket names to an object describing the S3 bucket settings for the bucket.
map(object({ 
bucket = string
permissions_boundary = string
region = string
acl = optional(string)
log_bucket_for_s3 = optional(string)
object_ownership = optional(string)
malware_protection = optional(bool, false)
policies = list(string)
server_side_encryption_configuration = any
cors_configuration = optional(
list(
object({
allowed_methods = list(string)
allowed_origins = list(string)
allowed_headers = optional(list(string))
expose_headers = optional(list(string))
max_age_seconds = optional(number)
id = optional(string)
})
)
)
lifecycle_rules = optional(list(object({
id = optional(string)
enabled = optional(bool, true)
filter = optional(object({
prefix = optional(string)
object_size_greater_than = optional(number)
object_size_less_than = optional(number)
tags = optional(map(string))
}))
transition = optional(list(object({
days = optional(number)
date = optional(string)
storage_class = string
})))
})))
}))
no
tags (Optional) A mapping of tags to assign to the bucket. map(string) {} no
object_ownership (Optional) Default object ownership setting for all buckets. Can be overridden at the bucket level using the object_ownership property in the bucket configuration. Valid values: BucketOwnerEnforced, BucketOwnerPreferred or ObjectWriter string "BucketOwnerEnforced" no

Outputs

Name Description
role The role which has access to the bucket
s3_buckets The names of the bucket.

Example

module "s3-generic" {
  source = "../..//"
  s3_buckets = {
    backups = {
      bucket               = "my-backups"
      permissions_boundary = "arn:aws:iam::${get_aws_account_id()}:policy/MyBoundary"
      region               = "ap-southeast-1"
      acl                  = "private"
      log_bucket_for_s3    = "my-access-logs"
      policies = [jsonencode(
        {
          "Version" : "2012-10-17",
          "Statement" : [
            {
              Action : "s3:GetBucketAcl",
              Effect : "Allow",
              Resource : "arn:aws:s3:::my-backups",
              Principal : { "Service" : "logs.ap-southeast-1.amazonaws.com" }
            },
            {
              Action : "s3:PutObject",
              Effect : "Allow",
              Resource : "arn:aws:s3:::my-backups/**",
              Condition : { "StringEquals" : { "s3:x-amz-acl" : "bucket-owner-full-control" } },
              Principal : { "Service" : "logs.ap-southeast-1.amazonaws.com" }
            }
          ]
        }
      )]
      server_side_encryption_configuration = {
        rule = {
          bucket_key_enabled = true
          apply_server_side_encryption_by_default = {
            sse_algorithm = "aws:kms"
          }
        }
      }
      lifecycle_rules = [
        {
          id      = "backup-lifecycle-rule"
          enabled = true
          filter = {
            object_size_greater_than = 0
          }
          transition = [
            {
              days          = 30
              storage_class = "STANDARD_IA"
            },
            {
              days          = 60
              storage_class = "GLACIER"
            },
            {
              days          = 150
              storage_class = "DEEP_ARCHIVE"
            }
          ]
          noncurrent_version_transition = [
            {
              noncurrent_days = 30
              storage_class   = "STANDARD_IA"
            },
            {
              noncurrent_days = 60
              storage_class   = "GLACIER"
            },
            {
              noncurrent_days = 150
              storage_class   = "DEEP_ARCHIVE"
            }
          ]
          expiration = {
            days = 183
          }
          noncurrent_version_expiration = {
            noncurrent_days = 151
          }
        }
      ]
    }
  }
}

Inputs

Name Description Type Default Required
force_destroy When destroying this user, destroy even if it has non-Terraform-managed IAM access keys, login profile or MFA devices. Without force_destroy a user with non-Terraform-managed access keys and login profile will fail to be destroyed. bool false no
object_lock_enabled (Optional) Enable object lock for the S3 bucket bool false no
object_ownership (Optional) Object ownership. Valid values: BucketOwnerEnforced, BucketOwnerPreferred or ObjectWriter string "BucketOwnerEnforced" no
path Desired path for the IAM user string "/" no
s3_buckets A map of bucket names to an object describing the S3 bucket settings for the bucket.
map(object({
bucket = string
permissions_boundary = string
region = string
acl = optional(string)
log_bucket_for_s3 = optional(string)
object_ownership = optional(string)
policies = list(string)
server_side_encryption_configuration = any
malware_protection = optional(bool, false)
malware_protection_prefix = optional(list(string))
cors_configuration = optional(
list(
object({
allowed_methods = list(string)
allowed_origins = list(string)
allowed_headers = optional(list(string))
expose_headers = optional(list(string))
max_age_seconds = optional(number)
id = optional(string)
})
)
)
lifecycle_rules = optional(list(object({
id = optional(string)
enabled = optional(bool, true)
filter = optional(object({
prefix = optional(string)
object_size_greater_than = optional(number)
object_size_less_than = optional(number)
tags = optional(map(string))
}))
transition = optional(list(object({
days = optional(number)
date = optional(string)
storage_class = string
})))
expiration = optional(object({
date = optional(string)
days = optional(number)
expired_object_delete_marker = optional(bool)
}))
noncurrent_version_expiration = optional(object({
noncurrent_days = optional(number)
newer_noncurrent_versions = optional(number)
}))
noncurrent_version_transition = optional(list(object({
noncurrent_days = optional(number)
newer_noncurrent_versions = optional(number)
storage_class = string
})))
abort_incomplete_multipart_upload_days = optional(number)
})))
}))
{
"main": {
"bucket": "",
"log_bucket_for_s3": "",
"malware_protection": false,
"malware_protection_prefix": [],
"permissions_boundary": "",
"policies": [],
"region": "ap-southeast-1",
"server_side_encryption_configuration": {
"rule": {
"apply_server_side_encryption_by_default": {
"sse_algorithm": "AES256"
}
}
}
}
}
no
tags (Optional) A mapping of tags to assign to the bucket. map(string) {} no

Outputs

Name Description
role The role which has access to the bucket
s3_buckets The names of the bucket.