From 05ef663aad00c64caae88ddf1723c853baf0545a Mon Sep 17 00:00:00 2001 From: Aayush-Abhyarthi Date: Mon, 10 Nov 2025 14:51:25 +0530 Subject: [PATCH 1/6] allow public acces to cos buckets --- main.tf | 47 +++++++++++++++++++++++++++++++++++++++++++++-- variables.tf | 6 ++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 6b63c734..18099af4 100644 --- a/main.tf +++ b/main.tf @@ -107,6 +107,11 @@ resource "ibm_iam_authorization_policy" "policy" { } } +# use a data lookup to get the ID of the "Public Access" IAM access group +data "ibm_iam_access_group" "public_access_group" { + access_group_name = "Public Access" +} + # Create random string which is added to COS bucket name as a suffix resource "random_string" "bucket_name_suffix" { count = var.add_bucket_name_suffix ? 1 : 0 @@ -121,10 +126,15 @@ resource "random_string" "bucket_name_suffix" { # - Monitoring # - Activity Tracking # - Versioning + +locals { + cos_bucket_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${random_string.bucket_name_suffix[0].result}" : var.bucket_name +} + resource "ibm_cos_bucket" "cos_bucket" { count = (var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 depends_on = [time_sleep.wait_for_authorization_policy] - bucket_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${random_string.bucket_name_suffix[0].result}" : var.bucket_name + bucket_name = locals.cos_bucket_name resource_instance_id = local.cos_instance_id region_location = var.region cross_region_location = var.cross_region_location @@ -174,6 +184,20 @@ resource "ibm_cos_bucket" "cos_bucket" { } } +# create an IAM access policy to granting public access to this bucket +resource "ibm_iam_access_group_policy" "policy" { + count = var.allow_public_access_to_buckets ? 1 : 0 + access_group_id = data.ibm_iam_access_group.public_access_group.groups[0].id + roles = ["Object Reader"] + + resources { + service = "cloud-object-storage" + resource_type = "bucket" + resource_instance_id = local.cos_instance_guid + resource = local.cos_bucket_name + } +} + # Create COS bucket with: # - Retention # - Monitoring @@ -181,9 +205,14 @@ resource "ibm_cos_bucket" "cos_bucket" { # - Versioning # Create COS bucket without: # - Encryption + +locals { + cos_bucket1_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${random_string.bucket_name_suffix[0].result}" : var.bucket_name +} + resource "ibm_cos_bucket" "cos_bucket1" { count = (!var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 - bucket_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${random_string.bucket_name_suffix[0].result}" : var.bucket_name + bucket_name = local.cos_bucket1_name depends_on = [time_sleep.wait_for_authorization_policy] resource_instance_id = local.cos_instance_id region_location = var.region @@ -233,6 +262,20 @@ resource "ibm_cos_bucket" "cos_bucket1" { } } +# create an IAM access policy to granting public access to this bucket +resource "ibm_iam_access_group_policy" "policy" { + count = var.allow_public_access_to_buckets ? 1 : 0 + access_group_id = data.ibm_iam_access_group.public_access_group.groups[0].id + roles = ["Object Reader"] + + resources { + service = "cloud-object-storage" + resource_type = "bucket" + resource_instance_id = local.cos_instance_guid + resource = local.cos_bucket_name + } +} + locals { expiration_or_archiving_or_noncurrent_version_expiration_rule_enabled = (length(local.expire_enabled) != 0 || length(local.archive_enabled) != 0 || length(local.noncurrent_version_expiration_enabled) != 0 || length(local.abort_multipart_enabled) != 0) diff --git a/variables.tf b/variables.tf index ac6575ae..94f17ba2 100644 --- a/variables.tf +++ b/variables.tf @@ -149,6 +149,12 @@ variable "bucket_name" { } } +variable "allow_public_access_to_buckets" { + type = bool + description = "Set it to `true` to allow the cos bucket to be publically accessible." + default = false +} + variable "add_bucket_name_suffix" { type = bool description = "Whether to add a randomly generated 4-character suffix to the bucket name." From 5644197662fa2b02278e2a085cd7b48d3ef91b9c Mon Sep 17 00:00:00 2001 From: Aayush-Abhyarthi Date: Mon, 17 Nov 2025 14:30:36 +0530 Subject: [PATCH 2/6] expose in DAs --- .secrets.baseline | 4 +- README.md | 4 ++ common-dev-assets | 2 +- ibm_catalog.json | 12 ++++++ main.tf | 10 ++--- modules/buckets/README.md | 2 +- modules/buckets/main.tf | 17 +++++---- modules/buckets/variables.tf | 37 ++++++++++--------- .../fully-configurable/main.tf | 33 +++++++++-------- .../fully-configurable/variables.tf | 6 +++ .../security-enforced/main.tf | 1 + .../security-enforced/variables.tf | 6 +++ .../fully-configurable/main.tf | 33 +++++++++-------- .../fully-configurable/variables.tf | 6 +++ .../regional-bucket/security-enforced/main.tf | 1 + .../security-enforced/variables.tf | 6 +++ tests/pr_test.go | 1 + variables.tf | 6 +-- 18 files changed, 117 insertions(+), 70 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 0e9ac7f8..fe1fd750 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-10-27T07:59:48Z", + "generated_at": "2025-11-17T08:56:04Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -90,7 +90,7 @@ "hashed_secret": "a7c93faaa770c377154ea9d4d0d17a9056dbfa95", "is_secret": false, "is_verified": false, - "line_number": 193, + "line_number": 197, "type": "Secret Keyword", "verified_result": null } diff --git a/README.md b/README.md index 70addc10..ea173617 100644 --- a/README.md +++ b/README.md @@ -140,12 +140,15 @@ You need the following permissions to run this module. | [ibm_cos_bucket.cos_bucket1](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/cos_bucket) | resource | | [ibm_cos_bucket_lifecycle_configuration.cos_bucket_lifecycle](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/cos_bucket_lifecycle_configuration) | resource | | [ibm_cos_bucket_object_lock_configuration.lock_configuration](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/cos_bucket_object_lock_configuration) | resource | +| [ibm_iam_access_group_policy.access_policy](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/iam_access_group_policy) | resource | +| [ibm_iam_access_group_policy.access_policy1](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/iam_access_group_policy) | resource | | [ibm_iam_authorization_policy.policy](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource | | [ibm_resource_instance.cos_instance](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/resource_instance) | resource | | [ibm_resource_key.resource_keys](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/resource_key) | resource | | [ibm_resource_tag.cos_access_tag](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/resource_tag) | resource | | [random_string.bucket_name_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | | [time_sleep.wait_for_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | +| [ibm_iam_access_group.public_access_group](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/data-sources/iam_access_group) | data source | ### Inputs @@ -158,6 +161,7 @@ You need the following permissions to run this module. | [activity\_tracker\_read\_data\_events](#input\_activity\_tracker\_read\_data\_events) | If set to `true`, all Object Storage bucket read events (i.e. downloads) are sent to Activity Tracker Event Routing. | `bool` | `true` | no | | [activity\_tracker\_write\_data\_events](#input\_activity\_tracker\_write\_data\_events) | If set to `true`, all Object Storage bucket write events (i.e. uploads) are sent to Activity Tracker Event Routing. | `bool` | `true` | no | | [add\_bucket\_name\_suffix](#input\_add\_bucket\_name\_suffix) | Whether to add a randomly generated 4-character suffix to the bucket name. | `bool` | `true` | no | +| [allow\_public\_access\_to\_buckets](#input\_allow\_public\_access\_to\_buckets) | Set it to `true` to allow the cos bucket to be publicly accessible. | `bool` | `false` | no | | [archive\_days](#input\_archive\_days) | The number of days before the `archive_type` rule action takes effect. Applies only if `create_cos_bucket` is set to `true`. Set to `null` if you specify a bucket location in `cross_region_location` because archive data is not supported with cross-region buckets. If null is passed, no lifecycle configuration will be added for bucket archival. | `number` | `null` | no | | [archive\_filter\_prefix](#input\_archive\_filter\_prefix) | Apply archive lifecycle rule to only objects with the following prefix. Applies to all objects by default. | `string` | `null` | no | | [archive\_type](#input\_archive\_type) | The storage class or archive type to which you want the object to transition. Possible values are `Glacier` or `Accelerated`. Applies only if `create_cos_bucket` is set to `true`. | `string` | `"Glacier"` | no | diff --git a/common-dev-assets b/common-dev-assets index 6a351e62..03a51f8c 160000 --- a/common-dev-assets +++ b/common-dev-assets @@ -1 +1 @@ -Subproject commit 6a351e62a04ea8bf074d4933c86cd28671154d3b +Subproject commit 03a51f8c4fadb23f8d26460eac6118d961b28bf8 diff --git a/ibm_catalog.json b/ibm_catalog.json index 4ced6d0e..aa20003b 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -343,6 +343,9 @@ "key": "bucket_name", "required": true }, + { + "key": "allow_public_access_to_buckets" + }, { "key": "provider_visibility", "hidden": true, @@ -789,6 +792,9 @@ "key": "bucket_name", "required": true }, + { + "key": "allow_public_access_to_buckets" + }, { "key": "add_bucket_name_suffix" }, @@ -1243,6 +1249,9 @@ "key": "bucket_name", "required": true }, + { + "key": "allow_public_access_to_buckets" + }, { "key": "provider_visibility", "hidden": true, @@ -1732,6 +1741,9 @@ "key": "bucket_name", "required": true }, + { + "key": "allow_public_access_to_buckets" + }, { "key": "add_bucket_name_suffix" }, diff --git a/main.tf b/main.tf index 49826ee0..33f6121b 100644 --- a/main.tf +++ b/main.tf @@ -134,7 +134,7 @@ locals { resource "ibm_cos_bucket" "cos_bucket" { count = (var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 depends_on = [time_sleep.wait_for_authorization_policy] - bucket_name = locals.cos_bucket_name + bucket_name = local.cos_bucket_name resource_instance_id = local.cos_instance_id region_location = var.region cross_region_location = var.cross_region_location @@ -185,8 +185,8 @@ resource "ibm_cos_bucket" "cos_bucket" { } # create an IAM access policy to granting public access to this bucket -resource "ibm_iam_access_group_policy" "policy" { - count = var.allow_public_access_to_buckets ? 1 : 0 +resource "ibm_iam_access_group_policy" "access_policy" { + count = var.allow_public_access_to_buckets ? 1 : 0 access_group_id = data.ibm_iam_access_group.public_access_group.groups[0].id roles = ["Object Reader"] @@ -263,8 +263,8 @@ resource "ibm_cos_bucket" "cos_bucket1" { } # create an IAM access policy to granting public access to this bucket -resource "ibm_iam_access_group_policy" "policy" { - count = var.allow_public_access_to_buckets ? 1 : 0 +resource "ibm_iam_access_group_policy" "access_policy1" { + count = var.allow_public_access_to_buckets ? 1 : 0 access_group_id = data.ibm_iam_access_group.public_access_group.groups[0].id roles = ["Object Reader"] diff --git a/modules/buckets/README.md b/modules/buckets/README.md index 01ea2f5b..a93bb320 100644 --- a/modules/buckets/README.md +++ b/modules/buckets/README.md @@ -82,7 +82,7 @@ You need the following permissions to run this module. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [bucket\_configs](#input\_bucket\_configs) | The Object Storage bucket configurations. |
list(object({
access_tags = optional(list(string), [])
add_bucket_name_suffix = optional(bool, true)
bucket_name = string
kms_encryption_enabled = optional(bool, true)
kms_guid = optional(string, null)
kms_key_crn = optional(string, null)
skip_iam_authorization_policy = optional(bool, false)
management_endpoint_type = optional(string, "public")
cross_region_location = optional(string, null)
storage_class = optional(string, "smart")
region_location = optional(string, null)
resource_instance_id = string
force_delete = optional(bool, true)
single_site_location = optional(string, null)
hard_quota = optional(number, null)
object_locking_enabled = optional(bool, false)
object_lock_duration_days = optional(number, 0)
object_lock_duration_years = optional(number, 0)

activity_tracking = optional(object({
read_data_events = optional(bool, true)
write_data_events = optional(bool, true)
management_events = optional(bool, true)
}))
archive_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
type = optional(string, "Glacier")
archive_filter_prefix = optional(string, null)
}))
expire_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
expire_filter_prefix = optional(string, null)
}))
abort_multipart_enabled_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
abort_multipart_filter_prefix = optional(string, null)
}))
noncurrent_version_expiration_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
noncurrent_version_expiration_filter_prefix = optional(string, null)
}))
metrics_monitoring = optional(object({
usage_metrics_enabled = optional(bool, true)
request_metrics_enabled = optional(bool, true)
metrics_monitoring_crn = optional(string, null)
}))
object_versioning = optional(object({
enable = optional(bool, false)
}))
retention_rule = optional(object({
default = optional(number, 90)
maximum = optional(number, 350)
minimum = optional(number, 90)
permanent = optional(bool, false)
}))
cbr_rules = optional(list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
tags = optional(list(object({
name = string
value = string
})), [])
operations = optional(list(object({
api_types = list(object({
api_type_id = string
}))
})))
})), [])

}))
| n/a | yes | +| [bucket\_configs](#input\_bucket\_configs) | The Object Storage bucket configurations. |
list(object({
access_tags = optional(list(string), [])
add_bucket_name_suffix = optional(bool, true)
bucket_name = string
allow_public_access_to_buckets = optional(bool, false)
kms_encryption_enabled = optional(bool, true)
kms_guid = optional(string, null)
kms_key_crn = optional(string, null)
skip_iam_authorization_policy = optional(bool, false)
management_endpoint_type = optional(string, "public")
cross_region_location = optional(string, null)
storage_class = optional(string, "smart")
region_location = optional(string, null)
resource_instance_id = string
force_delete = optional(bool, true)
single_site_location = optional(string, null)
hard_quota = optional(number, null)
object_locking_enabled = optional(bool, false)
object_lock_duration_days = optional(number, 0)
object_lock_duration_years = optional(number, 0)

activity_tracking = optional(object({
read_data_events = optional(bool, true)
write_data_events = optional(bool, true)
management_events = optional(bool, true)
}))
archive_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
type = optional(string, "Glacier")
archive_filter_prefix = optional(string, null)
}))
expire_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
expire_filter_prefix = optional(string, null)
}))
abort_multipart_enabled_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
abort_multipart_filter_prefix = optional(string, null)
}))
noncurrent_version_expiration_rule = optional(object({
enable = optional(bool, false)
days = optional(number, null)
noncurrent_version_expiration_filter_prefix = optional(string, null)
}))
metrics_monitoring = optional(object({
usage_metrics_enabled = optional(bool, true)
request_metrics_enabled = optional(bool, true)
metrics_monitoring_crn = optional(string, null)
}))
object_versioning = optional(object({
enable = optional(bool, false)
}))
retention_rule = optional(object({
default = optional(number, 90)
maximum = optional(number, 350)
minimum = optional(number, 90)
permanent = optional(bool, false)
}))
cbr_rules = optional(list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
tags = optional(list(object({
name = string
value = string
})), [])
operations = optional(list(object({
api_types = list(object({
api_type_id = string
}))
})))
})), [])

}))
| n/a | yes | ### Outputs diff --git a/modules/buckets/main.tf b/modules/buckets/main.tf index 913277ce..80779e81 100644 --- a/modules/buckets/main.tf +++ b/modules/buckets/main.tf @@ -70,14 +70,15 @@ module "buckets" { for index, bucket in var.bucket_configs : bucket.bucket_name => bucket } - depends_on = [time_sleep.wait_for_authorization_policy] - source = "../../" - bucket_name = each.value.bucket_name - create_cos_instance = false - add_bucket_name_suffix = each.value.add_bucket_name_suffix - skip_iam_authorization_policy = true - existing_cos_instance_id = each.value.resource_instance_id - region = each.value.region_location + depends_on = [time_sleep.wait_for_authorization_policy] + source = "../../" + bucket_name = each.value.bucket_name + allow_public_access_to_buckets = each.value.allow_public_access_to_buckets + create_cos_instance = false + add_bucket_name_suffix = each.value.add_bucket_name_suffix + skip_iam_authorization_policy = true + existing_cos_instance_id = each.value.resource_instance_id + region = each.value.region_location cross_region_location = each.value.cross_region_location single_site_location = each.value.single_site_location diff --git a/modules/buckets/variables.tf b/modules/buckets/variables.tf index 9b943bd2..5e0dcbd6 100644 --- a/modules/buckets/variables.tf +++ b/modules/buckets/variables.tf @@ -7,24 +7,25 @@ ############################################################################## variable "bucket_configs" { type = list(object({ - access_tags = optional(list(string), []) - add_bucket_name_suffix = optional(bool, true) - bucket_name = string - kms_encryption_enabled = optional(bool, true) - kms_guid = optional(string, null) - kms_key_crn = optional(string, null) - skip_iam_authorization_policy = optional(bool, false) - management_endpoint_type = optional(string, "public") - cross_region_location = optional(string, null) - storage_class = optional(string, "smart") - region_location = optional(string, null) - resource_instance_id = string - force_delete = optional(bool, true) - single_site_location = optional(string, null) - hard_quota = optional(number, null) - object_locking_enabled = optional(bool, false) - object_lock_duration_days = optional(number, 0) - object_lock_duration_years = optional(number, 0) + access_tags = optional(list(string), []) + add_bucket_name_suffix = optional(bool, true) + bucket_name = string + allow_public_access_to_buckets = optional(bool, false) + kms_encryption_enabled = optional(bool, true) + kms_guid = optional(string, null) + kms_key_crn = optional(string, null) + skip_iam_authorization_policy = optional(bool, false) + management_endpoint_type = optional(string, "public") + cross_region_location = optional(string, null) + storage_class = optional(string, "smart") + region_location = optional(string, null) + resource_instance_id = string + force_delete = optional(bool, true) + single_site_location = optional(string, null) + hard_quota = optional(number, null) + object_locking_enabled = optional(bool, false) + object_lock_duration_days = optional(number, 0) + object_lock_duration_years = optional(number, 0) activity_tracking = optional(object({ read_data_events = optional(bool, true) diff --git a/solutions/cross-regional-bucket/fully-configurable/main.tf b/solutions/cross-regional-bucket/fully-configurable/main.tf index 0aa5ebe3..9305c224 100644 --- a/solutions/cross-regional-bucket/fully-configurable/main.tf +++ b/solutions/cross-regional-bucket/fully-configurable/main.tf @@ -9,22 +9,23 @@ locals { locals { bucket_config = [{ - access_tags = var.bucket_access_tags - bucket_name = "${local.prefix}${var.bucket_name}" - kms_encryption_enabled = var.kms_encryption_enabled - add_bucket_name_suffix = var.add_bucket_name_suffix - kms_guid = local.existing_kms_instance_guid - kms_key_crn = local.kms_key_crn - skip_iam_authorization_policy = local.create_cross_account_auth_policy || var.skip_cos_kms_iam_auth_policy - management_endpoint_type = var.management_endpoint_type_for_bucket - cross_region_location = var.cross_region_location - resource_instance_id = var.existing_cos_instance_crn - storage_class = var.bucket_storage_class - force_delete = var.force_delete - hard_quota = var.bucket_hard_quota - object_locking_enabled = var.enable_object_locking - object_lock_duration_days = var.object_lock_duration_days - object_lock_duration_years = var.object_lock_duration_years + access_tags = var.bucket_access_tags + bucket_name = "${local.prefix}${var.bucket_name}" + allow_public_access_to_buckets = var.allow_public_access_to_buckets + kms_encryption_enabled = var.kms_encryption_enabled + add_bucket_name_suffix = var.add_bucket_name_suffix + kms_guid = local.existing_kms_instance_guid + kms_key_crn = local.kms_key_crn + skip_iam_authorization_policy = local.create_cross_account_auth_policy || var.skip_cos_kms_iam_auth_policy + management_endpoint_type = var.management_endpoint_type_for_bucket + cross_region_location = var.cross_region_location + resource_instance_id = var.existing_cos_instance_crn + storage_class = var.bucket_storage_class + force_delete = var.force_delete + hard_quota = var.bucket_hard_quota + object_locking_enabled = var.enable_object_locking + object_lock_duration_days = var.object_lock_duration_days + object_lock_duration_years = var.object_lock_duration_years activity_tracking = { read_data_events = true diff --git a/solutions/cross-regional-bucket/fully-configurable/variables.tf b/solutions/cross-regional-bucket/fully-configurable/variables.tf index edf5c285..c4387595 100644 --- a/solutions/cross-regional-bucket/fully-configurable/variables.tf +++ b/solutions/cross-regional-bucket/fully-configurable/variables.tf @@ -122,6 +122,12 @@ variable "bucket_name" { description = "The name to give the newly provisioned Object Storage bucket." } +variable "allow_public_access_to_buckets" { + type = bool + description = "Set it to `true` to allow the cos bucket to be publicly accessible." + default = false +} + variable "management_endpoint_type_for_bucket" { description = "The type of endpoint for the IBM terraform provider to manage the bucket. Possible values: `public`, `private`, `direct`." type = string diff --git a/solutions/cross-regional-bucket/security-enforced/main.tf b/solutions/cross-regional-bucket/security-enforced/main.tf index 7eefb722..f41c8e4e 100644 --- a/solutions/cross-regional-bucket/security-enforced/main.tf +++ b/solutions/cross-regional-bucket/security-enforced/main.tf @@ -14,6 +14,7 @@ module "cross_regional_bucket" { existing_cos_instance_crn = var.existing_cos_instance_crn bucket_access_tags = var.bucket_access_tags bucket_name = var.bucket_name + allow_public_access_to_buckets = var.allow_public_access_to_buckets management_endpoint_type_for_bucket = var.management_endpoint_type_for_bucket cross_region_location = var.cross_region_location bucket_storage_class = var.bucket_storage_class diff --git a/solutions/cross-regional-bucket/security-enforced/variables.tf b/solutions/cross-regional-bucket/security-enforced/variables.tf index 585162cb..900f99c2 100644 --- a/solutions/cross-regional-bucket/security-enforced/variables.tf +++ b/solutions/cross-regional-bucket/security-enforced/variables.tf @@ -96,6 +96,12 @@ variable "bucket_name" { description = "The name to give the newly provisioned Object Storage bucket." } +variable "allow_public_access_to_buckets" { + type = bool + description = "Set it to `true` to allow the cos bucket to be publicly accessible." + default = false +} + variable "management_endpoint_type_for_bucket" { description = "The type of endpoint for the IBM terraform provider to manage the bucket. Possible values: `private`, `direct`." type = string diff --git a/solutions/regional-bucket/fully-configurable/main.tf b/solutions/regional-bucket/fully-configurable/main.tf index 26972051..eefc0e72 100644 --- a/solutions/regional-bucket/fully-configurable/main.tf +++ b/solutions/regional-bucket/fully-configurable/main.tf @@ -8,22 +8,23 @@ locals { locals { bucket_config = [{ - access_tags = var.bucket_access_tags - bucket_name = "${local.prefix}${var.bucket_name}" - kms_encryption_enabled = var.kms_encryption_enabled - add_bucket_name_suffix = var.add_bucket_name_suffix - kms_guid = local.existing_kms_instance_guid - kms_key_crn = local.kms_key_crn - skip_iam_authorization_policy = local.create_cross_account_auth_policy || var.skip_cos_kms_iam_auth_policy - management_endpoint_type = var.management_endpoint_type_for_bucket - region_location = var.region - resource_instance_id = var.existing_cos_instance_crn - storage_class = var.bucket_storage_class - force_delete = var.force_delete - hard_quota = var.bucket_hard_quota - object_locking_enabled = var.enable_object_locking - object_lock_duration_days = var.object_lock_duration_days - object_lock_duration_years = var.object_lock_duration_years + access_tags = var.bucket_access_tags + bucket_name = "${local.prefix}${var.bucket_name}" + allow_public_access_to_buckets = var.allow_public_access_to_buckets + kms_encryption_enabled = var.kms_encryption_enabled + add_bucket_name_suffix = var.add_bucket_name_suffix + kms_guid = local.existing_kms_instance_guid + kms_key_crn = local.kms_key_crn + skip_iam_authorization_policy = local.create_cross_account_auth_policy || var.skip_cos_kms_iam_auth_policy + management_endpoint_type = var.management_endpoint_type_for_bucket + region_location = var.region + resource_instance_id = var.existing_cos_instance_crn + storage_class = var.bucket_storage_class + force_delete = var.force_delete + hard_quota = var.bucket_hard_quota + object_locking_enabled = var.enable_object_locking + object_lock_duration_days = var.object_lock_duration_days + object_lock_duration_years = var.object_lock_duration_years activity_tracking = { read_data_events = true diff --git a/solutions/regional-bucket/fully-configurable/variables.tf b/solutions/regional-bucket/fully-configurable/variables.tf index 600a3af4..4a8d64ac 100644 --- a/solutions/regional-bucket/fully-configurable/variables.tf +++ b/solutions/regional-bucket/fully-configurable/variables.tf @@ -132,6 +132,12 @@ variable "bucket_name" { description = "The name to give the newly provisioned Object Storage bucket." } +variable "allow_public_access_to_buckets" { + type = bool + description = "Set it to `true` to allow the cos bucket to be publicly accessible." + default = false +} + variable "management_endpoint_type_for_bucket" { description = "The type of endpoint for the IBM terraform provider to manage the bucket. Possible values: `public`, `private`, `direct`." type = string diff --git a/solutions/regional-bucket/security-enforced/main.tf b/solutions/regional-bucket/security-enforced/main.tf index 7d470e9a..a21a6c21 100644 --- a/solutions/regional-bucket/security-enforced/main.tf +++ b/solutions/regional-bucket/security-enforced/main.tf @@ -14,6 +14,7 @@ module "regional_bucket" { existing_cos_instance_crn = var.existing_cos_instance_crn bucket_access_tags = var.bucket_access_tags bucket_name = var.bucket_name + allow_public_access_to_buckets = var.allow_public_access_to_buckets management_endpoint_type_for_bucket = var.management_endpoint_type_for_bucket region = var.region bucket_storage_class = var.bucket_storage_class diff --git a/solutions/regional-bucket/security-enforced/variables.tf b/solutions/regional-bucket/security-enforced/variables.tf index 83428b8b..254b6be6 100644 --- a/solutions/regional-bucket/security-enforced/variables.tf +++ b/solutions/regional-bucket/security-enforced/variables.tf @@ -105,6 +105,12 @@ variable "bucket_name" { description = "The name to give the newly provisioned Object Storage bucket." } +variable "allow_public_access_to_buckets" { + type = bool + description = "Set it to `true` to allow the cos bucket to be publicly accessible." + default = false +} + variable "management_endpoint_type_for_bucket" { description = "The type of endpoint for the IBM terraform provider to manage the bucket. Possible values: `private`, `direct`." type = string diff --git a/tests/pr_test.go b/tests/pr_test.go index 7c9957b1..6eaffb63 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -448,6 +448,7 @@ func TestRunCrossRegionalFullyConfigurableSchematics(t *testing.T) { {Name: "prefix", Value: options.Prefix, DataType: "string"}, {Name: "existing_cos_instance_crn", Value: permanentResources["general_test_storage_cos_instance_crn"], DataType: "string"}, {Name: "bucket_name", Value: "cr-bucket", DataType: "string"}, + {Name: "allow_public_access_to_buckets", Value: true, DataType: "bool"}, } err := options.RunSchematicTest() diff --git a/variables.tf b/variables.tf index 94f17ba2..3f2dfa05 100644 --- a/variables.tf +++ b/variables.tf @@ -150,9 +150,9 @@ variable "bucket_name" { } variable "allow_public_access_to_buckets" { - type = bool - description = "Set it to `true` to allow the cos bucket to be publically accessible." - default = false + type = bool + description = "Set it to `true` to allow the cos bucket to be publicly accessible." + default = false } variable "add_bucket_name_suffix" { From 97d335112819a88ab1064052b2c8e309f2d65123 Mon Sep 17 00:00:00 2001 From: Aayush-Abhyarthi Date: Mon, 24 Nov 2025 14:46:41 +0530 Subject: [PATCH 3/6] fix: error --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 33f6121b..1cd0771d 100644 --- a/main.tf +++ b/main.tf @@ -109,7 +109,7 @@ resource "ibm_iam_authorization_policy" "policy" { # use a data lookup to get the ID of the "Public Access" IAM access group data "ibm_iam_access_group" "public_access_group" { - access_group_name = "Public Access" + access_group_name = "geretain-public-access" } # Create random string which is added to COS bucket name as a suffix From a699340683d490de252925608ed3c10565b54d1f Mon Sep 17 00:00:00 2001 From: Aayush-Abhyarthi Date: Mon, 24 Nov 2025 14:49:59 +0530 Subject: [PATCH 4/6] update: common dev assets --- common-dev-assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-dev-assets b/common-dev-assets index 03a51f8c..cefc143f 160000 --- a/common-dev-assets +++ b/common-dev-assets @@ -1 +1 @@ -Subproject commit 03a51f8c4fadb23f8d26460eac6118d961b28bf8 +Subproject commit cefc143fe9db966925c422ed7c67d7554288e8ff From b497b0d52b3375ef43e5a9d9ea162b914fda2734 Mon Sep 17 00:00:00 2001 From: Aayush-Abhyarthi Date: Mon, 1 Dec 2025 00:12:04 +0530 Subject: [PATCH 5/6] fix: error --- common-dev-assets | 2 +- main.tf | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/common-dev-assets b/common-dev-assets index cefc143f..238892dd 160000 --- a/common-dev-assets +++ b/common-dev-assets @@ -1 +1 @@ -Subproject commit cefc143fe9db966925c422ed7c67d7554288e8ff +Subproject commit 238892dddce116998ab6b6ebdb998708401174d1 diff --git a/main.tf b/main.tf index 1cd0771d..4c2e7895 100644 --- a/main.tf +++ b/main.tf @@ -128,13 +128,13 @@ resource "random_string" "bucket_name_suffix" { # - Versioning locals { - cos_bucket_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${random_string.bucket_name_suffix[0].result}" : var.bucket_name + random_suffix = random_string.bucket_name_suffix[0].result } resource "ibm_cos_bucket" "cos_bucket" { count = (var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 depends_on = [time_sleep.wait_for_authorization_policy] - bucket_name = local.cos_bucket_name + bucket_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${local.random_suffix}" : var.bucket_name resource_instance_id = local.cos_instance_id region_location = var.region cross_region_location = var.cross_region_location @@ -194,7 +194,7 @@ resource "ibm_iam_access_group_policy" "access_policy" { service = "cloud-object-storage" resource_type = "bucket" resource_instance_id = local.cos_instance_guid - resource = local.cos_bucket_name + resource = var.add_bucket_name_suffix ? "${var.bucket_name}-${local.random_suffix}" : var.bucket_name } } @@ -206,13 +206,9 @@ resource "ibm_iam_access_group_policy" "access_policy" { # Create COS bucket without: # - Encryption -locals { - cos_bucket1_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${random_string.bucket_name_suffix[0].result}" : var.bucket_name -} - resource "ibm_cos_bucket" "cos_bucket1" { count = (!var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 - bucket_name = local.cos_bucket1_name + bucket_name = var.add_bucket_name_suffix ? "${var.bucket_name}-${local.random_suffix}" : var.bucket_name depends_on = [time_sleep.wait_for_authorization_policy] resource_instance_id = local.cos_instance_id region_location = var.region @@ -272,7 +268,7 @@ resource "ibm_iam_access_group_policy" "access_policy1" { service = "cloud-object-storage" resource_type = "bucket" resource_instance_id = local.cos_instance_guid - resource = local.cos_bucket_name + resource = var.add_bucket_name_suffix ? "${var.bucket_name}-${local.random_suffix}" : var.bucket_name } } From a434a5bee6bfc0bfc92e095e1384dad8f12b9355 Mon Sep 17 00:00:00 2001 From: Aayush-Abhyarthi Date: Mon, 1 Dec 2025 02:01:25 +0530 Subject: [PATCH 6/6] fix: policy condition --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 4c2e7895..4b7a8a02 100644 --- a/main.tf +++ b/main.tf @@ -186,7 +186,7 @@ resource "ibm_cos_bucket" "cos_bucket" { # create an IAM access policy to granting public access to this bucket resource "ibm_iam_access_group_policy" "access_policy" { - count = var.allow_public_access_to_buckets ? 1 : 0 + count = (var.allow_public_access_to_buckets && var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 access_group_id = data.ibm_iam_access_group.public_access_group.groups[0].id roles = ["Object Reader"] @@ -260,7 +260,7 @@ resource "ibm_cos_bucket" "cos_bucket1" { # create an IAM access policy to granting public access to this bucket resource "ibm_iam_access_group_policy" "access_policy1" { - count = var.allow_public_access_to_buckets ? 1 : 0 + count = (var.allow_public_access_to_buckets && !var.kms_encryption_enabled && var.create_cos_bucket) ? 1 : 0 access_group_id = data.ibm_iam_access_group.public_access_group.groups[0].id roles = ["Object Reader"]