diff --git a/README.md b/README.md
index ef4b644..a7f1dbe 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ These features of S3 bucket configurations are supported:
- Account-level Public Access Block
- S3 Directory Bucket
- S3 Table Bucket
+- S3 Bucket ABAC (Attribute Based Access Control)
## Usage
@@ -97,6 +98,20 @@ module "s3_bucket_for_waf_logs" {
}
```
+### Bucket with ABAC enabled
+
+```hcl
+module "s3_bucket" {
+ source = "terraform-aws-modules/s3-bucket/aws"
+
+ bucket = "my-s3-bucket"
+
+ abac_status = {
+ status = "Enabled"
+ }
+}
+```
+
### Bucket with a custom policy attached
When you need to attach a custom policy to the bucket, you can use the `policy` argument. To keep bucket policy with correct S3 bucket and AWS account properties, you can use the placeholders `_S3_BUCKET_ID_`, `_S3_BUCKET_ARN_`, and `_AWS_ACCOUNT_ID_` in the policy document. Those values will be replaced with the actual values during the policy attachment. This is especially useful when using bucket prefixes.
@@ -173,6 +188,7 @@ No modules.
| Name | Type |
|------|------|
| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
+| [aws_s3_bucket_abac.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_abac) | resource |
| [aws_s3_bucket_accelerate_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_accelerate_configuration) | resource |
| [aws_s3_bucket_acl.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource |
| [aws_s3_bucket_analytics_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_analytics_configuration) | resource |
@@ -215,6 +231,7 @@ No modules.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
+| [abac\_status](#input\_abac\_status) | Map containing ABAC (Attribute Based Access Control) configuration | `any` | `{}` | no |
| [acceleration\_status](#input\_acceleration\_status) | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | `string` | `null` | no |
| [access\_log\_delivery\_policy\_source\_accounts](#input\_access\_log\_delivery\_policy\_source\_accounts) | (Optional) List of AWS Account IDs should be allowed to deliver access logs to this bucket. | `list(string)` | `[]` | no |
| [access\_log\_delivery\_policy\_source\_buckets](#input\_access\_log\_delivery\_policy\_source\_buckets) | (Optional) List of S3 bucket ARNs which should be allowed to deliver access logs to this bucket. | `list(string)` | `[]` | no |
@@ -292,6 +309,7 @@ No modules.
| Name | Description |
|------|-------------|
| [aws\_s3\_bucket\_versioning\_status](#output\_aws\_s3\_bucket\_versioning\_status) | The versioning status of the bucket. Will be 'Enabled', 'Suspended', or 'Disabled'. |
+| [s3\_bucket\_abac\_status](#output\_s3\_bucket\_abac\_status) | The ABAC status of the bucket. |
| [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | The ARN of the bucket. Will be of format arn:aws:s3:::bucketname. |
| [s3\_bucket\_bucket\_domain\_name](#output\_s3\_bucket\_bucket\_domain\_name) | The bucket domain name. Will be of format bucketname.s3.amazonaws.com. |
| [s3\_bucket\_bucket\_regional\_domain\_name](#output\_s3\_bucket\_bucket\_regional\_domain\_name) | The bucket region-specific domain name. The bucket domain name including the region name, please refer here for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent redirect issues from CloudFront to S3 Origin URL. |
diff --git a/examples/complete/README.md b/examples/complete/README.md
index 895ba1e..1382bb6 100644
--- a/examples/complete/README.md
+++ b/examples/complete/README.md
@@ -70,6 +70,7 @@ No inputs.
| Name | Description |
|------|-------------|
+| [s3\_bucket\_abac\_status](#output\_s3\_bucket\_abac\_status) | The ABAC status of the bucket. |
| [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | The ARN of the bucket. Will be of format arn:aws:s3:::bucketname. |
| [s3\_bucket\_bucket\_domain\_name](#output\_s3\_bucket\_bucket\_domain\_name) | The bucket domain name. Will be of format bucketname.s3.amazonaws.com. |
| [s3\_bucket\_bucket\_regional\_domain\_name](#output\_s3\_bucket\_bucket\_regional\_domain\_name) | The bucket region-specific domain name. The bucket domain name including the region name, please refer here for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent redirect issues from CloudFront to S3 Origin URL. |
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 33eddbf..1a528b8 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -410,6 +410,10 @@ module "s3_bucket" {
# metadata_encryption_configuration = {
# sse_algorithm = "AES256"
# }
+
+ abac_status = {
+ status = "Enabled"
+ }
}
module "disabled" {
diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf
index eddd541..7b5378c 100644
--- a/examples/complete/outputs.tf
+++ b/examples/complete/outputs.tf
@@ -47,3 +47,8 @@ output "s3_bucket_website_domain" {
description = "The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records. "
value = module.s3_bucket.s3_bucket_website_domain
}
+
+output "s3_bucket_abac_status" {
+ description = "The ABAC status of the bucket."
+ value = module.s3_bucket.s3_bucket_abac_status
+}
diff --git a/main.tf b/main.tf
index f824047..ea1d92c 100644
--- a/main.tf
+++ b/main.tf
@@ -1409,3 +1409,16 @@ resource "aws_s3_bucket_metadata_configuration" "this" {
}
}
}
+
+resource "aws_s3_bucket_abac" "this" {
+ count = local.create_bucket && length(keys(var.abac_status)) > 0 && !var.is_directory_bucket ? 1 : 0
+
+ region = var.region
+
+ bucket = aws_s3_bucket.this[0].bucket
+ expected_bucket_owner = var.expected_bucket_owner
+
+ abac_status {
+ status = try(var.abac_status["status"], "Enabled")
+ }
+}
diff --git a/outputs.tf b/outputs.tf
index 3874afd..5823a7c 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -67,3 +67,8 @@ output "s3_bucket_tags" {
description = "Tags of the bucket."
value = try(aws_s3_bucket.this[0].tags, {})
}
+
+output "s3_bucket_abac_status" {
+ description = "The ABAC status of the bucket."
+ value = try(aws_s3_bucket_abac.this[0].abac_status[0].status, null)
+}
diff --git a/variables.tf b/variables.tf
index 63f45be..e4a9bb2 100644
--- a/variables.tf
+++ b/variables.tf
@@ -419,6 +419,12 @@ variable "metadata_journal_table_record_expiration" {
default = null
}
+variable "abac_status" {
+ description = "Map containing ABAC (Attribute Based Access Control) configuration"
+ type = any
+ default = {}
+}
+
variable "putin_khuylo" {
description = "Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!"
type = bool
diff --git a/wrappers/main.tf b/wrappers/main.tf
index 6e388ac..c04c291 100644
--- a/wrappers/main.tf
+++ b/wrappers/main.tf
@@ -3,6 +3,7 @@ module "wrapper" {
for_each = var.items
+ abac_status = try(each.value.abac_status, var.defaults.abac_status, {})
acceleration_status = try(each.value.acceleration_status, var.defaults.acceleration_status, null)
access_log_delivery_policy_source_accounts = try(each.value.access_log_delivery_policy_source_accounts, var.defaults.access_log_delivery_policy_source_accounts, [])
access_log_delivery_policy_source_buckets = try(each.value.access_log_delivery_policy_source_buckets, var.defaults.access_log_delivery_policy_source_buckets, [])