Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ module "s3_bucket_for_waf_logs" {
}
```

### 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.

## Conditional creation

Sometimes you need to have a way to create S3 resources conditionally but Terraform does not allow to use `count` inside `module` block, so the solution is to specify argument `create_bucket`.
Expand Down
21 changes: 21 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,27 @@ data "aws_iam_policy_document" "bucket_policy" {
"arn:aws:s3:::${local.bucket_name}",
]
}

statement {
principals {
type = "AWS"
identifiers = [aws_iam_role.this.arn]
}

actions = [
"s3:ListBucket",
]

resources = [
"_S3_BUCKET_ARN_",
]

condition {
test = "StringNotEquals"
variable = "aws:PrincipalAccount"
values = ["_AWS_ACCOUNT_ID_"]
}
}
}

module "log_bucket" {
Expand Down
20 changes: 19 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ locals {

attach_policy = var.attach_require_latest_tls_policy || var.attach_access_log_delivery_policy || var.attach_elb_log_delivery_policy || var.attach_lb_log_delivery_policy || var.attach_cloudtrail_log_delivery_policy || var.attach_deny_insecure_transport_policy || var.attach_inventory_destination_policy || var.attach_deny_incorrect_encryption_headers || var.attach_deny_incorrect_kms_key_sse || var.attach_deny_unencrypted_object_uploads || var.attach_deny_ssec_encrypted_object_uploads || var.attach_policy || var.attach_waf_log_delivery_policy

# Placeholders in the policy document to be replaced with the actual values
policy_placeholders = {
"_S3_BUCKET_ID_" = var.is_directory_bucket ? aws_s3_directory_bucket.this[0].id : aws_s3_bucket.this[0].id,
"_S3_BUCKET_ARN_" = var.is_directory_bucket ? aws_s3_directory_bucket.this[0].arn : aws_s3_bucket.this[0].arn,
"_AWS_ACCOUNT_ID_" = data.aws_caller_identity.current.account_id
}

policy = local.create_bucket && local.attach_policy ? replace(
replace(
replace(
data.aws_iam_policy_document.combined[0].json,
"_S3_BUCKET_ID_", local.policy_placeholders["_S3_BUCKET_ID_"]
),
"_S3_BUCKET_ARN_", local.policy_placeholders["_S3_BUCKET_ARN_"]
),
"_AWS_ACCOUNT_ID_", local.policy_placeholders["_AWS_ACCOUNT_ID_"]
) : ""

# Variables with type `any` should be jsonencode()'d when value is coming from Terragrunt
grants = try(jsondecode(var.grant), var.grant)
cors_rules = try(jsondecode(var.cors_rule), var.cors_rule)
Expand Down Expand Up @@ -591,7 +609,7 @@ resource "aws_s3_bucket_policy" "this" {
# Ref: https://github.com/hashicorp/terraform-provider-aws/issues/7628

bucket = var.is_directory_bucket ? aws_s3_directory_bucket.this[0].bucket : aws_s3_bucket.this[0].id
policy = data.aws_iam_policy_document.combined[0].json
policy = local.policy

depends_on = [
aws_s3_bucket_public_access_block.this
Expand Down