From 3812cb5f1385e86b1a40b91537760d24560773fc Mon Sep 17 00:00:00 2001 From: szubersk Date: Fri, 13 Dec 2024 16:23:25 +1000 Subject: [PATCH] feat: Add log delivery source organization variables Allow S3 bucket access scoping to AWS Organizations in ALB/NLB/S3 access log bucket policies. Signed-off-by: szubersk --- README.md | 2 + examples/complete/main.tf | 6 ++- main.tf | 39 ++++++++++++++ variables.tf | 12 +++++ wrappers/main.tf | 110 +++++++++++++++++++------------------- 5 files changed, 113 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 179ed85..1e3e3bb 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ No modules. | [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 | +| [access\_log\_delivery\_policy\_source\_organizations](#input\_access\_log\_delivery\_policy\_source\_organizations) | (Optional) List of AWS Organization IDs should be allowed to deliver access logs to this bucket. | `list(string)` | `[]` | no | | [acl](#input\_acl) | (Optional) The canned ACL to apply. Conflicts with `grant` | `string` | `null` | no | | [allowed\_kms\_key\_arn](#input\_allowed\_kms\_key\_arn) | The ARN of KMS key which should be allowed in PutObject | `string` | `null` | no | | [analytics\_configuration](#input\_analytics\_configuration) | Map containing bucket analytics configuration. | `any` | `{}` | no | @@ -217,6 +218,7 @@ No modules. | [inventory\_self\_source\_destination](#input\_inventory\_self\_source\_destination) | Whether or not the inventory source bucket is also the destination bucket. | `bool` | `false` | no | | [inventory\_source\_account\_id](#input\_inventory\_source\_account\_id) | The inventory source account id. | `string` | `null` | no | | [inventory\_source\_bucket\_arn](#input\_inventory\_source\_bucket\_arn) | The inventory source bucket ARN. | `string` | `null` | no | +| [lb\_log\_delivery\_policy\_source\_organizations](#input\_lb\_log\_delivery\_policy\_source\_organizations) | (Optional) List of AWS Organization IDs should be allowed to deliver ALB/NLB logs to this bucket. | `list(string)` | `[]` | no | | [lifecycle\_rule](#input\_lifecycle\_rule) | List of maps containing configuration of object lifecycle management. | `any` | `[]` | no | | [logging](#input\_logging) | Map containing access bucket logging configuration. | `any` | `{}` | no | | [metric\_configuration](#input\_metric\_configuration) | Map containing bucket metric configuration. | `any` | `[]` | no | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 1f2538b..a831235 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -76,8 +76,10 @@ module "log_bucket" { attach_deny_insecure_transport_policy = true attach_require_latest_tls_policy = true - access_log_delivery_policy_source_accounts = [data.aws_caller_identity.current.account_id] - access_log_delivery_policy_source_buckets = ["arn:aws:s3:::${local.bucket_name}"] + access_log_delivery_policy_source_accounts = [data.aws_caller_identity.current.account_id] + access_log_delivery_policy_source_buckets = ["arn:aws:s3:::${local.bucket_name}"] + access_log_delivery_policy_source_organizations = ["o-123456"] + lb_log_delivery_policy_source_organizations = ["o-123456"] } module "cloudfront_log_bucket" { diff --git a/main.tf b/main.tf index 4bffeb0..c7a9abf 100644 --- a/main.tf +++ b/main.tf @@ -675,6 +675,16 @@ data "aws_iam_policy_document" "lb_log_delivery" { variable = "s3:x-amz-acl" values = ["bucket-owner-full-control"] } + + dynamic "condition" { + for_each = length(var.lb_log_delivery_policy_source_organizations) > 0 ? [true] : [] + + content { + test = "StringEquals" + variable = "aws:ResourceOrgID" + values = var.lb_log_delivery_policy_source_organizations + } + } } statement { @@ -696,6 +706,15 @@ data "aws_iam_policy_document" "lb_log_delivery" { aws_s3_bucket.this[0].arn, ] + dynamic "condition" { + for_each = length(var.lb_log_delivery_policy_source_organizations) > 0 ? [true] : [] + + content { + test = "StringEquals" + variable = "aws:ResourceOrgID" + values = var.lb_log_delivery_policy_source_organizations + } + } } } @@ -741,6 +760,16 @@ data "aws_iam_policy_document" "access_log_delivery" { } } + dynamic "condition" { + for_each = length(var.access_log_delivery_policy_source_organizations) > 0 ? [true] : [] + + content { + test = "StringEquals" + variable = "aws:ResourceOrgID" + values = var.access_log_delivery_policy_source_organizations + } + } + } statement { @@ -761,6 +790,16 @@ data "aws_iam_policy_document" "access_log_delivery" { aws_s3_bucket.this[0].arn, ] + dynamic "condition" { + for_each = length(var.access_log_delivery_policy_source_organizations) > 0 ? [true] : [] + + content { + test = "StringEquals" + variable = "aws:ResourceOrgID" + values = var.access_log_delivery_policy_source_organizations + } + } + } } diff --git a/variables.tf b/variables.tf index 92feec9..349622f 100644 --- a/variables.tf +++ b/variables.tf @@ -166,6 +166,18 @@ variable "access_log_delivery_policy_source_accounts" { default = [] } +variable "access_log_delivery_policy_source_organizations" { + description = "(Optional) List of AWS Organization IDs should be allowed to deliver access logs to this bucket." + type = list(string) + default = [] +} + +variable "lb_log_delivery_policy_source_organizations" { + description = "(Optional) List of AWS Organization IDs should be allowed to deliver ALB/NLB logs to this bucket." + type = list(string) + default = [] +} + variable "grant" { description = "An ACL policy grant. Conflicts with `acl`" type = any diff --git a/wrappers/main.tf b/wrappers/main.tf index 5b3d0c7..0971be8 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -3,58 +3,60 @@ module "wrapper" { for_each = var.items - 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, []) - acl = try(each.value.acl, var.defaults.acl, null) - allowed_kms_key_arn = try(each.value.allowed_kms_key_arn, var.defaults.allowed_kms_key_arn, null) - analytics_configuration = try(each.value.analytics_configuration, var.defaults.analytics_configuration, {}) - analytics_self_source_destination = try(each.value.analytics_self_source_destination, var.defaults.analytics_self_source_destination, false) - analytics_source_account_id = try(each.value.analytics_source_account_id, var.defaults.analytics_source_account_id, null) - analytics_source_bucket_arn = try(each.value.analytics_source_bucket_arn, var.defaults.analytics_source_bucket_arn, null) - attach_access_log_delivery_policy = try(each.value.attach_access_log_delivery_policy, var.defaults.attach_access_log_delivery_policy, false) - attach_analytics_destination_policy = try(each.value.attach_analytics_destination_policy, var.defaults.attach_analytics_destination_policy, false) - attach_deny_incorrect_encryption_headers = try(each.value.attach_deny_incorrect_encryption_headers, var.defaults.attach_deny_incorrect_encryption_headers, false) - attach_deny_incorrect_kms_key_sse = try(each.value.attach_deny_incorrect_kms_key_sse, var.defaults.attach_deny_incorrect_kms_key_sse, false) - attach_deny_insecure_transport_policy = try(each.value.attach_deny_insecure_transport_policy, var.defaults.attach_deny_insecure_transport_policy, false) - attach_deny_unencrypted_object_uploads = try(each.value.attach_deny_unencrypted_object_uploads, var.defaults.attach_deny_unencrypted_object_uploads, false) - attach_elb_log_delivery_policy = try(each.value.attach_elb_log_delivery_policy, var.defaults.attach_elb_log_delivery_policy, false) - attach_inventory_destination_policy = try(each.value.attach_inventory_destination_policy, var.defaults.attach_inventory_destination_policy, false) - attach_lb_log_delivery_policy = try(each.value.attach_lb_log_delivery_policy, var.defaults.attach_lb_log_delivery_policy, false) - attach_policy = try(each.value.attach_policy, var.defaults.attach_policy, false) - attach_public_policy = try(each.value.attach_public_policy, var.defaults.attach_public_policy, true) - attach_require_latest_tls_policy = try(each.value.attach_require_latest_tls_policy, var.defaults.attach_require_latest_tls_policy, false) - block_public_acls = try(each.value.block_public_acls, var.defaults.block_public_acls, true) - block_public_policy = try(each.value.block_public_policy, var.defaults.block_public_policy, true) - bucket = try(each.value.bucket, var.defaults.bucket, null) - bucket_prefix = try(each.value.bucket_prefix, var.defaults.bucket_prefix, null) - control_object_ownership = try(each.value.control_object_ownership, var.defaults.control_object_ownership, false) - cors_rule = try(each.value.cors_rule, var.defaults.cors_rule, []) - create_bucket = try(each.value.create_bucket, var.defaults.create_bucket, true) - expected_bucket_owner = try(each.value.expected_bucket_owner, var.defaults.expected_bucket_owner, null) - force_destroy = try(each.value.force_destroy, var.defaults.force_destroy, false) - grant = try(each.value.grant, var.defaults.grant, []) - ignore_public_acls = try(each.value.ignore_public_acls, var.defaults.ignore_public_acls, true) - intelligent_tiering = try(each.value.intelligent_tiering, var.defaults.intelligent_tiering, {}) - inventory_configuration = try(each.value.inventory_configuration, var.defaults.inventory_configuration, {}) - inventory_self_source_destination = try(each.value.inventory_self_source_destination, var.defaults.inventory_self_source_destination, false) - inventory_source_account_id = try(each.value.inventory_source_account_id, var.defaults.inventory_source_account_id, null) - inventory_source_bucket_arn = try(each.value.inventory_source_bucket_arn, var.defaults.inventory_source_bucket_arn, null) - lifecycle_rule = try(each.value.lifecycle_rule, var.defaults.lifecycle_rule, []) - logging = try(each.value.logging, var.defaults.logging, {}) - metric_configuration = try(each.value.metric_configuration, var.defaults.metric_configuration, []) - object_lock_configuration = try(each.value.object_lock_configuration, var.defaults.object_lock_configuration, {}) - object_lock_enabled = try(each.value.object_lock_enabled, var.defaults.object_lock_enabled, false) - object_ownership = try(each.value.object_ownership, var.defaults.object_ownership, "BucketOwnerEnforced") - owner = try(each.value.owner, var.defaults.owner, {}) - policy = try(each.value.policy, var.defaults.policy, null) - putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true) - replication_configuration = try(each.value.replication_configuration, var.defaults.replication_configuration, {}) - request_payer = try(each.value.request_payer, var.defaults.request_payer, null) - restrict_public_buckets = try(each.value.restrict_public_buckets, var.defaults.restrict_public_buckets, true) - server_side_encryption_configuration = try(each.value.server_side_encryption_configuration, var.defaults.server_side_encryption_configuration, {}) - tags = try(each.value.tags, var.defaults.tags, {}) - transition_default_minimum_object_size = try(each.value.transition_default_minimum_object_size, var.defaults.transition_default_minimum_object_size, null) - versioning = try(each.value.versioning, var.defaults.versioning, {}) - website = try(each.value.website, var.defaults.website, {}) + 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, []) + access_log_delivery_policy_source_organizations = try(each.value.access_log_delivery_policy_source_organizations, var.defaults.access_log_delivery_policy_source_organizations, []) + acl = try(each.value.acl, var.defaults.acl, null) + allowed_kms_key_arn = try(each.value.allowed_kms_key_arn, var.defaults.allowed_kms_key_arn, null) + analytics_configuration = try(each.value.analytics_configuration, var.defaults.analytics_configuration, {}) + analytics_self_source_destination = try(each.value.analytics_self_source_destination, var.defaults.analytics_self_source_destination, false) + analytics_source_account_id = try(each.value.analytics_source_account_id, var.defaults.analytics_source_account_id, null) + analytics_source_bucket_arn = try(each.value.analytics_source_bucket_arn, var.defaults.analytics_source_bucket_arn, null) + attach_access_log_delivery_policy = try(each.value.attach_access_log_delivery_policy, var.defaults.attach_access_log_delivery_policy, false) + attach_analytics_destination_policy = try(each.value.attach_analytics_destination_policy, var.defaults.attach_analytics_destination_policy, false) + attach_deny_incorrect_encryption_headers = try(each.value.attach_deny_incorrect_encryption_headers, var.defaults.attach_deny_incorrect_encryption_headers, false) + attach_deny_incorrect_kms_key_sse = try(each.value.attach_deny_incorrect_kms_key_sse, var.defaults.attach_deny_incorrect_kms_key_sse, false) + attach_deny_insecure_transport_policy = try(each.value.attach_deny_insecure_transport_policy, var.defaults.attach_deny_insecure_transport_policy, false) + attach_deny_unencrypted_object_uploads = try(each.value.attach_deny_unencrypted_object_uploads, var.defaults.attach_deny_unencrypted_object_uploads, false) + attach_elb_log_delivery_policy = try(each.value.attach_elb_log_delivery_policy, var.defaults.attach_elb_log_delivery_policy, false) + attach_inventory_destination_policy = try(each.value.attach_inventory_destination_policy, var.defaults.attach_inventory_destination_policy, false) + attach_lb_log_delivery_policy = try(each.value.attach_lb_log_delivery_policy, var.defaults.attach_lb_log_delivery_policy, false) + attach_policy = try(each.value.attach_policy, var.defaults.attach_policy, false) + attach_public_policy = try(each.value.attach_public_policy, var.defaults.attach_public_policy, true) + attach_require_latest_tls_policy = try(each.value.attach_require_latest_tls_policy, var.defaults.attach_require_latest_tls_policy, false) + block_public_acls = try(each.value.block_public_acls, var.defaults.block_public_acls, true) + block_public_policy = try(each.value.block_public_policy, var.defaults.block_public_policy, true) + bucket = try(each.value.bucket, var.defaults.bucket, null) + bucket_prefix = try(each.value.bucket_prefix, var.defaults.bucket_prefix, null) + control_object_ownership = try(each.value.control_object_ownership, var.defaults.control_object_ownership, false) + cors_rule = try(each.value.cors_rule, var.defaults.cors_rule, []) + create_bucket = try(each.value.create_bucket, var.defaults.create_bucket, true) + expected_bucket_owner = try(each.value.expected_bucket_owner, var.defaults.expected_bucket_owner, null) + force_destroy = try(each.value.force_destroy, var.defaults.force_destroy, false) + grant = try(each.value.grant, var.defaults.grant, []) + ignore_public_acls = try(each.value.ignore_public_acls, var.defaults.ignore_public_acls, true) + intelligent_tiering = try(each.value.intelligent_tiering, var.defaults.intelligent_tiering, {}) + inventory_configuration = try(each.value.inventory_configuration, var.defaults.inventory_configuration, {}) + inventory_self_source_destination = try(each.value.inventory_self_source_destination, var.defaults.inventory_self_source_destination, false) + inventory_source_account_id = try(each.value.inventory_source_account_id, var.defaults.inventory_source_account_id, null) + inventory_source_bucket_arn = try(each.value.inventory_source_bucket_arn, var.defaults.inventory_source_bucket_arn, null) + lb_log_delivery_policy_source_organizations = try(each.value.lb_log_delivery_policy_source_organizations, var.defaults.lb_log_delivery_policy_source_organizations, []) + lifecycle_rule = try(each.value.lifecycle_rule, var.defaults.lifecycle_rule, []) + logging = try(each.value.logging, var.defaults.logging, {}) + metric_configuration = try(each.value.metric_configuration, var.defaults.metric_configuration, []) + object_lock_configuration = try(each.value.object_lock_configuration, var.defaults.object_lock_configuration, {}) + object_lock_enabled = try(each.value.object_lock_enabled, var.defaults.object_lock_enabled, false) + object_ownership = try(each.value.object_ownership, var.defaults.object_ownership, "BucketOwnerEnforced") + owner = try(each.value.owner, var.defaults.owner, {}) + policy = try(each.value.policy, var.defaults.policy, null) + putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true) + replication_configuration = try(each.value.replication_configuration, var.defaults.replication_configuration, {}) + request_payer = try(each.value.request_payer, var.defaults.request_payer, null) + restrict_public_buckets = try(each.value.restrict_public_buckets, var.defaults.restrict_public_buckets, true) + server_side_encryption_configuration = try(each.value.server_side_encryption_configuration, var.defaults.server_side_encryption_configuration, {}) + tags = try(each.value.tags, var.defaults.tags, {}) + transition_default_minimum_object_size = try(each.value.transition_default_minimum_object_size, var.defaults.transition_default_minimum_object_size, null) + versioning = try(each.value.versioning, var.defaults.versioning, {}) + website = try(each.value.website, var.defaults.website, {}) }