From e681f7473acff2fe4d80efc1edde80ffec7b55e4 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Tue, 3 Jun 2025 13:58:52 -0400 Subject: [PATCH 01/11] feat: fully configurable da --- .catalog-onboard-pipeline.yaml | 2 +- ibm_catalog.json | 33 +++++++++----- .../DA-cbr_rules.md | 0 .../DA-types.md | 0 .../README.md | 0 .../catalogValidationValues.json.template | 1 - .../{standard => fully-configurable}/main.tf | 45 +++++++++---------- .../{standard => fully-configurable}/moved.tf | 0 .../outputs.tf | 0 .../provider.tf | 0 .../variables.tf | 34 ++++++++++---- .../version.tf | 0 12 files changed, 67 insertions(+), 48 deletions(-) rename solutions/{standard => fully-configurable}/DA-cbr_rules.md (100%) rename solutions/{standard => fully-configurable}/DA-types.md (100%) rename solutions/{standard => fully-configurable}/README.md (100%) rename solutions/{standard => fully-configurable}/catalogValidationValues.json.template (82%) rename solutions/{standard => fully-configurable}/main.tf (82%) rename solutions/{standard => fully-configurable}/moved.tf (100%) rename solutions/{standard => fully-configurable}/outputs.tf (100%) rename solutions/{standard => fully-configurable}/provider.tf (100%) rename solutions/{standard => fully-configurable}/variables.tf (93%) rename solutions/{standard => fully-configurable}/version.tf (100%) diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index 24b56c2d..a356d7f0 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -6,7 +6,7 @@ offerings: catalog_id: 7df1e4ca-d54c-4fd0-82ce-3d13247308cd offering_id: 01f5b01a-3650-4acf-aaf3-4790f7cbd422 variations: - - name: standard + - name: fully-configurable mark_ready: true install_type: fullstack scc: diff --git a/ibm_catalog.json b/ibm_catalog.json index b825340e..d695ba83 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -46,10 +46,10 @@ ], "flavors": [ { - "label": "Standard", - "name": "standard", + "label": "Fully Configurable", + "name": "fully-configurable", "install_type": "fullstack", - "working_directory": "solutions/standard", + "working_directory": "solutions/fully-configurable", "compliance": { "authority": "scc-v3", "profiles": [ @@ -84,7 +84,7 @@ "features": [ { "title": " Creates an instance of Databases for RabbitMQ", - "description": "This architecture creates an instance of IBM Cloud Messages for RabbitMQ with KMS encryption. It accepts or creates a resource group, and provides autoscaling rules." + "description": "This architecture creates an instance of IBM Cloud Messages for RabbitMQ with optional KMS encryption. It accepts a resource group, and provides autoscaling rules." } ], "diagrams": [ @@ -94,7 +94,7 @@ "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/main/reference-architecture/deployable-architecture-rabbitmq.svg", "type": "image/svg+xml" }, - "description": "This architecture supports creating and configuring an instance of Messages for RabbitMQ instance with KMS encryption." + "description": "This architecture supports creating and configuring an instance of Messages for RabbitMQ instance with optional KMS encryption." } ] }, @@ -120,13 +120,20 @@ ] }, { - "key": "use_existing_resource_group" - }, - { - "key": "resource_group_name" + "key": "existing_resource_group_name", + "required": true, + "custom_config": { + "type": "resource_group", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "identifier": "rg_name" + } + } }, { - "key": "prefix" + "key": "prefix", + "required": true }, { "key": "name" @@ -200,6 +207,9 @@ } ] }, + { + "key": "rabbitmq_service_endpoints" + }, { "key": "members" }, @@ -251,8 +261,7 @@ "key": "ibmcloud_kms_api_key" }, { - "key": "existing_kms_instance_crn", - "required": true + "key": "existing_kms_instance_crn" }, { "key": "existing_kms_key_crn" diff --git a/solutions/standard/DA-cbr_rules.md b/solutions/fully-configurable/DA-cbr_rules.md similarity index 100% rename from solutions/standard/DA-cbr_rules.md rename to solutions/fully-configurable/DA-cbr_rules.md diff --git a/solutions/standard/DA-types.md b/solutions/fully-configurable/DA-types.md similarity index 100% rename from solutions/standard/DA-types.md rename to solutions/fully-configurable/DA-types.md diff --git a/solutions/standard/README.md b/solutions/fully-configurable/README.md similarity index 100% rename from solutions/standard/README.md rename to solutions/fully-configurable/README.md diff --git a/solutions/standard/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template similarity index 82% rename from solutions/standard/catalogValidationValues.json.template rename to solutions/fully-configurable/catalogValidationValues.json.template index e69e502f..3576f866 100644 --- a/solutions/standard/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -3,6 +3,5 @@ "region": "us-south", "tags": $TAGS, "name": $PREFIX, - "resource_group_name": $PREFIX, "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN } diff --git a/solutions/standard/main.tf b/solutions/fully-configurable/main.tf similarity index 82% rename from solutions/standard/main.tf rename to solutions/fully-configurable/main.tf index e3914d17..dc47d296 100644 --- a/solutions/standard/main.tf +++ b/solutions/fully-configurable/main.tf @@ -5,25 +5,18 @@ module "resource_group" { source = "terraform-ibm-modules/resource-group/ibm" version = "1.2.0" - resource_group_name = var.use_existing_resource_group == false ? (var.prefix != null ? "${var.prefix}-${var.resource_group_name}" : var.resource_group_name) : null - existing_resource_group_name = var.use_existing_resource_group == true ? var.resource_group_name : null + existing_resource_group_name = var.existing_resource_group_name } -####################################################################################################################### -# KMS related variable validation -# (approach based on https://github.com/hashicorp/terraform/issues/25609#issuecomment-1057614400) -# -# TODO: Replace with terraform cross variable validation: https://github.ibm.com/GoldenEye/issues/issues/10836 -####################################################################################################################### - ####################################################################################################################### # KMS encryption key ####################################################################################################################### locals { - create_new_kms_key = var.existing_rabbitmq_instance_crn == null && !var.use_ibm_owned_encryption_key && var.existing_kms_key_crn == null ? true : false # no need to create any KMS resources if passing an existing key, or using IBM owned keys - rabbitmq_key_name = var.prefix != null ? "${var.prefix}-${var.key_name}" : var.key_name - rabbitmq_key_ring_name = var.prefix != null ? "${var.prefix}-${var.key_ring_name}" : var.key_ring_name + prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : "" + create_new_kms_key = var.existing_rabbitmq_instance_crn == null && !var.use_ibm_owned_encryption_key && var.existing_kms_key_crn == null # no need to create any KMS resources if passing an existing key, or using IBM owned keys + rabbitmq_key_name = "${local.prefix}${var.key_name}" + rabbitmq_key_ring_name = "${local.prefix}${var.key_ring_name}" } module "kms" { @@ -92,16 +85,17 @@ data "ibm_iam_account_settings" "iam_account_settings" { locals { account_id = data.ibm_iam_account_settings.iam_account_settings.account_id - create_cross_account_kms_auth_policy = var.existing_rabbitmq_instance_crn == null && !var.skip_rabbitmq_kms_auth_policy && var.ibmcloud_kms_api_key != null && !var.use_ibm_owned_encryption_key - create_cross_account_backup_kms_auth_policy = var.existing_rabbitmq_instance_crn == null && !var.skip_rabbitmq_kms_auth_policy && var.ibmcloud_kms_api_key != null && !var.use_ibm_owned_encryption_key && var.existing_backup_kms_key_crn != null + use_kms_encryption = var.existing_rabbitmq_instance_crn == null && !var.use_ibm_owned_encryption_key + create_cross_account_kms_auth_policy = local.use_kms_encryption && !var.skip_rabbitmq_kms_auth_policy && var.ibmcloud_kms_api_key != null + create_cross_account_backup_kms_auth_policy = local.create_cross_account_kms_auth_policy && var.existing_backup_kms_key_crn != null # If KMS encryption enabled (and existing ES instance is not being passed), parse details from the existing key if being passed, otherwise get it from the key that the DA creates - kms_account_id = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id - kms_service = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name - kms_instance_guid = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance - kms_key_crn = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? var.existing_kms_key_crn : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].crn - kms_key_id = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].key_id - kms_region = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].region : module.kms_instance_crn_parser[0].region + kms_account_id = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id : null + kms_service = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name : null + kms_instance_guid = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance : null + kms_key_crn = local.use_kms_encryption ? var.existing_kms_key_crn != null ? var.existing_kms_key_crn : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].crn : null + kms_key_id = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].key_id : null + kms_region = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].region : module.kms_instance_crn_parser[0].region : null # If creating KMS cross account policy for backups, parse backup key details from passed in key CRN backup_kms_account_id = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].account_id : local.kms_account_id @@ -109,7 +103,7 @@ locals { backup_kms_instance_guid = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].service_instance : local.kms_instance_guid backup_kms_key_id = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].resource : local.kms_key_id - backup_kms_key_crn = var.existing_rabbitmq_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_backup_kms_key_crn + backup_kms_key_crn = local.use_kms_encryption ? var.existing_backup_kms_key_crn : null # Always use same key for backups unless user explicially passed a value for 'existing_backup_kms_key_crn' use_same_kms_key_for_backups = var.existing_backup_kms_key_crn == null ? true : false } @@ -275,12 +269,13 @@ data "ibm_database_connection" "existing_connection" { # Create new instance module "rabbitmq" { count = var.existing_rabbitmq_instance_crn != null ? 0 : 1 - source = "../../modules/fscloud" + source = "../../" depends_on = [time_sleep.wait_for_authorization_policy, time_sleep.wait_for_backup_kms_authorization_policy] resource_group_id = module.resource_group.resource_group_id - name = var.prefix != null ? "${var.prefix}-${var.name}" : var.name + name = "${local.prefix}${var.name}" region = var.region rabbitmq_version = var.rabbitmq_version + service_endpoints = var.rabbitmq_service_endpoints skip_iam_authorization_policy = var.skip_rabbitmq_kms_auth_policy use_ibm_owned_encryption_key = var.use_ibm_owned_encryption_key kms_key_crn = local.kms_key_crn @@ -371,10 +366,10 @@ locals { # Build the structure of the arbitrary credential type secret for admin password admin_pass_secret = [{ - secret_group_name = (var.prefix != null && var.prefix != "") && var.admin_pass_secrets_manager_secret_group != null ? "${var.prefix}-${var.admin_pass_secrets_manager_secret_group}" : var.admin_pass_secrets_manager_secret_group + secret_group_name = "${local.prefix}${var.admin_pass_secrets_manager_secret_group}" existing_secret_group = var.use_existing_admin_pass_secrets_manager_secret_group secrets = [{ - secret_name = (var.prefix != null && var.prefix != "") && var.admin_pass_secrets_manager_secret_name != null ? "${var.prefix}-${var.admin_pass_secrets_manager_secret_name}" : var.admin_pass_secrets_manager_secret_name + secret_name = "${var.prefix}${var.admin_pass_secrets_manager_secret_name}" secret_type = "arbitrary" secret_payload_password = local.admin_pass } diff --git a/solutions/standard/moved.tf b/solutions/fully-configurable/moved.tf similarity index 100% rename from solutions/standard/moved.tf rename to solutions/fully-configurable/moved.tf diff --git a/solutions/standard/outputs.tf b/solutions/fully-configurable/outputs.tf similarity index 100% rename from solutions/standard/outputs.tf rename to solutions/fully-configurable/outputs.tf diff --git a/solutions/standard/provider.tf b/solutions/fully-configurable/provider.tf similarity index 100% rename from solutions/standard/provider.tf rename to solutions/fully-configurable/provider.tf diff --git a/solutions/standard/variables.tf b/solutions/fully-configurable/variables.tf similarity index 93% rename from solutions/standard/variables.tf rename to solutions/fully-configurable/variables.tf index 7e6e492e..e6222412 100644 --- a/solutions/standard/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -7,21 +7,26 @@ variable "ibmcloud_api_key" { description = "The IBM Cloud API key to deploy resources." sensitive = true } -variable "use_existing_resource_group" { - type = bool - description = "Whether to use an existing resource group." - default = false -} -variable "resource_group_name" { +variable "existing_resource_group_name" { type = string - description = "The name of a new or an existing resource group to provision the Databases for RabbitMQ in. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + description = "The name of an existing resource group to provision the Databases for RabbitMQ in." + default = "Default" } variable "prefix" { type = string - description = "Prefix to add to all resources created by this solution." - default = null + description = "The prefix to add to all resources that this solution creates. Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters. It also cannot have a `--`. To not use any prefix value, you can set this value to `null` or an empty string." + nullable = true + validation { + condition = (var.prefix == null ? true : + alltrue([ + can(regex("^[a-z]{0,1}[-a-z0-9]{0,14}[a-z0-9]{0,1}$", var.prefix)), + length(regexall("^.*--.*", var.prefix)) == 0 + ]) + ) + error_message = "Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." + } } variable "name" { @@ -53,6 +58,17 @@ variable "existing_rabbitmq_instance_crn" { description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." } +variable "rabbitmq_service_endpoints" { + type = string + description = "Specify whether you want to enable the public, private, or both service endpoints. Supported values are 'public', 'private', or 'public-and-private'." + default = "private" + + validation { + condition = can(regex("public|public-and-private|private", var.rabbitmq_service_endpoints)) + error_message = "Valid values for rabbitmq_service_endpoints are 'public', 'public-and-private', and 'private'" + } +} + ############################################################################## # ICD hosting model properties ############################################################################## diff --git a/solutions/standard/version.tf b/solutions/fully-configurable/version.tf similarity index 100% rename from solutions/standard/version.tf rename to solutions/fully-configurable/version.tf From 721c822117d3ac486d21406bad9f3d204fabf8ad Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Fri, 6 Jun 2025 11:50:20 -0400 Subject: [PATCH 02/11] feat: security enforced da --- .catalog-onboard-pipeline.yaml | 6 + ibm_catalog.json | 244 ++++++++++++- solutions/security-enforced/README.md | 13 + .../catalogValidationValues.json.template | 7 + solutions/security-enforced/main.tf | 42 +++ solutions/security-enforced/moved.tf | 4 + solutions/security-enforced/outputs.tf | 56 +++ solutions/security-enforced/variables.tf | 340 ++++++++++++++++++ solutions/security-enforced/version.tf | 5 + tests/other_test.go | 4 +- tests/pr_test.go | 139 +++++-- 11 files changed, 818 insertions(+), 42 deletions(-) create mode 100644 solutions/security-enforced/README.md create mode 100644 solutions/security-enforced/catalogValidationValues.json.template create mode 100644 solutions/security-enforced/main.tf create mode 100644 solutions/security-enforced/moved.tf create mode 100644 solutions/security-enforced/outputs.tf create mode 100644 solutions/security-enforced/variables.tf create mode 100644 solutions/security-enforced/version.tf diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index a356d7f0..b058c86a 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -12,3 +12,9 @@ offerings: scc: instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 region: us-south + - name: security-enforced + mark_ready: true + install_type: fullstack + scc: + instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 + region: us-south diff --git a/ibm_catalog.json b/ibm_catalog.json index d695ba83..907a245b 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -22,7 +22,7 @@ "in memory" ], "short_description": "Creates and configures an instance of IBM Cloud Databases for RabbitMQ.", - "long_description": "This architecture supports creating and configuring an instance of Databases for RabbitMQ with KMS encryption.", + "long_description": "This architecture supports creating and configuring an instance of Databases for RabbitMQ with KMS encryption. RabbitMQ routes messages between microservices for modern applications. Messages for RabbitMQ makes RabbitMQ even better by managing it for you. Features include high availability, automated backup orchestration, autoscaling, and de-coupled allocation of storage, RAM, and vCPUs. Messages for RabbitMQ pricing is based on underlying disk, RAM, and optional vCPU allocation, as well as backup storage usage. The service is HIPAA-Ready and compliant with PCI-DSS, SOC 1 Type 2, SOC 2 Type 2, ISO 27001, ISO 27017, ISO 27018, ISO 27701, and GDPR. You can also learn more by viewing docs, API docs, and terms.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/README.md", "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/main/images/rabbitmq_icon.svg", "provider_name": "IBM", @@ -338,6 +338,248 @@ "key": "existing_rabbitmq_instance_crn" } ] + }, + { + "label": "Security-Enforced", + "name": "security-enforced", + "install_type": "fullstack", + "working_directory": "solutions/security-enforced", + "compliance": { + "authority": "scc-v3", + "profiles": [ + { + "profile_name": "IBM Cloud Framework for Financial Services", + "profile_version": "1.7.0" + } + ] + }, + "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Administrator" + ], + "service_name": "all-account-management-services" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "messages-for-rabbitmq" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "kms" + } + ], + "architecture": { + "features": [ + { + "title": " Creates an instance of Databases for RabbitMQ", + "description": "This architecture creates an instance of IBM Cloud Messages for RabbitMQ with KMS encryption. It accepts a resource group, and provides autoscaling rules." + } + ], + "diagrams": [ + { + "diagram": { + "caption": "Messages for RabbitMQ instance on IBM Cloud", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/main/reference-architecture/deployable-architecture-rabbitmq.svg", + "type": "image/svg+xml" + }, + "description": "This architecture supports creating and configuring an instance of Messages for RabbitMQ instance with KMS encryption." + } + ] + }, + "configuration": [ + { + "key": "ibmcloud_api_key" + }, + { + "key": "existing_resource_group_name", + "required": true, + "custom_config": { + "type": "resource_group", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "identifier": "rg_name" + } + } + }, + { + "key": "prefix", + "required": true + }, + { + "key": "name" + }, + { + "key": "region", + "required": true, + "default_value": "us-south", + "options": [ + { + "displayname": "Chennai (che01)", + "value": "che01" + }, + { + "displayname": "Dallas (us-south)", + "value": "us-south" + }, + { + "displayname": "Frankfurt (eu-de)", + "value": "eu-de" + }, + { + "displayname": "London (eu-gb)", + "value": "eu-gb" + }, + { + "displayname": "Madrid (eu-es)", + "value": "eu-es" + }, + { + "displayname": "Osaka (jp-osa)", + "value": "jp-osa" + }, + { + "displayname": "Paris (par01)", + "value": "par01" + }, + { + "displayname": "Sao Paulo (br-sao)", + "value": "br-sao" + }, + { + "displayname": "Sydney (au-syd)", + "value": "au-syd" + }, + { + "displayname": "Toronto (ca-tor)", + "value": "ca-tor" + }, + { + "displayname": "Tokyo (jp-tok)", + "value": "jp-tok" + }, + { + "displayname": "Washington (us-east)", + "value": "us-east" + } + ] + }, + { + "key": "rabbitmq_version", + "required": true, + "options": [ + { + "displayname": "3.13", + "value": "3.13" + }, + { + "displayname": "4.0", + "value": "4.0" + } + ] + }, + { + "key": "members" + }, + { + "key": "member_memory_mb" + }, + { + "key": "member_cpu_count" + }, + { + "key": "member_disk_mb" + }, + { + "key": "member_host_flavor" + }, + { + "key": "service_credential_names" + }, + { + "key": "admin_pass" + }, + { + "key": "users" + }, + { + "key": "tags", + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "type": "string" + } + } + }, + { + "key": "access_tags", + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "type": "string" + } + } + }, + { + "key": "ibmcloud_kms_api_key" + }, + { + "key": "existing_kms_instance_crn" + }, + { + "key": "existing_kms_key_crn" + }, + { + "key": "key_ring_name" + }, + { + "key": "key_name" + }, + { + "key": "auto_scaling" + }, + { + "key": "existing_secrets_manager_instance_crn" + }, + { + "key": "service_credential_secrets" + }, + { + "key": "skip_rabbitmq_sm_auth_policy" + }, + { + "key": "skip_rabbitmq_kms_auth_policy" + }, + { + "key": "backup_crn" + }, + { + "key": "existing_backup_kms_key_crn" + }, + { + "key": "admin_pass_secrets_manager_secret_group" + }, + { + "key": "admin_pass_secrets_manager_secret_name" + }, + { + "key": "use_existing_admin_pass_secrets_manager_secret_group" + }, + { + "key": "cbr_rules" + }, + { + "key": "existing_rabbitmq_instance_crn" + } + ] } ] } diff --git a/solutions/security-enforced/README.md b/solutions/security-enforced/README.md new file mode 100644 index 00000000..04b4a86a --- /dev/null +++ b/solutions/security-enforced/README.md @@ -0,0 +1,13 @@ + # IBM Cloud Databases for RabbitMQ + +This architecture creates an instance of IBM Cloud Databases for RabbitMQ and supports provisioning of the following resources: + +- A resource group, if one is not passed in. +- A KMS root key, if one is not passed in. +- An IBM Cloud Databases for RabbitMQ instance with KMS encryption. +- Autoscaling rules for the database instance, if provided. +- Service credential secrets and store them in secret manager. + +![fscloud-rabbitmq](../../reference-architecture/deployable-architecture-rabbitmq.svg) + +:exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). diff --git a/solutions/security-enforced/catalogValidationValues.json.template b/solutions/security-enforced/catalogValidationValues.json.template new file mode 100644 index 00000000..3576f866 --- /dev/null +++ b/solutions/security-enforced/catalogValidationValues.json.template @@ -0,0 +1,7 @@ +{ + "ibmcloud_api_key": $VALIDATION_APIKEY, + "region": "us-south", + "tags": $TAGS, + "name": $PREFIX, + "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN +} diff --git a/solutions/security-enforced/main.tf b/solutions/security-enforced/main.tf new file mode 100644 index 00000000..a7cea4ed --- /dev/null +++ b/solutions/security-enforced/main.tf @@ -0,0 +1,42 @@ +module "icd_rabbitmq" { + source = "../fully-configurable" + prefix = var.prefix + ibmcloud_api_key = var.ibmcloud_api_key + existing_resource_group_name = var.existing_resource_group_name + name = var.name + region = var.region + rabbitmq_version = var.rabbitmq_version + existing_rabbitmq_instance_crn = var.existing_rabbitmq_instance_crn + rabbitmq_service_endpoints = "private" + members = var.members + member_memory_mb = var.member_memory_mb + member_cpu_count = var.member_cpu_count + member_disk_mb = var.member_disk_mb + member_host_flavor = var.member_host_flavor + service_credential_names = var.service_credential_names + admin_pass = var.admin_pass + users = var.users + tags = var.tags + access_tags = var.access_tags + use_ibm_owned_encryption_key = false + existing_kms_instance_crn = var.existing_kms_instance_crn + existing_kms_key_crn = var.existing_kms_key_crn + kms_endpoint_type = "private" + skip_rabbitmq_kms_auth_policy = var.skip_rabbitmq_kms_auth_policy + ibmcloud_kms_api_key = var.ibmcloud_kms_api_key + key_ring_name = var.key_ring_name + key_name = var.key_name + existing_backup_kms_key_crn = var.existing_backup_kms_key_crn + use_default_backup_encryption_key = "false" + backup_crn = var.backup_crn + provider_visibility = "private" + auto_scaling = var.auto_scaling + existing_secrets_manager_instance_crn = var.existing_secrets_manager_instance_crn + existing_secrets_manager_endpoint_type = "private" + service_credential_secrets = var.service_credential_secrets + skip_rabbitmq_sm_auth_policy = var.skip_rabbitmq_sm_auth_policy + admin_pass_secrets_manager_secret_group = var.admin_pass_secrets_manager_secret_group + use_existing_admin_pass_secrets_manager_secret_group = var.use_existing_admin_pass_secrets_manager_secret_group + admin_pass_secrets_manager_secret_name = var.admin_pass_secrets_manager_secret_name + cbr_rules = var.cbr_rules +} diff --git a/solutions/security-enforced/moved.tf b/solutions/security-enforced/moved.tf new file mode 100644 index 00000000..2c783c3c --- /dev/null +++ b/solutions/security-enforced/moved.tf @@ -0,0 +1,4 @@ +moved { + from = module.rabbitmq + to = module.rabbitmq[0] +} diff --git a/solutions/security-enforced/outputs.tf b/solutions/security-enforced/outputs.tf new file mode 100644 index 00000000..a2c7c8c0 --- /dev/null +++ b/solutions/security-enforced/outputs.tf @@ -0,0 +1,56 @@ +############################################################################## +# Outputs +############################################################################## + +output "id" { + description = "RabbitMQ instance id" + value = module.icd_rabbitmq.id +} + +output "version" { + description = "RabbitMQ instance version" + value = module.icd_rabbitmq.version +} + +output "guid" { + description = "RabbitMQ instance guid" + value = module.icd_rabbitmq.guid +} + +output "crn" { + description = "RabbitMQ instance crn" + value = module.icd_rabbitmq.crn +} + +output "service_credentials_json" { + description = "Service credentials json map" + value = module.icd_rabbitmq.service_credentials_json + sensitive = true +} + +output "service_credentials_object" { + description = "Service credentials object" + value = module.icd_rabbitmq.service_credentials_object + sensitive = true +} + +output "hostname" { + description = "Database connection hostname" + value = module.icd_rabbitmq.hostname +} + +output "port" { + description = "Database connection port" + value = module.icd_rabbitmq.port +} + +output "secrets_manager_secrets" { + description = "Service credential secrets" + value = module.icd_rabbitmq.secrets_manager_secrets +} + +output "admin_pass" { + description = "RabbitMQ administrator password" + value = module.icd_rabbitmq.admin_pass + sensitive = true +} diff --git a/solutions/security-enforced/variables.tf b/solutions/security-enforced/variables.tf new file mode 100644 index 00000000..02670ca4 --- /dev/null +++ b/solutions/security-enforced/variables.tf @@ -0,0 +1,340 @@ +############################################################################## +# Input Variables +############################################################################## + +variable "ibmcloud_api_key" { + type = string + description = "The IBM Cloud API key to deploy resources." + sensitive = true +} + +variable "existing_resource_group_name" { + type = string + description = "The name of an existing resource group to provision the Databases for RabbitMQ in." + default = "Default" +} + +variable "prefix" { + type = string + description = "The prefix to add to all resources that this solution creates. Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters. It also cannot have a `--`. To not use any prefix value, you can set this value to `null` or an empty string." + nullable = true + validation { + condition = (var.prefix == null ? true : + alltrue([ + can(regex("^[a-z]{0,1}[-a-z0-9]{0,14}[a-z0-9]{0,1}$", var.prefix)), + length(regexall("^.*--.*", var.prefix)) == 0 + ]) + ) + error_message = "Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." + } +} + +variable "name" { + type = string + description = "The name of the Databases for RabbitMQ instance. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + default = "rabbitmq" +} + +variable "region" { + description = "The region where you want to deploy your instance." + type = string + default = "us-south" +} + +variable "rabbitmq_version" { + description = "The version of the Databases for RabbitMQ instance. If no value is specified, the current preferred version of Databases for RabbitMQ is used." + type = string + default = null +} + +variable "existing_rabbitmq_instance_crn" { + type = string + default = null + description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." +} + +############################################################################## +# ICD hosting model properties +############################################################################## + +variable "members" { + type = number + description = "The number of members that are allocated. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." + default = 3 +} + +variable "member_memory_mb" { + type = number + description = "The memory per member that is allocated. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)" + default = 8192 +} + +variable "member_cpu_count" { + type = number + description = "The dedicated CPU per member that is allocated. For shared CPU, set to 0. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." + default = 0 +} + +variable "member_disk_mb" { + type = number + description = "The disk that is allocated per member. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." + default = 1024 +} + +variable "member_host_flavor" { + type = string + description = "The host flavor per member. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/database#host_flavor)." + default = "multitenant" +} + +variable "service_credential_names" { + description = "Map of name, role for service credentials that you want to create for the database. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/solutions/standard/DA-types.md#svc-credential-name)" + type = map(string) + default = {} +} + +variable "admin_pass" { + type = string + description = "The password for the database administrator. If the admin password is null then the admin user ID cannot be accessed. More users can be specified in a user block." + default = null + sensitive = true +} + +variable "users" { + type = list(object({ + name = string + password = string # pragma: allowlist secret + type = string # "type" is required to generate the connection string for the outputs. + role = optional(string) + })) + default = [] + sensitive = true + description = "A list of users that you want to create on the database. Users block is supported by RabbitMQ version >= 6.0. Multiple blocks are allowed. The user password must be in the range of 10-32 characters. Be warned that in most case using IAM service credentials (via the var.service_credential_names) is sufficient to control access to the RabbitMQ instance. This blocks creates native RabbitMQ database users. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/solutions/standard/DA-types.md#users)" +} + +variable "tags" { + type = list(any) + description = "The list of tags to be added to the Databases for RabbitMQ instance." + default = [] +} + +variable "access_tags" { + type = list(string) + description = "A list of access tags to apply to the Databases for RabbitMQ instance created by the solution. [Learn more](https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial)." + default = [] +} + +############################################################## +# Encryption +############################################################## + +variable "existing_kms_instance_crn" { + type = string + description = "The CRN of a Key Protect or Hyper Protect Crypto Services instance. Required to create a new encryption key and key ring which will be used to encrypt both deployment data and backups. To use an existing key, pass values for `existing_kms_key_crn` and/or `existing_backup_kms_key_crn`. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." + default = null + + validation { + condition = anytrue([var.existing_kms_instance_crn == null, var.existing_kms_key_crn == null]) + error_message = "Either an existing_kms_instance_crn or an existing_kms_key_crn needs to be provided." + } +} + +variable "existing_kms_key_crn" { + type = string + description = "The CRN of a Key Protect or Hyper Protect Crypto Services encryption key to encrypt your data. By default this key is used for both deployment data and backups, but this behaviour can be altered using the optional `existing_backup_kms_key_crn` input. If no value is passed a new key will be created in the instance specified in the `existing_kms_instance_crn` input. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." + default = null +} + +variable "skip_rabbitmq_kms_auth_policy" { + type = bool + description = "Whether to create an IAM authorization policy that permits all Databases for RabbitMQ instances in the resource group to read the encryption key from the Hyper Protect Crypto Services instance specified in the `existing_kms_instance_crn` variable." + default = false +} + +variable "ibmcloud_kms_api_key" { + type = string + description = "The IBM Cloud API key that can create a root key and key ring in the key management service (KMS) instance. If not specified, the 'ibmcloud_api_key' variable is used. Specify this key if the instance in `existing_kms_instance_crn` is in an account that's different from the RabbitMQ instance. Leave this input empty if the same account owns both instances." + sensitive = true + default = null +} + +variable "key_ring_name" { + type = string + default = "rabbitmq-key-ring" + description = "The name for the key ring created for the Databases for RabbitMQ key. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format." +} + +variable "key_name" { + type = string + default = "rabbitmq-key" + description = "The name for the key created for the Databases for RabbitMQ key. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format." +} + +variable "existing_backup_kms_key_crn" { + type = string + description = "The CRN of a Key Protect or Hyper Protect Crypto Services encryption key that you want to use for encrypting the disk that holds deployment backups. Applies only if `use_ibm_owned_encryption_key` is false. If no value is passed, the value of `existing_kms_key_crn` is used. If no value is passed for `existing_kms_key_crn`, a new key will be created in the instance specified in the `existing_kms_instance_crn` input. Alternatively set `use_default_backup_encryption_key` to true to use the IBM Cloud Databases default encryption. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." + default = null +} + +variable "backup_crn" { + type = string + description = "The CRN of a backup resource to restore from. The backup is created by a database deployment with the same service ID. The backup is loaded after provisioning and the new deployment starts up that uses that data. A backup CRN is in the format crn:v1:<…>:backup:. If omitted, the database is provisioned empty." + default = null + + validation { + condition = anytrue([ + var.backup_crn == null, + can(regex("^crn:.*:backup:", var.backup_crn)) + ]) + error_message = "backup_crn must be null OR starts with 'crn:' and contains ':backup:'" + } +} + +############################################################## +# Auto Scaling +############################################################## + +variable "auto_scaling" { + type = object({ + disk = object({ + capacity_enabled = optional(bool, false) + free_space_less_than_percent = optional(number, 10) + io_above_percent = optional(number, 90) + io_enabled = optional(bool, false) + io_over_period = optional(string, "15m") + rate_increase_percent = optional(number, 10) + rate_limit_mb_per_member = optional(number, 3670016) + rate_period_seconds = optional(number, 900) + rate_units = optional(string, "mb") + }) + memory = object({ + io_above_percent = optional(number, 90) + io_enabled = optional(bool, false) + io_over_period = optional(string, "15m") + rate_increase_percent = optional(number, 10) + rate_limit_mb_per_member = optional(number, 114688) + rate_period_seconds = optional(number, 900) + rate_units = optional(string, "mb") + }) + }) + description = "Optional rules to allow the database to increase resources in response to usage. Only a single autoscaling block is allowed. Make sure you understand the effects of autoscaling, especially for production environments. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/solutions/standard/DA-types.md#autoscaling)" + default = null +} + +############################################################################## +## Secrets Manager Service Credentials +############################################################################## + +variable "existing_secrets_manager_instance_crn" { + type = string + default = null + description = "The CRN of existing secrets manager to use to create service credential secrets for Databases for RabbitMQ instance." +} + +variable "service_credential_secrets" { + type = list(object({ + secret_group_name = string + secret_group_description = optional(string) + existing_secret_group = optional(bool) + service_credentials = list(object({ + secret_name = string + service_credentials_source_service_role_crn = string + secret_labels = optional(list(string)) + secret_auto_rotation = optional(bool) + secret_auto_rotation_unit = optional(string) + secret_auto_rotation_interval = optional(number) + service_credentials_ttl = optional(string) + service_credential_secret_description = optional(string) + + })) + })) + default = [] + description = "Service credential secrets configuration for Databases for RabbitMQ. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/tree/main/solutions/standard/DA-types.md#service-credential-secrets)." + + validation { + # Service roles CRNs can be found at https://cloud.ibm.com/iam/roles, select the IBM Cloud Database and select the role + condition = alltrue([ + for group in var.service_credential_secrets : alltrue([ + # crn:v?:bluemix; two non-empty segments; three possibly empty segments; :serviceRole or role: non-empty segment + for credential in group.service_credentials : can(regex("^crn:v[0-9]:bluemix(:..*){2}(:.*){3}:(serviceRole|role):..*$", credential.service_credentials_source_service_role_crn)) + ]) + ]) + error_message = "service_credentials_source_service_role_crn must be a serviceRole CRN. See https://cloud.ibm.com/iam/roles" + } + + validation { + condition = ( + length(var.service_credential_secrets) == 0 || + var.existing_secrets_manager_instance_crn != null + ) + error_message = "`existing_secrets_manager_instance_crn` is required when adding service credentials to a secrets manager secret." + } +} + +variable "skip_rabbitmq_sm_auth_policy" { + type = bool + description = "Whether an IAM authorization policy is created for Secrets Manager instance to create a service credential secrets for Databases for RabbitMQ. If set to false, the Secrets Manager instance passed by the user is granted the Key Manager access to the RabbitMQ instance created by the Deployable Architecture. Set to `true` to use an existing policy. The value of this is ignored if any value for 'existing_secrets_manager_instance_crn' is not passed." + default = false +} + +variable "admin_pass_secrets_manager_secret_group" { + type = string + description = "The name of a new or existing secrets manager secret group for admin password. To use existing secret group, `use_existing_admin_pass_secrets_manager_secret_group` must be set to `true`. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + default = "rabbitmq-secrets" + + validation { + condition = ( + var.existing_secrets_manager_instance_crn == null || + var.admin_pass_secrets_manager_secret_group != null + ) + error_message = "`admin_pass_secrets_manager_secret_group` is required when `existing_secrets_manager_instance_crn` is set." + } +} + +variable "use_existing_admin_pass_secrets_manager_secret_group" { + type = bool + description = "Whether to use an existing secrets manager secret group for admin password." + default = false +} + +variable "admin_pass_secrets_manager_secret_name" { + type = string + description = "The name of a new rabbitmq administrator secret. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + default = "rabbitmq-admin-password" + + validation { + condition = ( + var.existing_secrets_manager_instance_crn == null || + var.admin_pass_secrets_manager_secret_name != null + ) + error_message = "`admin_pass_secrets_manager_secret_name` is required when `existing_secrets_manager_instance_crn` is set." + } +} + +############################################################## +# Context-based restriction (CBR) +############################################################## + +variable "cbr_rules" { + type = 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 + })) + }))) + })) + description = "(Optional, list) List of context-based restrictions rules to create." + default = [] +} diff --git a/solutions/security-enforced/version.tf b/solutions/security-enforced/version.tf new file mode 100644 index 00000000..2d5c091d --- /dev/null +++ b/solutions/security-enforced/version.tf @@ -0,0 +1,5 @@ +terraform { + required_version = ">= 1.9.0" + # Lock DA into an exact provider version - renovate automation will keep it updated + required_providers {} +} diff --git a/tests/other_test.go b/tests/other_test.go index 778c1117..b063765c 100644 --- a/tests/other_test.go +++ b/tests/other_test.go @@ -27,7 +27,7 @@ func TestRunCompleteExample(t *testing.T) { options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ Testing: t, TerraformDir: completeExampleTerraformDir, - Prefix: "rabbitmq-upg", + Prefix: "rmq-upg", BestRegionYAMLPath: regionSelectionPath, ResourceGroup: resourceGroup, TerraformVars: map[string]interface{}{ @@ -86,7 +86,7 @@ func TestRunRestoredDBExample(t *testing.T) { options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ Testing: t, TerraformDir: "examples/backup-restore", - Prefix: "rabbitmq-restored", + Prefix: "rmq-restored", ResourceGroup: resourceGroup, Region: fmt.Sprint(permanentResources["rabbitmqRegion"]), TerraformVars: map[string]interface{}{ diff --git a/tests/pr_test.go b/tests/pr_test.go index b3a1b3ae..f75d9244 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -24,9 +24,9 @@ import ( "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testschematic" ) -const standardSolutionTerraformDir = "solutions/standard" +const fullyConfigurableSolutionTerraformDir = "solutions/fully-configurable" +const securityEnforcedTerraformDir = "solutions/security-enforced" const completeExampleTerraformDir = "examples/complete" -const fscloudExampleTerraformDir = "examples/fscloud" const earliestVersion = "3.13" const latestVersion = "4.0" @@ -60,21 +60,19 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func TestRunStandardSolutionSchematics(t *testing.T) { +func TestRunFullyConfigurableSolutionSchematics(t *testing.T) { t.Parallel() options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ Testing: t, TarIncludePatterns: []string{ "*.tf", - fmt.Sprintf("%s/*.tf", standardSolutionTerraformDir), - fmt.Sprintf("%s/*.tf", fscloudExampleTerraformDir), - fmt.Sprintf("%s/*.tf", "modules/fscloud"), + fmt.Sprintf("%s/*.tf", fullyConfigurableSolutionTerraformDir), fmt.Sprintf("%s/*.sh", "scripts"), }, - TemplateFolder: standardSolutionTerraformDir, + TemplateFolder: fullyConfigurableSolutionTerraformDir, BestRegionYAMLPath: regionSelectionPath, - Prefix: "rabbitmq-st-da", + Prefix: "rbtmq-da", ResourceGroup: resourceGroup, DeleteWorkspaceOnFail: false, WaitJobCompleteMinutes: 60, @@ -109,40 +107,40 @@ func TestRunStandardSolutionSchematics(t *testing.T) { options.TerraformVars = []testschematic.TestSchematicTerraformVar{ {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "existing_kms_instance_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"}, {Name: "existing_backup_kms_key_crn", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, {Name: "kms_endpoint_type", Value: "private", DataType: "string"}, - {Name: "resource_group_name", Value: options.Prefix, DataType: "string"}, + {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "rabbitmq_version", Value: latestVersion, DataType: "string"}, // Always lock this test into the latest supported RabbitMQ version {Name: "service_credential_names", Value: string(serviceCredentialNamesJSON), DataType: "map(string)"}, {Name: "existing_secrets_manager_instance_crn", Value: permanentResources["secretsManagerCRN"], DataType: "string"}, {Name: "service_credential_secrets", Value: serviceCredentialSecrets, DataType: "list(object)"}, {Name: "admin_pass", Value: GetRandomAdminPassword(t), DataType: "string"}, - {Name: "admin_pass_secrets_manager_secret_group", Value: options.Prefix, DataType: "string"}, - {Name: "admin_pass_secrets_manager_secret_name", Value: options.Prefix, DataType: "string"}, } err = options.RunSchematicTest() assert.Nil(t, err, "This should not have errored") } -func TestRunStandardUpgradeSolution(t *testing.T) { +func TestRunFullyConfigurableUpgradeSolution(t *testing.T) { t.Parallel() options := testhelper.TestOptionsDefault(&testhelper.TestOptions{ Testing: t, - TerraformDir: standardSolutionTerraformDir, + TerraformDir: fullyConfigurableSolutionTerraformDir, BestRegionYAMLPath: regionSelectionPath, - Prefix: "rabbitmq-st-da-upg", + Prefix: "rmq-da-upg", ResourceGroup: resourceGroup, }) options.TerraformVars = map[string]any{ - "access_tags": permanentResources["accessTags"], - "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], - "kms_endpoint_type": "public", - "provider_visibility": "public", - "resource_group_name": options.Prefix, + "prefix": options.Prefix, + "access_tags": permanentResources["accessTags"], + "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], + "kms_endpoint_type": "public", + "provider_visibility": "public", + "existing_resource_group_name": resourceGroup, } output, err := options.RunTestUpgrade() @@ -152,11 +150,74 @@ func TestRunStandardUpgradeSolution(t *testing.T) { } } +func TestRunSecurityEnforcedSchematics(t *testing.T) { + t.Parallel() + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + TarIncludePatterns: []string{ + "*.tf", + fmt.Sprintf("%s/*.tf", fullyConfigurableSolutionTerraformDir), + fmt.Sprintf("%s/*.tf", securityEnforcedTerraformDir), + fmt.Sprintf("%s/*.sh", "scripts"), + }, + TemplateFolder: securityEnforcedTerraformDir, + BestRegionYAMLPath: regionSelectionPath, + Prefix: "rmq-sec", + ResourceGroup: resourceGroup, + DeleteWorkspaceOnFail: false, + WaitJobCompleteMinutes: 60, + }) + + serviceCredentialSecrets := []map[string]any{ + { + "secret_group_name": fmt.Sprintf("%s-secret-group", options.Prefix), + "service_credentials": []map[string]string{ + { + "secret_name": fmt.Sprintf("%s-cred-reader", options.Prefix), + "service_credentials_source_service_role_crn": "crn:v1:bluemix:public:iam::::role:Viewer", + }, + { + "secret_name": fmt.Sprintf("%s-cred-writer", options.Prefix), + "service_credentials_source_service_role_crn": "crn:v1:bluemix:public:iam::::role:Editor", + }, + }, + }, + } + + serviceCredentialNames := map[string]string{ + "admin": "Administrator", + "user1": "Viewer", + "user2": "Editor", + } + + serviceCredentialNamesJSON, err := json.Marshal(serviceCredentialNames) + if err != nil { + log.Fatalf("Error converting to JSON: %s", err) + } + + options.TerraformVars = []testschematic.TestSchematicTerraformVar{ + {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, + {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "existing_kms_instance_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"}, + {Name: "existing_backup_kms_key_crn", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, + {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, + {Name: "rabbitmq_version", Value: latestVersion, DataType: "string"}, // Always lock this test into the latest supported RabbitMQ version + {Name: "service_credential_names", Value: string(serviceCredentialNamesJSON), DataType: "map(string)"}, + {Name: "existing_secrets_manager_instance_crn", Value: permanentResources["secretsManagerCRN"], DataType: "string"}, + {Name: "service_credential_secrets", Value: serviceCredentialSecrets, DataType: "list(object)"}, + {Name: "admin_pass", Value: GetRandomAdminPassword(t), DataType: "string"}, + } + err = options.RunSchematicTest() + assert.Nil(t, err, "This should not have errored") +} + func TestPlanValidation(t *testing.T) { options := testhelper.TestOptionsDefault(&testhelper.TestOptions{ Testing: t, - TerraformDir: standardSolutionTerraformDir, - Prefix: "validate-plan", + TerraformDir: fullyConfigurableSolutionTerraformDir, + Prefix: "val-plan", ResourceGroup: resourceGroup, Region: "us-south", // skip VPC region picker }) @@ -164,28 +225,29 @@ func TestPlanValidation(t *testing.T) { options.TerraformOptions.NoColor = true options.TerraformOptions.Logger = logger.Discard options.TerraformOptions.Vars = map[string]any{ - "prefix": options.Prefix, - "region": "us-south", - "rabbitmq_version": earliestVersion, - "provider_visibility": "public", - "resource_group_name": options.Prefix, + "prefix": options.Prefix, + "region": "us-south", + "rabbitmq_version": earliestVersion, + "provider_visibility": "public", + "existing_resource_group_name": resourceGroup, } // Test the DA when using an existing KMS instance - var standardSolutionWithExistingKms = map[string]any{ - "access_tags": permanentResources["accessTags"], - "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], + var fullyConfigurableSolutionWithExistingKms = map[string]any{ + "access_tags": permanentResources["accessTags"], + "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], + "use_ibm_owned_encryption_key": false, } // Test the DA when using IBM owned encryption key - var standardSolutionWithUseIbmOwnedEncKey = map[string]any{ + var fullyConfigurableWithUseIbmOwnedEncKey = map[string]any{ "use_ibm_owned_encryption_key": true, } // Create a map of the variables tfVarsMap := map[string]map[string]any{ - "standardSolutionWithExistingKms": standardSolutionWithExistingKms, - "standardSolutionWithUseIbmOwnedEncKey": standardSolutionWithUseIbmOwnedEncKey, + "fullyConfigurableSolutionWithExistingKms": fullyConfigurableSolutionWithExistingKms, + "fullyConfigurableWithUseIbmOwnedEncKey": fullyConfigurableWithUseIbmOwnedEncKey, //pragma: allowlist secret } _, initErr := terraform.InitE(t, options.TerraformOptions) @@ -233,6 +295,7 @@ func TestRunExistingInstance(t *testing.T) { Vars: map[string]any{ "prefix": prefix, "region": region, + "resource_group": resourceGroup, "rabbitmq_version": latestVersion, "service_endpoints": "public-and-private", }, @@ -251,14 +314,12 @@ func TestRunExistingInstance(t *testing.T) { Testing: t, TarIncludePatterns: []string{ "*.tf", - fmt.Sprintf("%s/*.tf", standardSolutionTerraformDir), - fmt.Sprintf("%s/*.tf", fscloudExampleTerraformDir), - fmt.Sprintf("%s/*.tf", "modules/fscloud"), + fmt.Sprintf("%s/*.tf", fullyConfigurableSolutionTerraformDir), fmt.Sprintf("%s/*.sh", "scripts"), }, - TemplateFolder: standardSolutionTerraformDir, + TemplateFolder: fullyConfigurableSolutionTerraformDir, BestRegionYAMLPath: regionSelectionPath, - Prefix: "rabbitmq-da", + Prefix: "rmq-da-ex", ResourceGroup: resourceGroup, DeleteWorkspaceOnFail: false, WaitJobCompleteMinutes: 60, @@ -266,10 +327,10 @@ func TestRunExistingInstance(t *testing.T) { options.TerraformVars = []testschematic.TestSchematicTerraformVar{ {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, {Name: "existing_rabbitmq_instance_crn", Value: terraform.Output(t, existingTerraformOptions, "rabbitmq_crn"), DataType: "string"}, - {Name: "resource_group_name", Value: fmt.Sprintf("%s-resource-group", prefix), DataType: "string"}, + {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "region", Value: region, DataType: "string"}, - {Name: "use_existing_resource_group", Value: true, DataType: "bool"}, {Name: "provider_visibility", Value: "public", DataType: "string"}, } err := options.RunSchematicTest() From 209aafcaba734d6683a81d2a46c0953553a3b203 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Fri, 6 Jun 2025 12:08:53 -0400 Subject: [PATCH 03/11] fix: update cra-config --- cra-config.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cra-config.yaml b/cra-config.yaml index fbae9039..8a801ae2 100644 --- a/cra-config.yaml +++ b/cra-config.yaml @@ -1,12 +1,13 @@ # More info about this file at https://github.com/terraform-ibm-modules/common-pipeline-assets/blob/main/.github/workflows/terraform-test-pipeline.md#cra-config-yaml version: "v1" CRA_TARGETS: - - CRA_TARGET: "solutions/standard" + - CRA_TARGET: "solutions/fully-configurable" CRA_IGNORE_RULES_FILE: "cra-tf-validate-ignore-rules.json" PROFILE_ID: "fe96bd4d-9b37-40f2-b39f-a62760e326a3" # SCC profile ID (currently set to 'IBM Cloud Framework for Financial Services' '1.7.0' profile). CRA_ENVIRONMENT_VARIABLES: TF_VAR_existing_kms_instance_crn: "crn:v1:bluemix:public:hs-crypto:us-south:a/abac0df06b644a9cabc6e44f55b3880e:e6dce284-e80f-46e1-a3c1-830f7adff7a9::" TF_VAR_existing_kms_key_crn: "crn:v1:bluemix:public:hs-crypto:us-south:a/abac0df06b644a9cabc6e44f55b3880e:e6dce284-e80f-46e1-a3c1-830f7adff7a9:key:1368d2eb-3ed0-4a8b-b09c-2155895f01ea" - TF_VAR_use_existing_resource_group: true - TF_VAR_resource_group_name: "geretain-test-redis" + TF_VAR_existing_resource_group_name: "geretain-test-rabbitmq" TF_VAR_provider_visibility: "public" + TF_VAR_use_ibm_owned_encryption_key: false + TF_VAR_prefix: "test" From 887c75069fe48e90f628238d44f3166542162d2e Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Fri, 6 Jun 2025 13:25:31 -0400 Subject: [PATCH 04/11] fix: update vars for fully config schematics test --- tests/pr_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/pr_test.go b/tests/pr_test.go index f75d9244..3ef26fe5 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -110,7 +110,6 @@ func TestRunFullyConfigurableSolutionSchematics(t *testing.T) { {Name: "prefix", Value: options.Prefix, DataType: "string"}, {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "existing_kms_instance_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"}, - {Name: "existing_backup_kms_key_crn", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, {Name: "kms_endpoint_type", Value: "private", DataType: "string"}, {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "rabbitmq_version", Value: latestVersion, DataType: "string"}, // Always lock this test into the latest supported RabbitMQ version From ae12f6dff9fc66f335204f439a5a2fe12e37b19f Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Fri, 27 Jun 2025 10:13:18 -0400 Subject: [PATCH 05/11] refactor: sync with redis --- ibm_catalog.json | 219 ++++++++++++---------- solutions/fully-configurable/README.md | 12 +- solutions/fully-configurable/main.tf | 42 +++-- solutions/fully-configurable/provider.tf | 17 +- solutions/fully-configurable/variables.tf | 64 ++++--- solutions/security-enforced/README.md | 12 +- solutions/security-enforced/main.tf | 8 +- solutions/security-enforced/variables.tf | 24 ++- 8 files changed, 217 insertions(+), 181 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 4f159f3a..e45e99e2 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -29,26 +29,27 @@ "support_details": "This product is in the community registry, as such support is handled through the originated repo. If you experience issues please open an issue in the repository [https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/issues](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/issues). Please note this product is not supported via the IBM Cloud Support Center.", "features": [ { - "title": "Creates an instance of Databases for RabbitMQ", - "description": "Creates and configures an IBM Cloud Databases for RabbitMQ instance." - }, - { - "title": "Supports KMS encryption", + "title": "KMS encryption", "description": "Provides KMS encryption for the data that you store in the database." }, { - "title": "Supports autoscaling", + "title": "Autoscaling", "description": "Provides the autoscaling to allow the database to increase resources in response to usage." }, { - "title": "Supports backup restoration", + "title": "Backup restoration", "description": "Provides database restoration using a backup created by a deployment with the same service ID." + }, + { + "title": "Access tags", + "description": "Attaches access tags to the RabbitMQ instance." } ], "flavors": [ { "label": "Fully Configurable", "name": "fully-configurable", + "index": 1, "install_type": "fullstack", "working_directory": "solutions/fully-configurable", "compliance": { @@ -105,6 +106,7 @@ }, { "key": "provider_visibility", + "hidden": true, "options": [ { "displayname": "private", @@ -122,6 +124,7 @@ }, { "key": "existing_resource_group_name", + "display_name": "resource_group", "required": true, "custom_config": { "type": "resource_group", @@ -136,9 +139,6 @@ "key": "prefix", "required": true }, - { - "key": "name" - }, { "key": "region", "required": true, @@ -209,7 +209,27 @@ ] }, { - "key": "rabbitmq_service_endpoints" + "key": "name" + }, + { + "key": "tags", + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "type": "string" + } + } + }, + { + "key": "access_tags", + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "type": "string" + } + } }, { "key": "members" @@ -227,48 +247,31 @@ "key": "member_host_flavor" }, { - "key": "service_credential_names" + "key": "auto_scaling" }, { - "key": "admin_pass" + "key": "service_endpoints" }, { - "key": "users" + "key": "service_credential_names" }, { - "key": "tags", + "key": "service_credential_secrets", + "type": "array", "custom_config": { + "type": "textarea", "grouping": "deployment", - "original_grouping": "deployment", - "config_constraints": { - "type": "string" - } + "original_grouping": "deployment" } }, { - "key": "access_tags", - "custom_config": { - "grouping": "deployment", - "original_grouping": "deployment", - "config_constraints": { - "type": "string" - } - } - }, - { - "key": "use_ibm_owned_encryption_key" - }, - { - "key": "ibmcloud_kms_api_key" - }, - { - "key": "existing_kms_instance_crn" + "key": "admin_pass" }, { - "key": "existing_kms_key_crn" + "key": "existing_secrets_manager_instance_crn" }, { - "key": "kms_endpoint_type", + "key": "existing_secrets_manager_endpoint_type", "options": [ { "displayname": "public", @@ -281,19 +284,40 @@ ] }, { - "key": "key_ring_name" + "key": "skip_rabbitmq_secrets_manager_auth_policy" }, { - "key": "key_name" + "key": "admin_pass_secrets_manager_secret_group" }, { - "key": "auto_scaling" + "key": "admin_pass_secrets_manager_secret_name" }, { - "key": "existing_secrets_manager_instance_crn" + "key": "use_existing_admin_pass_secrets_manager_secret_group" }, { - "key": "existing_secrets_manager_endpoint_type", + "key": "users", + "type": "array", + "custom_config": { + "type": "textarea", + "grouping": "deployment", + "original_grouping": "deployment" + } + }, + { + "key": "ibmcloud_kms_api_key" + }, + { + "key": "kms_encryption_enabled" + }, + { + "key": "existing_kms_instance_crn" + }, + { + "key": "existing_kms_key_crn" + }, + { + "key": "kms_endpoint_type", "options": [ { "displayname": "public", @@ -306,13 +330,10 @@ ] }, { - "key": "service_credential_secrets" - }, - { - "key": "skip_rabbitmq_sm_auth_policy" + "key": "key_ring_name" }, { - "key": "skip_rabbitmq_kms_auth_policy" + "key": "key_name" }, { "key": "backup_crn" @@ -324,13 +345,7 @@ "key": "use_default_backup_encryption_key" }, { - "key": "admin_pass_secrets_manager_secret_group" - }, - { - "key": "admin_pass_secrets_manager_secret_name" - }, - { - "key": "use_existing_admin_pass_secrets_manager_secret_group" + "key": "skip_rabbitmq_kms_auth_policy" }, { "key": "cbr_rules" @@ -343,6 +358,7 @@ { "label": "Security-Enforced", "name": "security-enforced", + "index": 2, "install_type": "fullstack", "working_directory": "solutions/security-enforced", "compliance": { @@ -378,8 +394,8 @@ "architecture": { "features": [ { - "title": " Creates an instance of Databases for RabbitMQ", - "description": "This architecture creates an instance of IBM Cloud Messages for RabbitMQ with KMS encryption. It accepts a resource group, and provides autoscaling rules." + "title": " ", + "description": "Configured to use IBM secure by default standards that can't be changed." } ], "diagrams": [ @@ -413,9 +429,6 @@ "key": "prefix", "required": true }, - { - "key": "name" - }, { "key": "region", "required": true, @@ -486,28 +499,7 @@ ] }, { - "key": "members" - }, - { - "key": "member_memory_mb" - }, - { - "key": "member_cpu_count" - }, - { - "key": "member_disk_mb" - }, - { - "key": "member_host_flavor" - }, - { - "key": "service_credential_names" - }, - { - "key": "admin_pass" - }, - { - "key": "users" + "key": "name" }, { "key": "tags", @@ -530,40 +522,43 @@ } }, { - "key": "ibmcloud_kms_api_key" + "key": "members" }, { - "key": "existing_kms_instance_crn" + "key": "member_memory_mb" }, { - "key": "existing_kms_key_crn" + "key": "member_cpu_count" }, { - "key": "key_ring_name" + "key": "member_disk_mb" }, { - "key": "key_name" + "key": "member_host_flavor" }, { "key": "auto_scaling" }, { - "key": "existing_secrets_manager_instance_crn" - }, - { - "key": "service_credential_secrets" + "key": "service_credential_names" }, { - "key": "skip_rabbitmq_sm_auth_policy" + "key": "service_credential_secrets", + "type": "array", + "custom_config": { + "type": "textarea", + "grouping": "deployment", + "original_grouping": "deployment" + } }, { - "key": "skip_rabbitmq_kms_auth_policy" + "key": "admin_pass" }, { - "key": "backup_crn" + "key": "existing_secrets_manager_instance_crn" }, { - "key": "existing_backup_kms_key_crn" + "key": "skip_rabbitmq_secrets_manager_auth_policy" }, { "key": "admin_pass_secrets_manager_secret_group" @@ -574,6 +569,40 @@ { "key": "use_existing_admin_pass_secrets_manager_secret_group" }, + { + "key": "users", + "type": "array", + "custom_config": { + "type": "textarea", + "grouping": "deployment", + "original_grouping": "deployment" + } + }, + { + "key": "ibmcloud_kms_api_key" + }, + { + "key": "existing_kms_instance_crn", + "required": true + }, + { + "key": "existing_kms_key_crn" + }, + { + "key": "key_ring_name" + }, + { + "key": "key_name" + }, + { + "key": "backup_crn" + }, + { + "key": "existing_backup_kms_key_crn" + }, + { + "key": "skip_rabbitmq_kms_auth_policy" + }, { "key": "cbr_rules" }, diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 04b4a86a..d5f5803d 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -1,13 +1,3 @@ - # IBM Cloud Databases for RabbitMQ - -This architecture creates an instance of IBM Cloud Databases for RabbitMQ and supports provisioning of the following resources: - -- A resource group, if one is not passed in. -- A KMS root key, if one is not passed in. -- An IBM Cloud Databases for RabbitMQ instance with KMS encryption. -- Autoscaling rules for the database instance, if provided. -- Service credential secrets and store them in secret manager. - -![fscloud-rabbitmq](../../reference-architecture/deployable-architecture-rabbitmq.svg) +# Cloud automation for RabbitMQ (Fully configurable) :exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index dc47d296..b657160f 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -1,6 +1,10 @@ ####################################################################################################################### # Resource Group ####################################################################################################################### +locals { + prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : "" +} + module "resource_group" { source = "terraform-ibm-modules/resource-group/ibm" @@ -13,8 +17,12 @@ module "resource_group" { ####################################################################################################################### locals { - prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : "" - create_new_kms_key = var.existing_rabbitmq_instance_crn == null && !var.use_ibm_owned_encryption_key && var.existing_kms_key_crn == null # no need to create any KMS resources if passing an existing key, or using IBM owned keys + use_ibm_owned_encryption_key = !var.kms_encryption_enabled + create_new_kms_key = ( + var.kms_encryption_enabled && + var.existing_rabbitmq_instance_crn == null && + var.existing_kms_key_crn == null + ) rabbitmq_key_name = "${local.prefix}${var.key_name}" rabbitmq_key_ring_name = "${local.prefix}${var.key_ring_name}" } @@ -85,25 +93,23 @@ data "ibm_iam_account_settings" "iam_account_settings" { locals { account_id = data.ibm_iam_account_settings.iam_account_settings.account_id - use_kms_encryption = var.existing_rabbitmq_instance_crn == null && !var.use_ibm_owned_encryption_key - create_cross_account_kms_auth_policy = local.use_kms_encryption && !var.skip_rabbitmq_kms_auth_policy && var.ibmcloud_kms_api_key != null - create_cross_account_backup_kms_auth_policy = local.create_cross_account_kms_auth_policy && var.existing_backup_kms_key_crn != null + create_cross_account_kms_auth_policy = var.kms_encryption_enabled && !var.skip_rabbitmq_kms_auth_policy && var.ibmcloud_kms_api_key != null + create_cross_account_backup_kms_auth_policy = var.kms_encryption_enabled && !var.skip_rabbitmq_kms_auth_policy && var.ibmcloud_kms_api_key != null && var.existing_backup_kms_key_crn != null # If KMS encryption enabled (and existing ES instance is not being passed), parse details from the existing key if being passed, otherwise get it from the key that the DA creates - kms_account_id = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id : null - kms_service = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name : null - kms_instance_guid = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance : null - kms_key_crn = local.use_kms_encryption ? var.existing_kms_key_crn != null ? var.existing_kms_key_crn : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].crn : null - kms_key_id = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].key_id : null - kms_region = local.use_kms_encryption ? var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].region : module.kms_instance_crn_parser[0].region : null + kms_account_id = !var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id + kms_service = !var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name + kms_instance_guid = !var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance + kms_key_crn = !var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null ? null : var.existing_kms_key_crn != null ? var.existing_kms_key_crn : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].crn + kms_key_id = !var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms[0].keys[format("%s.%s", local.rabbitmq_key_ring_name, local.rabbitmq_key_name)].key_id + kms_region = !var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].region : module.kms_instance_crn_parser[0].region # If creating KMS cross account policy for backups, parse backup key details from passed in key CRN backup_kms_account_id = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].account_id : local.kms_account_id backup_kms_service = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].service_name : local.kms_service backup_kms_instance_guid = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].service_instance : local.kms_instance_guid backup_kms_key_id = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].resource : local.kms_key_id - - backup_kms_key_crn = local.use_kms_encryption ? var.existing_backup_kms_key_crn : null + backup_kms_key_crn = var.existing_rabbitmq_instance_crn != null || local.use_ibm_owned_encryption_key ? null : var.existing_backup_kms_key_crn # Always use same key for backups unless user explicially passed a value for 'existing_backup_kms_key_crn' use_same_kms_key_for_backups = var.existing_backup_kms_key_crn == null ? true : false } @@ -221,7 +227,9 @@ locals { # if - replace first char with J # elseif _ replace first char with K # else use asis - admin_pass = var.admin_pass == null ? (startswith(random_password.admin_password[0].result, "-") ? "J${substr(random_password.admin_password[0].result, 1, -1)}" : startswith(random_password.admin_password[0].result, "_") ? "K${substr(random_password.admin_password[0].result, 1, -1)}" : random_password.admin_password[0].result) : var.admin_pass + generated_admin_password = (length(random_password.admin_password) > 0 ? (startswith(random_password.admin_password[0].result, "-") ? "J${substr(random_password.admin_password[0].result, 1, -1)}" : startswith(random_password.admin_password[0].result, "_") ? "K${substr(random_password.admin_password[0].result, 1, -1)}" : random_password.admin_password[0].result) : null) + # admin password to use + admin_pass = var.admin_pass == null ? local.generated_admin_password : var.admin_pass } ####################################################################################################################### @@ -275,9 +283,9 @@ module "rabbitmq" { name = "${local.prefix}${var.name}" region = var.region rabbitmq_version = var.rabbitmq_version - service_endpoints = var.rabbitmq_service_endpoints + service_endpoints = var.service_endpoints skip_iam_authorization_policy = var.skip_rabbitmq_kms_auth_policy - use_ibm_owned_encryption_key = var.use_ibm_owned_encryption_key + use_ibm_owned_encryption_key = local.use_ibm_owned_encryption_key kms_key_crn = local.kms_key_crn backup_encryption_key_crn = local.backup_kms_key_crn use_same_kms_key_for_backups = local.use_same_kms_key_for_backups @@ -312,7 +320,7 @@ locals { locals { ## Variable validation (approach based on https://github.com/hashicorp/terraform/issues/25609#issuecomment-1057614400) - create_sm_auth_policy = var.skip_rabbitmq_sm_auth_policy || var.existing_secrets_manager_instance_crn == null ? 0 : 1 + create_sm_auth_policy = var.skip_rabbitmq_secrets_manager_auth_policy || var.existing_secrets_manager_instance_crn == null ? 0 : 1 } # Parse the Secrets Manager CRN diff --git a/solutions/fully-configurable/provider.tf b/solutions/fully-configurable/provider.tf index 65c38f7d..e66dac2c 100644 --- a/solutions/fully-configurable/provider.tf +++ b/solutions/fully-configurable/provider.tf @@ -1,11 +1,14 @@ provider "ibm" { - ibmcloud_api_key = var.ibmcloud_api_key - region = var.region - visibility = var.provider_visibility + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region + visibility = var.provider_visibility + private_endpoint_type = (var.provider_visibility == "private" && var.region == "ca-mon") ? "vpe" : null } + provider "ibm" { - alias = "kms" - ibmcloud_api_key = var.ibmcloud_kms_api_key != null ? var.ibmcloud_kms_api_key : var.ibmcloud_api_key - region = local.kms_region - visibility = var.provider_visibility + alias = "kms" + ibmcloud_api_key = var.ibmcloud_kms_api_key != null ? var.ibmcloud_kms_api_key : var.ibmcloud_api_key + region = local.kms_region + visibility = var.provider_visibility + private_endpoint_type = (var.provider_visibility == "private" && var.region == "ca-mon") ? "vpe" : null } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index e6222412..7378befd 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -16,16 +16,28 @@ variable "existing_resource_group_name" { variable "prefix" { type = string - description = "The prefix to add to all resources that this solution creates. Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters. It also cannot have a `--`. To not use any prefix value, you can set this value to `null` or an empty string." nullable = true + description = "The prefix to be added to all resources created by this solution. To skip using a prefix, set this value to null or an empty string. The prefix must begin with a lowercase letter and may contain only lowercase letters, digits, and hyphens '-'. It should not exceed 16 characters, must not end with a hyphen('-'), and can not contain consecutive hyphens ('--'). Example: prod-0205-cos. [Learn more](https://terraform-ibm-modules.github.io/documentation/#/prefix.md)." + validation { - condition = (var.prefix == null ? true : + # - null and empty string is allowed + # - Must not contain consecutive hyphens (--): length(regexall("--", var.prefix)) == 0 + # - Starts with a lowercase letter: [a-z] + # - Contains only lowercase letters (a–z), digits (0–9), and hyphens (-) + # - Must not end with a hyphen (-): [a-z0-9] + condition = (var.prefix == null || var.prefix == "" ? true : alltrue([ - can(regex("^[a-z]{0,1}[-a-z0-9]{0,14}[a-z0-9]{0,1}$", var.prefix)), - length(regexall("^.*--.*", var.prefix)) == 0 + can(regex("^[a-z][-a-z0-9]*[a-z0-9]$", var.prefix)), + length(regexall("--", var.prefix)) == 0 ]) ) - error_message = "Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." + error_message = "Prefix must begin with a lowercase letter and may contain only lowercase letters, digits, and hyphens '-'. It must not end with a hyphen('-'), and cannot contain consecutive hyphens ('--')." + } + + validation { + # must not exceed 16 characters in length + condition = length(var.prefix) <= 16 + error_message = "Prefix must not exceed 16 characters." } } @@ -58,20 +70,21 @@ variable "existing_rabbitmq_instance_crn" { description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." } -variable "rabbitmq_service_endpoints" { +############################################################################## +# ICD hosting model properties +############################################################################## + +variable "service_endpoints" { type = string description = "Specify whether you want to enable the public, private, or both service endpoints. Supported values are 'public', 'private', or 'public-and-private'." default = "private" validation { - condition = can(regex("public|public-and-private|private", var.rabbitmq_service_endpoints)) - error_message = "Valid values for rabbitmq_service_endpoints are 'public', 'public-and-private', and 'private'" + condition = can(regex("public|public-and-private|private", var.service_endpoints)) + error_message = "Valid values for service_endpoints are 'public', 'public-and-private', and 'private'" } } -############################################################################## -# ICD hosting model properties -############################################################################## variable "members" { type = number @@ -144,33 +157,24 @@ variable "access_tags" { # Encryption ############################################################## -variable "use_ibm_owned_encryption_key" { +variable "kms_encryption_enabled" { type = bool - description = "IBM Cloud Databases will secure your deployment's data at rest automatically with an encryption key that IBM hold. Alternatively, you may select your own Key Management System instance and encryption key (Key Protect or Hyper Protect Crypto Services) by setting this to false. If setting to false, a value must be passed for `existing_kms_instance_crn` to create a new key, or `existing_kms_key_crn` and/or `existing_backup_kms_key_crn` to use an existing key." + description = "Set to true to enable KMS encryption using customer-managed keys. When enabled, you must provide a value for at least one of the following: existing_kms_instance_crn, existing_kms_key_crn, or existing_backup_kms_key_crn. If set to false, IBM-owned encryption is used (i.e., encryption keys managed and held by IBM)." default = false - # this validation ensures IBM-owned key is not used when KMS details are provided validation { - condition = ( + condition = (!var.kms_encryption_enabled || var.existing_rabbitmq_instance_crn != null || - !(var.use_ibm_owned_encryption_key && ( - var.existing_kms_instance_crn != null || - var.existing_kms_key_crn != null || - var.existing_backup_kms_key_crn != null - )) + var.existing_kms_instance_crn != null || + var.existing_kms_key_crn != null || + var.existing_backup_kms_key_crn != null ) - error_message = "When setting values for 'existing_kms_instance_crn', 'existing_kms_key_crn' or 'existing_backup_kms_key_crn', the 'use_ibm_owned_encryption_key' input must be set to false." + error_message = "When 'kms_encryption_enabled' is true, you must provide either 'existing_backup_kms_key_crn', 'existing_kms_instance_crn' (to create a new key) or 'existing_kms_key_crn' (to use an existing key)." } - # this validation ensures key info is provided when IBM-owned key is disabled and no RabbitMQ instance is given validation { - condition = !( - var.existing_rabbitmq_instance_crn == null && - var.use_ibm_owned_encryption_key == false && - var.existing_kms_instance_crn == null && - var.existing_kms_key_crn == null - ) - error_message = "When 'use_ibm_owned_encryption_key' is false, you must provide either 'existing_kms_instance_crn' (to create a new key) or 'existing_kms_key_crn' (to use an existing key)." + condition = (var.existing_kms_instance_crn == null && var.existing_kms_key_crn == null && var.existing_backup_kms_key_crn == null) || var.kms_encryption_enabled + error_message = "When either 'existing_kms_instance_crn', 'existing_kms_key_crn' or 'existing_backup_kms_key_crn' is set then 'kms_encryption_enabled' must be set to true." } } @@ -348,7 +352,7 @@ variable "service_credential_secrets" { } } -variable "skip_rabbitmq_sm_auth_policy" { +variable "skip_rabbitmq_secrets_manager_auth_policy" { type = bool description = "Whether an IAM authorization policy is created for Secrets Manager instance to create a service credential secrets for Databases for RabbitMQ. If set to false, the Secrets Manager instance passed by the user is granted the Key Manager access to the RabbitMQ instance created by the Deployable Architecture. Set to `true` to use an existing policy. The value of this is ignored if any value for 'existing_secrets_manager_instance_crn' is not passed." default = false diff --git a/solutions/security-enforced/README.md b/solutions/security-enforced/README.md index 04b4a86a..ebf814cd 100644 --- a/solutions/security-enforced/README.md +++ b/solutions/security-enforced/README.md @@ -1,13 +1,3 @@ - # IBM Cloud Databases for RabbitMQ - -This architecture creates an instance of IBM Cloud Databases for RabbitMQ and supports provisioning of the following resources: - -- A resource group, if one is not passed in. -- A KMS root key, if one is not passed in. -- An IBM Cloud Databases for RabbitMQ instance with KMS encryption. -- Autoscaling rules for the database instance, if provided. -- Service credential secrets and store them in secret manager. - -![fscloud-rabbitmq](../../reference-architecture/deployable-architecture-rabbitmq.svg) +# Cloud automation for RabbitMQ (Security Enforced) :exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). diff --git a/solutions/security-enforced/main.tf b/solutions/security-enforced/main.tf index a7cea4ed..12f2ca58 100644 --- a/solutions/security-enforced/main.tf +++ b/solutions/security-enforced/main.tf @@ -4,10 +4,11 @@ module "icd_rabbitmq" { ibmcloud_api_key = var.ibmcloud_api_key existing_resource_group_name = var.existing_resource_group_name name = var.name + provider_visibility = "private" region = var.region rabbitmq_version = var.rabbitmq_version existing_rabbitmq_instance_crn = var.existing_rabbitmq_instance_crn - rabbitmq_service_endpoints = "private" + service_endpoints = "private" members = var.members member_memory_mb = var.member_memory_mb member_cpu_count = var.member_cpu_count @@ -18,7 +19,7 @@ module "icd_rabbitmq" { users = var.users tags = var.tags access_tags = var.access_tags - use_ibm_owned_encryption_key = false + kms_encryption_enabled = true existing_kms_instance_crn = var.existing_kms_instance_crn existing_kms_key_crn = var.existing_kms_key_crn kms_endpoint_type = "private" @@ -29,12 +30,11 @@ module "icd_rabbitmq" { existing_backup_kms_key_crn = var.existing_backup_kms_key_crn use_default_backup_encryption_key = "false" backup_crn = var.backup_crn - provider_visibility = "private" auto_scaling = var.auto_scaling existing_secrets_manager_instance_crn = var.existing_secrets_manager_instance_crn existing_secrets_manager_endpoint_type = "private" service_credential_secrets = var.service_credential_secrets - skip_rabbitmq_sm_auth_policy = var.skip_rabbitmq_sm_auth_policy + skip_rabbitmq_secrets_manager_auth_policy = var.skip_rabbitmq_secrets_manager_auth_policy admin_pass_secrets_manager_secret_group = var.admin_pass_secrets_manager_secret_group use_existing_admin_pass_secrets_manager_secret_group = var.use_existing_admin_pass_secrets_manager_secret_group admin_pass_secrets_manager_secret_name = var.admin_pass_secrets_manager_secret_name diff --git a/solutions/security-enforced/variables.tf b/solutions/security-enforced/variables.tf index 02670ca4..b7658696 100644 --- a/solutions/security-enforced/variables.tf +++ b/solutions/security-enforced/variables.tf @@ -16,16 +16,28 @@ variable "existing_resource_group_name" { variable "prefix" { type = string - description = "The prefix to add to all resources that this solution creates. Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters. It also cannot have a `--`. To not use any prefix value, you can set this value to `null` or an empty string." nullable = true + description = "The prefix to be added to all resources created by this solution. To skip using a prefix, set this value to null or an empty string. The prefix must begin with a lowercase letter and may contain only lowercase letters, digits, and hyphens '-'. It should not exceed 16 characters, must not end with a hyphen('-'), and can not contain consecutive hyphens ('--'). Example: prod-0205-cos. [Learn more](https://terraform-ibm-modules.github.io/documentation/#/prefix.md)." + validation { - condition = (var.prefix == null ? true : + # - null and empty string is allowed + # - Must not contain consecutive hyphens (--): length(regexall("--", var.prefix)) == 0 + # - Starts with a lowercase letter: [a-z] + # - Contains only lowercase letters (a–z), digits (0–9), and hyphens (-) + # - Must not end with a hyphen (-): [a-z0-9] + condition = (var.prefix == null || var.prefix == "" ? true : alltrue([ - can(regex("^[a-z]{0,1}[-a-z0-9]{0,14}[a-z0-9]{0,1}$", var.prefix)), - length(regexall("^.*--.*", var.prefix)) == 0 + can(regex("^[a-z][-a-z0-9]*[a-z0-9]$", var.prefix)), + length(regexall("--", var.prefix)) == 0 ]) ) - error_message = "Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." + error_message = "Prefix must begin with a lowercase letter and may contain only lowercase letters, digits, and hyphens '-'. It must not end with a hyphen('-'), and cannot contain consecutive hyphens ('--')." + } + + validation { + # must not exceed 16 characters in length + condition = length(var.prefix) <= 16 + error_message = "Prefix must not exceed 16 characters." } } @@ -271,7 +283,7 @@ variable "service_credential_secrets" { } } -variable "skip_rabbitmq_sm_auth_policy" { +variable "skip_rabbitmq_secrets_manager_auth_policy" { type = bool description = "Whether an IAM authorization policy is created for Secrets Manager instance to create a service credential secrets for Databases for RabbitMQ. If set to false, the Secrets Manager instance passed by the user is granted the Key Manager access to the RabbitMQ instance created by the Deployable Architecture. Set to `true` to use an existing policy. The value of this is ignored if any value for 'existing_secrets_manager_instance_crn' is not passed." default = false From 959e7356db9362c0f93b1d8d6a9270da38b87eed Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Fri, 27 Jun 2025 11:13:26 -0400 Subject: [PATCH 06/11] fix: enhanced ux --- ibm_catalog.json | 22 ++++++++++++++++--- .../deployable-architecture-rabbitmq.svg | 2 +- solutions/fully-configurable/DA-cbr_rules.md | 2 +- solutions/fully-configurable/variables.tf | 2 +- solutions/security-enforced/variables.tf | 2 +- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index e45e99e2..0de27e5e 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -22,7 +22,7 @@ "in memory" ], "short_description": "Creates and configures an instance of IBM Cloud Databases for RabbitMQ.", - "long_description": "This architecture supports creating and configuring an instance of Databases for RabbitMQ with KMS encryption. RabbitMQ routes messages between microservices for modern applications. Messages for RabbitMQ makes RabbitMQ even better by managing it for you. Features include high availability, automated backup orchestration, autoscaling, and de-coupled allocation of storage, RAM, and vCPUs. Messages for RabbitMQ pricing is based on underlying disk, RAM, and optional vCPU allocation, as well as backup storage usage. The service is HIPAA-Ready and compliant with PCI-DSS, SOC 1 Type 2, SOC 2 Type 2, ISO 27001, ISO 27017, ISO 27018, ISO 27701, and GDPR. You can also learn more by viewing docs, API docs, and terms.", + "long_description": "This architecture supports creating and configuring an instance of Databases for RabbitMQ with KMS encryption. RabbitMQ routes messages between microservices for modern applications. [Messages for RabbitMQ](https://www.ibm.com/products/messages-for-rabbitmq) makes RabbitMQ even better by managing it for you. Features include high availability, automated backup orchestration, autoscaling, and de-coupled allocation of storage, RAM, and vCPUs. Messages for RabbitMQ pricing is based on underlying disk, RAM, and optional vCPU allocation, as well as backup storage usage. The service is HIPAA-Ready and compliant with PCI-DSS, SOC 1 Type 2, SOC 2 Type 2, ISO 27001, ISO 27017, ISO 27018, ISO 27701, and GDPR. You can also learn more by viewing docs, API docs, and terms.\n\nℹ️ This Terraform-based automation is part of a broader suite of IBM-maintained Infrastructure as Code (IaC) assets, each following the naming pattern \"Cloud automation for servicename\" and focusing on single IBM Cloud service. These single-service deployable architectures can be used on their own to streamline and automate service deployments through an [IaC approach](https://cloud.ibm.com/docs/secure-enterprise?topic=secure-enterprise-understanding-projects), or assembled together into a broader [automated IaC stack](https://cloud.ibm.com/docs/secure-enterprise?topic=secure-enterprise-config-stack) to automate the deployment of an end-to-end solution architecture.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/README.md", "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/main/images/rabbitmq_icon.svg", "provider_name": "IBM", @@ -62,6 +62,13 @@ ] }, "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Viewer" + ], + "service_name": "Resource group only", + "notes": "Viewer access is required in the resource group you want to provision in." + }, { "role_crns": [ "crn:v1:bluemix:public:iam::::role:Administrator" @@ -85,8 +92,8 @@ "architecture": { "features": [ { - "title": " Creates an instance of Databases for RabbitMQ", - "description": "This architecture creates an instance of IBM Cloud Messages for RabbitMQ with optional KMS encryption. It accepts a resource group, and provides autoscaling rules." + "title": " ", + "description": "Configured to use IBM secure by default standards, but can be edited to fit your use case." } ], "diagrams": [ @@ -272,6 +279,7 @@ }, { "key": "existing_secrets_manager_endpoint_type", + "hidden": true, "options": [ { "displayname": "public", @@ -318,6 +326,7 @@ }, { "key": "kms_endpoint_type", + "hidden": true, "options": [ { "displayname": "public", @@ -371,6 +380,13 @@ ] }, "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Viewer" + ], + "service_name": "Resource group only", + "notes": "Viewer access is required in the resource group you want to provision in." + }, { "role_crns": [ "crn:v1:bluemix:public:iam::::role:Administrator" diff --git a/reference-architecture/deployable-architecture-rabbitmq.svg b/reference-architecture/deployable-architecture-rabbitmq.svg index 1071c607..3a11c7d0 100644 --- a/reference-architecture/deployable-architecture-rabbitmq.svg +++ b/reference-architecture/deployable-architecture-rabbitmq.svg @@ -1,4 +1,4 @@ -
IBM Cloud
IBM Cloud
KMS Encryption
KMS Encryption
Region
Region
Resource Group
Resource Group
IBM Cloud RabbitMQ Instance
IBM Cloud RabbitMQ Instance
RMQ
RMQ
Text is not SVG - cannot display
\ No newline at end of file +
IBM Cloud
IBM Cloud
Region
Region
Resource Group
Resource Group
Rabbit
Key ProtectSecrets Manager
Text is not SVG - cannot display
\ No newline at end of file diff --git a/solutions/fully-configurable/DA-cbr_rules.md b/solutions/fully-configurable/DA-cbr_rules.md index 6ddb077b..abb5e7cb 100644 --- a/solutions/fully-configurable/DA-cbr_rules.md +++ b/solutions/fully-configurable/DA-cbr_rules.md @@ -37,7 +37,7 @@ The `cbr_rules` input variable allows you to provide a rule for the target servi ### Example Rule For Context-Based Restrictions Configuration ```hcl -cbr_rules = [ +[ { "description" : "SCC Instance can be accessed from xyz" "account_id" : "defc0df06b644a9cabc6e44f55b3880s." diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 7378befd..75e9a403 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -48,7 +48,7 @@ variable "name" { } variable "region" { - description = "The region where you want to deploy your instance." + description = "The region to provision all resources in. [Learn more](https://terraform-ibm-modules.github.io/documentation/#/region) about how to select different regions for different services." type = string default = "us-south" diff --git a/solutions/security-enforced/variables.tf b/solutions/security-enforced/variables.tf index b7658696..c05b5e48 100644 --- a/solutions/security-enforced/variables.tf +++ b/solutions/security-enforced/variables.tf @@ -48,7 +48,7 @@ variable "name" { } variable "region" { - description = "The region where you want to deploy your instance." + description = "The region to provision all resources in. [Learn more](https://terraform-ibm-modules.github.io/documentation/#/region) about how to select different regions for different services." type = string default = "us-south" } From 9555205454af8a1917db43cfe87f59a278d54442 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Mon, 30 Jun 2025 09:51:16 -0400 Subject: [PATCH 07/11] fix: missed things when syncing with redis --- .catalog-onboard-pipeline.yaml | 2 + cra-config.yaml | 2 +- ibm_catalog.json | 72 +++++++++++-------- .../catalogValidationValues.json.template | 6 +- solutions/fully-configurable/main.tf | 9 ++- solutions/fully-configurable/moved.tf | 4 -- solutions/fully-configurable/variables.tf | 28 ++++---- .../catalogValidationValues.json.template | 3 +- solutions/security-enforced/main.tf | 2 +- solutions/security-enforced/variables.tf | 18 ++--- tests/pr_test.go | 2 +- 11 files changed, 82 insertions(+), 66 deletions(-) delete mode 100644 solutions/fully-configurable/moved.tf diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index b058c86a..f91d0c71 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -12,9 +12,11 @@ offerings: scc: instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 region: us-south + scope_resource_group_var_name: existing_resource_group_name - name: security-enforced mark_ready: true install_type: fullstack scc: instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 region: us-south + scope_resource_group_var_name: existing_resource_group_name diff --git a/cra-config.yaml b/cra-config.yaml index 8a801ae2..65c84b39 100644 --- a/cra-config.yaml +++ b/cra-config.yaml @@ -8,6 +8,6 @@ CRA_TARGETS: TF_VAR_existing_kms_instance_crn: "crn:v1:bluemix:public:hs-crypto:us-south:a/abac0df06b644a9cabc6e44f55b3880e:e6dce284-e80f-46e1-a3c1-830f7adff7a9::" TF_VAR_existing_kms_key_crn: "crn:v1:bluemix:public:hs-crypto:us-south:a/abac0df06b644a9cabc6e44f55b3880e:e6dce284-e80f-46e1-a3c1-830f7adff7a9:key:1368d2eb-3ed0-4a8b-b09c-2155895f01ea" TF_VAR_existing_resource_group_name: "geretain-test-rabbitmq" + TF_VAR_kms_encryption_enabled: true TF_VAR_provider_visibility: "public" - TF_VAR_use_ibm_owned_encryption_key: false TF_VAR_prefix: "test" diff --git a/ibm_catalog.json b/ibm_catalog.json index 0de27e5e..28e2004f 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -17,7 +17,6 @@ "infrastructure as code", "terraform", "solution", - "rabbitmq standard", "cache", "in memory" ], @@ -30,24 +29,25 @@ "features": [ { "title": "KMS encryption", - "description": "Provides KMS encryption for the data that you store in the database." + "description": "Provides [KMS encryption](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-key-protect&interface=ui) for the data that you store in the database, enhancing data security." + }, { "title": "Autoscaling", - "description": "Provides the autoscaling to allow the database to increase resources in response to usage." - }, - { - "title": "Backup restoration", - "description": "Provides database restoration using a backup created by a deployment with the same service ID." + "description": "Provides the [autoscaling](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-autoscaling&interface=ui) to allow the database to increase resources in response to usage." }, { "title": "Access tags", "description": "Attaches access tags to the RabbitMQ instance." + }, + { + "title": "Backup restoration", + "description": "Provides [database restoration](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-backups-for-rabbitmq&interface=ui) using a backup created by a deployment with the same service ID." } ], "flavors": [ { - "label": "Fully Configurable", + "label": "Fully configurable", "name": "fully-configurable", "index": 1, "install_type": "fullstack", @@ -71,22 +71,23 @@ }, { "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Administrator" + "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "all-account-management-services" + "service_name": "messages-for-rabbitmq" }, { "role_crns": [ "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "messages-for-rabbitmq" + "service_name": "kms", + "notes": "[Optional] Editor access is required to create keys. It is only required when using Key Protect for encryption." }, { "role_crns": [ - "crn:v1:bluemix:public:iam::::serviceRole:Manager", "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "kms" + "service_name": "hs-crypto", + "notes": "[Optional] Editor access is required to create keys in HPCS. It is only required when using HPCS for encryption." } ], "architecture": { @@ -143,13 +144,11 @@ } }, { - "key": "prefix", - "required": true + "key": "prefix" }, { "key": "region", "required": true, - "default_value": "us-south", "options": [ { "displayname": "Chennai (che01)", @@ -219,7 +218,8 @@ "key": "name" }, { - "key": "tags", + "key": "resource_tags", + "type": "array", "custom_config": { "grouping": "deployment", "original_grouping": "deployment", @@ -230,6 +230,7 @@ }, { "key": "access_tags", + "type": "array", "custom_config": { "grouping": "deployment", "original_grouping": "deployment", @@ -257,7 +258,21 @@ "key": "auto_scaling" }, { - "key": "service_endpoints" + "key": "service_endpoints", + "options": [ + { + "displayname": "private", + "value": "private" + }, + { + "displayname": "public", + "value": "public" + }, + { + "displayname": "public-and-private", + "value": "public-and-private" + } + ] }, { "key": "service_credential_names" @@ -365,7 +380,7 @@ ] }, { - "label": "Security-Enforced", + "label": "Security-enforced", "name": "security-enforced", "index": 2, "install_type": "fullstack", @@ -389,22 +404,23 @@ }, { "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Administrator" + "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "all-account-management-services" + "service_name": "messages-for-rabbitmq" }, { "role_crns": [ "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "messages-for-rabbitmq" + "service_name": "kms", + "notes": "[Optional] Editor access is required to create keys. It is only required when using Key Protect for encryption." }, { "role_crns": [ - "crn:v1:bluemix:public:iam::::serviceRole:Manager", "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "kms" + "service_name": "hs-crypto", + "notes": "[Optional] Editor access is required to create keys in HPCS. It is only required when using HPCS for encryption." } ], "architecture": { @@ -442,13 +458,11 @@ } }, { - "key": "prefix", - "required": true + "key": "prefix" }, { "key": "region", "required": true, - "default_value": "us-south", "options": [ { "displayname": "Chennai (che01)", @@ -518,7 +532,8 @@ "key": "name" }, { - "key": "tags", + "key": "resource_tags", + "type": "array", "custom_config": { "grouping": "deployment", "original_grouping": "deployment", @@ -529,6 +544,7 @@ }, { "key": "access_tags", + "type": "array", "custom_config": { "grouping": "deployment", "original_grouping": "deployment", diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 3576f866..a8cd4380 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -1,7 +1,9 @@ { "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", - "tags": $TAGS, + "resource_tags": $TAGS, "name": $PREFIX, - "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN + "existing_resource_group_name":"geretain-test-rabbitmq", + "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN, + "kms_encryption_enabled": true } diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index b657160f..d41f51fb 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -5,7 +5,6 @@ locals { prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : "" } - module "resource_group" { source = "terraform-ibm-modules/resource-group/ibm" version = "1.2.0" @@ -49,7 +48,7 @@ module "kms" { standard_key = false rotation_interval_month = 3 dual_auth_delete_enabled = false - force_delete = true + force_delete = true # Force delete must be set to true, or the terraform destroy will fail since the service does not de-register itself from the key until the reclamation period has expired. } ] } @@ -291,7 +290,7 @@ module "rabbitmq" { use_same_kms_key_for_backups = local.use_same_kms_key_for_backups use_default_backup_encryption_key = var.use_default_backup_encryption_key access_tags = var.access_tags - tags = var.tags + tags = var.resource_tags admin_pass = local.admin_pass users = var.users members = var.members @@ -365,7 +364,7 @@ locals { service_credentials_ttl = secret.service_credentials_ttl service_credential_secret_description = secret.service_credential_secret_description service_credentials_source_service_role_crn = secret.service_credentials_source_service_role_crn - service_credentials_source_service_crn = module.rabbitmq[0].crn + service_credentials_source_service_crn = local.rabbitmq_crn secret_type = "service_credentials" #checkov:skip=CKV_SECRET_6 } ] @@ -377,7 +376,7 @@ locals { secret_group_name = "${local.prefix}${var.admin_pass_secrets_manager_secret_group}" existing_secret_group = var.use_existing_admin_pass_secrets_manager_secret_group secrets = [{ - secret_name = "${var.prefix}${var.admin_pass_secrets_manager_secret_name}" + secret_name = "${local.prefix}${var.admin_pass_secrets_manager_secret_name}" secret_type = "arbitrary" secret_payload_password = local.admin_pass } diff --git a/solutions/fully-configurable/moved.tf b/solutions/fully-configurable/moved.tf deleted file mode 100644 index 2c783c3c..00000000 --- a/solutions/fully-configurable/moved.tf +++ /dev/null @@ -1,4 +0,0 @@ -moved { - from = module.rabbitmq - to = module.rabbitmq[0] -} diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 75e9a403..1224eab6 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -58,16 +58,16 @@ variable "region" { } } -variable "rabbitmq_version" { - description = "The version of the Databases for RabbitMQ instance. If no value is specified, the current preferred version of Databases for RabbitMQ is used." +variable "existing_rabbitmq_instance_crn" { type = string default = null + description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." } -variable "existing_rabbitmq_instance_crn" { +variable "rabbitmq_version" { + description = "The version of the Messages for RabbitMQ instance." type = string default = null - description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." } ############################################################################## @@ -76,7 +76,7 @@ variable "existing_rabbitmq_instance_crn" { variable "service_endpoints" { type = string - description = "Specify whether you want to enable the public, private, or both service endpoints. Supported values are 'public', 'private', or 'public-and-private'." + description = "The type of endpoint of the database instance. Possible values: `public`, `private`, `public-and-private`." default = "private" validation { @@ -85,11 +85,10 @@ variable "service_endpoints" { } } - variable "members" { type = number description = "The number of members that are allocated. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." - default = 3 + default = 2 } variable "member_memory_mb" { @@ -124,7 +123,7 @@ variable "service_credential_names" { variable "admin_pass" { type = string - description = "The password for the database administrator. If the admin password is null then the admin user ID cannot be accessed. More users can be specified in a user block." + description = "The password for the database administrator. If no admin password is provided (i.e., it is null), one will be generated automatically. Additional users can be added using a user block." default = null sensitive = true } @@ -141,15 +140,15 @@ variable "users" { description = "A list of users that you want to create on the database. Users block is supported by RabbitMQ version >= 6.0. Multiple blocks are allowed. The user password must be in the range of 10-32 characters. Be warned that in most case using IAM service credentials (via the var.service_credential_names) is sufficient to control access to the RabbitMQ instance. This blocks creates native RabbitMQ database users. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/solutions/standard/DA-types.md#users)" } -variable "tags" { +variable "resource_tags" { type = list(any) - description = "The list of tags to be added to the Databases for RabbitMQ instance." + description = "The list of tags to be added to the Messages for RabbitMQ instance." default = [] } variable "access_tags" { type = list(string) - description = "A list of access tags to apply to the Databases for RabbitMQ instance created by the solution. [Learn more](https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial)." + description = "A list of access tags to apply to the Messages for RabbitMQ instance created by the solution. [Learn more](https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial)." default = [] } @@ -180,13 +179,13 @@ variable "kms_encryption_enabled" { variable "existing_kms_instance_crn" { type = string - description = "The CRN of a Key Protect or Hyper Protect Crypto Services instance. Required to create a new encryption key and key ring which will be used to encrypt both deployment data and backups. Applies only if `use_ibm_owned_encryption_key` is false. To use an existing key, pass values for `existing_kms_key_crn` and/or `existing_backup_kms_key_crn`. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." + description = "The CRN of a Key Protect or Hyper Protect Crypto Services instance. Required to create a new encryption key and key ring which will be used to encrypt both deployment data and backups. To use an existing key, pass values for `existing_kms_key_crn` and/or `existing_backup_kms_key_crn`. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." default = null } variable "existing_kms_key_crn" { type = string - description = "The CRN of a Key Protect or Hyper Protect Crypto Services encryption key to encrypt your data. Applies only if `use_ibm_owned_encryption_key` is false. By default this key is used for both deployment data and backups, but this behaviour can be altered using the optional `existing_backup_kms_key_crn` input. If no value is passed a new key will be created in the instance specified in the `existing_kms_instance_crn` input. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." + description = "The CRN of a Key Protect or Hyper Protect Crypto Services encryption key to encrypt your data. By default this key is used for both deployment data and backups, but this behaviour can be altered using the optional `existing_backup_kms_key_crn` input. If no value is passed a new key will be created in the instance specified in the `existing_kms_instance_crn` input. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups)." default = null } @@ -233,7 +232,7 @@ variable "existing_backup_kms_key_crn" { variable "use_default_backup_encryption_key" { type = bool - description = "When `use_ibm_owned_encryption_key` is set to false, backups will be encrypted with either the key specified in `existing_kms_key_crn`, in `existing_backup_kms_key_crn`, or with a new key that will be created in the instance specified in the `existing_kms_instance_crn` input. If you do not want to use your own key for backups encryption, you can set this to `true` to use the IBM Cloud Databases default encryption for backups. Alternatively set `use_ibm_owned_encryption_key` to true to use the default encryption for both backups and deployment data." + description = "When `kms_encryption_enabled` is set to true, backups will be encrypted with either the key specified in `existing_kms_key_crn`, in `existing_backup_kms_key_crn`, or with a new key that will be created in the instance specified in the `existing_kms_instance_crn` input. If you do not want to use your own key for backups encryption, you can set this to `true` to use the IBM Cloud Databases default encryption for backups. Alternatively set `kms_encryption_enabled` to false to use the default encryption for both backups and deployment data." default = false } @@ -250,6 +249,7 @@ variable "backup_crn" { error_message = "backup_crn must be null OR starts with 'crn:' and contains ':backup:'" } } + variable "provider_visibility" { description = "Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints)." type = string diff --git a/solutions/security-enforced/catalogValidationValues.json.template b/solutions/security-enforced/catalogValidationValues.json.template index 3576f866..a0370e26 100644 --- a/solutions/security-enforced/catalogValidationValues.json.template +++ b/solutions/security-enforced/catalogValidationValues.json.template @@ -1,7 +1,8 @@ { "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", - "tags": $TAGS, + "resource_tags": $TAGS, "name": $PREFIX, + "existing_resource_group_name": "geretain-test-rabbitmq", "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN } diff --git a/solutions/security-enforced/main.tf b/solutions/security-enforced/main.tf index 12f2ca58..04d50458 100644 --- a/solutions/security-enforced/main.tf +++ b/solutions/security-enforced/main.tf @@ -17,7 +17,7 @@ module "icd_rabbitmq" { service_credential_names = var.service_credential_names admin_pass = var.admin_pass users = var.users - tags = var.tags + resource_tags = var.resource_tags access_tags = var.access_tags kms_encryption_enabled = true existing_kms_instance_crn = var.existing_kms_instance_crn diff --git a/solutions/security-enforced/variables.tf b/solutions/security-enforced/variables.tf index c05b5e48..c4ce28dd 100644 --- a/solutions/security-enforced/variables.tf +++ b/solutions/security-enforced/variables.tf @@ -53,16 +53,16 @@ variable "region" { default = "us-south" } -variable "rabbitmq_version" { - description = "The version of the Databases for RabbitMQ instance. If no value is specified, the current preferred version of Databases for RabbitMQ is used." +variable "existing_rabbitmq_instance_crn" { type = string default = null + description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." } -variable "existing_rabbitmq_instance_crn" { +variable "rabbitmq_version" { + description = "The version of the Messages for RabbitMQ instance." type = string default = null - description = "The CRN of an existing Messages for RabbitMQ instance. If no value is specified, a new instance is created." } ############################################################################## @@ -72,7 +72,7 @@ variable "existing_rabbitmq_instance_crn" { variable "members" { type = number description = "The number of members that are allocated. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." - default = 3 + default = 2 } variable "member_memory_mb" { @@ -107,7 +107,7 @@ variable "service_credential_names" { variable "admin_pass" { type = string - description = "The password for the database administrator. If the admin password is null then the admin user ID cannot be accessed. More users can be specified in a user block." + description = "The password for the database administrator. If no admin password is provided (i.e., it is null), one will be generated automatically. Additional users can be added using a user block." default = null sensitive = true } @@ -124,15 +124,15 @@ variable "users" { description = "A list of users that you want to create on the database. Users block is supported by RabbitMQ version >= 6.0. Multiple blocks are allowed. The user password must be in the range of 10-32 characters. Be warned that in most case using IAM service credentials (via the var.service_credential_names) is sufficient to control access to the RabbitMQ instance. This blocks creates native RabbitMQ database users. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-icd-rabbitmq/blob/main/solutions/standard/DA-types.md#users)" } -variable "tags" { +variable "resource_tags" { type = list(any) - description = "The list of tags to be added to the Databases for RabbitMQ instance." + description = "The list of resource tags to be added to the Messages for RabbitMQ instance." default = [] } variable "access_tags" { type = list(string) - description = "A list of access tags to apply to the Databases for RabbitMQ instance created by the solution. [Learn more](https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial)." + description = "A list of access tags to apply to the Messages for RabbitMQ instance created by the solution. [Learn more](https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial)." default = [] } diff --git a/tests/pr_test.go b/tests/pr_test.go index 3ef26fe5..1fe92b7e 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -129,7 +129,7 @@ func TestRunFullyConfigurableUpgradeSolution(t *testing.T) { Testing: t, TerraformDir: fullyConfigurableSolutionTerraformDir, BestRegionYAMLPath: regionSelectionPath, - Prefix: "rmq-da-upg", + Prefix: "rmq-upg", ResourceGroup: resourceGroup, }) From 45012baca2b7e5ab9a6cfb59a4c8bb4091ee8888 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Mon, 30 Jun 2025 12:26:48 -0400 Subject: [PATCH 08/11] fix: a few more changes --- ibm_catalog.json | 16 +++++++--------- .../deployable-architecture-rabbitmq.svg | 2 +- solutions/fully-configurable/variables.tf | 2 +- solutions/security-enforced/variables.tf | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 28e2004f..2b462114 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -30,7 +30,6 @@ { "title": "KMS encryption", "description": "Provides [KMS encryption](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-key-protect&interface=ui) for the data that you store in the database, enhancing data security." - }, { "title": "Autoscaling", @@ -64,7 +63,7 @@ "iam_permissions": [ { "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Viewer" + "crn:v1:bluemix:public:iam::::role:Viewer" ], "service_name": "Resource group only", "notes": "Viewer access is required in the resource group you want to provision in." @@ -133,7 +132,6 @@ { "key": "existing_resource_group_name", "display_name": "resource_group", - "required": true, "custom_config": { "type": "resource_group", "grouping": "deployment", @@ -372,10 +370,10 @@ "key": "skip_rabbitmq_kms_auth_policy" }, { - "key": "cbr_rules" + "key": "existing_rabbitmq_instance_crn" }, { - "key": "existing_rabbitmq_instance_crn" + "key": "cbr_rules" } ] }, @@ -397,7 +395,7 @@ "iam_permissions": [ { "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Viewer" + "crn:v1:bluemix:public:iam::::role:Viewer" ], "service_name": "Resource group only", "notes": "Viewer access is required in the resource group you want to provision in." @@ -447,7 +445,7 @@ }, { "key": "existing_resource_group_name", - "required": true, + "display_name": "resource_group", "custom_config": { "type": "resource_group", "grouping": "deployment", @@ -636,10 +634,10 @@ "key": "skip_rabbitmq_kms_auth_policy" }, { - "key": "cbr_rules" + "key": "existing_rabbitmq_instance_crn" }, { - "key": "existing_rabbitmq_instance_crn" + "key": "cbr_rules" } ] } diff --git a/reference-architecture/deployable-architecture-rabbitmq.svg b/reference-architecture/deployable-architecture-rabbitmq.svg index 3a11c7d0..52358440 100644 --- a/reference-architecture/deployable-architecture-rabbitmq.svg +++ b/reference-architecture/deployable-architecture-rabbitmq.svg @@ -1,4 +1,4 @@ -
IBM Cloud
IBM Cloud
Region
Region
Resource Group
Resource Group
Rabbit
Key ProtectSecrets Manager
Text is not SVG - cannot display
\ No newline at end of file +IBM CloudRegionResource GroupRabbit
[Optional] Key Protect
[Optional] Key Protect
Key Ring
Key Ring
Key
[Optional] Secrets Manager
Text is not SVG - cannot display
\ No newline at end of file diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 1224eab6..aefad033 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -88,7 +88,7 @@ variable "service_endpoints" { variable "members" { type = number description = "The number of members that are allocated. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." - default = 2 + default = 3 } variable "member_memory_mb" { diff --git a/solutions/security-enforced/variables.tf b/solutions/security-enforced/variables.tf index c4ce28dd..298a0d9e 100644 --- a/solutions/security-enforced/variables.tf +++ b/solutions/security-enforced/variables.tf @@ -72,7 +72,7 @@ variable "rabbitmq_version" { variable "members" { type = number description = "The number of members that are allocated. [Learn more](https://cloud.ibm.com/docs/messages-for-rabbitmq?topic=messages-for-rabbitmq-resources-scaling)." - default = 2 + default = 3 } variable "member_memory_mb" { From 28fb5ef1ccb8fb1d11f13942420b556f935ce906 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Mon, 30 Jun 2025 12:53:09 -0400 Subject: [PATCH 09/11] fix: diagram --- reference-architecture/deployable-architecture-rabbitmq.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-architecture/deployable-architecture-rabbitmq.svg b/reference-architecture/deployable-architecture-rabbitmq.svg index 52358440..dfed3a1d 100644 --- a/reference-architecture/deployable-architecture-rabbitmq.svg +++ b/reference-architecture/deployable-architecture-rabbitmq.svg @@ -1,4 +1,4 @@ -IBM CloudRegionResource GroupRabbit
[Optional] Key Protect
[Optional] Key Protect
Key Ring
Key Ring
Key
[Optional] Secrets Manager
Text is not SVG - cannot display
\ No newline at end of file +IBM CloudRegionResource GroupRabbit
[Optional] Key Protect
[Optional] Key Protect
Key Ring
Key Ring
rabbitmq-key
[Optional] Secrets Manager
Text is not SVG - cannot display
\ No newline at end of file From c8d694abacaaeb8a2a5d25cb700916a834c24778 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Mon, 30 Jun 2025 13:30:48 -0400 Subject: [PATCH 10/11] test: fix kms vars in test --- tests/pr_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/pr_test.go b/tests/pr_test.go index 1fe92b7e..2df5d794 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -110,6 +110,7 @@ func TestRunFullyConfigurableSolutionSchematics(t *testing.T) { {Name: "prefix", Value: options.Prefix, DataType: "string"}, {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "existing_kms_instance_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"}, + {Name: "kms_encryption_enabled", Value: true, DataType: "bool"}, {Name: "kms_endpoint_type", Value: "private", DataType: "string"}, {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "rabbitmq_version", Value: latestVersion, DataType: "string"}, // Always lock this test into the latest supported RabbitMQ version @@ -137,6 +138,7 @@ func TestRunFullyConfigurableUpgradeSolution(t *testing.T) { "prefix": options.Prefix, "access_tags": permanentResources["accessTags"], "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], + "kms_encryption_enabled": true, "kms_endpoint_type": "public", "provider_visibility": "public", "existing_resource_group_name": resourceGroup, @@ -233,14 +235,14 @@ func TestPlanValidation(t *testing.T) { // Test the DA when using an existing KMS instance var fullyConfigurableSolutionWithExistingKms = map[string]any{ - "access_tags": permanentResources["accessTags"], - "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], - "use_ibm_owned_encryption_key": false, + "access_tags": permanentResources["accessTags"], + "existing_kms_instance_crn": permanentResources["hpcs_south_crn"], + "kms_encryption_enabled": true, } // Test the DA when using IBM owned encryption key var fullyConfigurableWithUseIbmOwnedEncKey = map[string]any{ - "use_ibm_owned_encryption_key": true, + "kms_encryption_enabled": false, } // Create a map of the variables From 427f49f02b4c15394d6a53ca25a5eab8245a5169 Mon Sep 17 00:00:00 2001 From: "kierra.searle@ibm.com" Date: Mon, 30 Jun 2025 14:12:29 -0400 Subject: [PATCH 11/11] SKIP UPGRADE TEST