Creates a s3 bucket with policies to allow using it, for attaching to other roles/users
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"
}
}
}
}
}
}
GuardDuty Malware Protection
When malware_protection = true
is set for a bucket, this module will:
Create a dedicated IAM role with the appropriate permissions for GuardDuty to scan objects
Configure an AWS GuardDuty Malware Protection Plan to monitor the bucket
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.
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
Name
Description
role
The role which has access to the bucket
s3_buckets
The names of the bucket.
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
}
}
]
}
}
}
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
Name
Description
role
The role which has access to the bucket
s3_buckets
The names of the bucket.