From 99414ebe972582e927e279be39f3455beda13586 Mon Sep 17 00:00:00 2001 From: Kierra Searle Date: Fri, 8 Nov 2024 06:26:56 -0500 Subject: [PATCH] feat: added support to the instances DA to use KMS from a different account using the new `ibmcloud_kms_api_key` input (#131) --- solutions/instances/README.md | 15 ++- solutions/instances/main.tf | 166 ++++++++++++++++++++++++------- solutions/instances/outputs.tf | 12 +-- solutions/instances/provider.tf | 2 +- solutions/instances/variables.tf | 11 +- 5 files changed, 160 insertions(+), 46 deletions(-) diff --git a/solutions/instances/README.md b/solutions/instances/README.md index ff5a4348..323520ed 100644 --- a/solutions/instances/README.md +++ b/solutions/instances/README.md @@ -25,11 +25,17 @@ This solution supports provisioning and configuring the following infrastructure | Name | Source | Version | |------|--------|---------| +| [buckets](#module\_buckets) | terraform-ibm-modules/cos/ibm//modules/buckets | 8.14.1 | | [cos](#module\_cos) | terraform-ibm-modules/cos/ibm//modules/fscloud | 8.14.1 | | [create\_profile\_attachment](#module\_create\_profile\_attachment) | terraform-ibm-modules/scc/ibm//modules/attachment | 1.8.10 | +| [existing\_cos\_crn\_parser](#module\_existing\_cos\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_en\_crn\_parser](#module\_existing\_en\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.0.0 | +| [existing\_kms\_crn\_parser](#module\_existing\_kms\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_kms\_key\_crn\_parser](#module\_existing\_kms\_key\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_scc\_crn\_parser](#module\_existing\_scc\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.0.0 | | [kms](#module\_kms) | terraform-ibm-modules/kms-all-inclusive/ibm | 4.15.13 | | [resource\_group](#module\_resource\_group) | terraform-ibm-modules/resource-group/ibm | 1.1.6 | -| [scc](#module\_scc) | terraform-ibm-modules/scc/ibm | 1.8.10 | +| [scc](#module\_scc) | terraform-ibm-modules/scc/ibm | 1.8.12 | | [scc\_wp](#module\_scc\_wp) | terraform-ibm-modules/scc-workload-protection/ibm | 1.4.0 | ### Resources @@ -38,6 +44,8 @@ This solution supports provisioning and configuring the following infrastructure |------|------| | [ibm_en_subscription_email.email_subscription](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.70.1/docs/resources/en_subscription_email) | resource | | [ibm_en_topic.en_topic](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.70.1/docs/resources/en_topic) | resource | +| [ibm_iam_authorization_policy.cos_kms_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.70.1/docs/resources/iam_authorization_policy) | resource | +| [time_sleep.wait_for_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/0.12.1/docs/resources/sleep) | resource | | [time_sleep.wait_for_scc](https://registry.terraform.io/providers/hashicorp/time/0.12.1/docs/resources/sleep) | resource | | [ibm_en_destinations.en_destinations](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.70.1/docs/data-sources/en_destinations) | data source | | [ibm_iam_account_settings.iam_account_settings](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.70.1/docs/data-sources/iam_account_settings) | data source | @@ -56,12 +64,13 @@ This solution supports provisioning and configuring the following infrastructure | [existing\_activity\_tracker\_crn](#input\_existing\_activity\_tracker\_crn) | The CRN of an Activity Tracker instance to send Security and Compliance Object Storage bucket events to. If no value passed, events are sent to the instance associated to the container's location unless otherwise specified in the Activity Tracker Event Routing service configuration. Ignored if using existing Object Storage bucket. | `string` | `null` | no | | [existing\_cos\_instance\_crn](#input\_existing\_cos\_instance\_crn) | The CRN of an existing Object Storage instance. If not specified, an instance is created. | `string` | `null` | no | | [existing\_en\_crn](#input\_existing\_en\_crn) | The CRN of an Event Notification instance. Used to integrate with Security and Compliance Center. | `string` | `null` | no | -| [existing\_kms\_instance\_crn](#input\_existing\_kms\_instance\_crn) | The CRN of the existing Hyper Protect Crypto Services or Key Protect instance. Applies only if not supplying an existing KMS root key and if `skip_cos_kms_auth_policy` is true. | `string` | `null` | no | +| [existing\_kms\_instance\_crn](#input\_existing\_kms\_instance\_crn) | The CRN of the existing KMS instance (Hyper Protect Crypto Services or Key Protect). If the KMS instance is in different account you must also provide a value for `ibmcloud_kms_api_key`. | `string` | `null` | no | | [existing\_monitoring\_crn](#input\_existing\_monitoring\_crn) | The CRN of an IBM Cloud Monitoring instance to to send Security and Compliance Object Storage bucket metrics to, as well as Workload Protection data. If no value passed, metrics are sent to the instance associated to the container's location unless otherwise specified in the Metrics Router service configuration. Ignored if using existing Object Storage bucket and not provisioning Workload Protection. | `string` | `null` | no | | [existing\_scc\_cos\_bucket\_name](#input\_existing\_scc\_cos\_bucket\_name) | The name of an existing bucket inside the existing Object Storage instance to use for Security and Compliance Center. If not specified, a bucket is created. | `string` | `null` | no | | [existing\_scc\_cos\_kms\_key\_crn](#input\_existing\_scc\_cos\_kms\_key\_crn) | The CRN of an existing KMS key to use to encrypt the Security and Compliance Center Object Storage bucket. If no value is set for this variable, specify a value for either the `existing_kms_instance_crn` variable to create a key ring and key, or for the `existing_scc_cos_bucket_name` variable to use an existing bucket. | `string` | `null` | no | | [existing\_scc\_instance\_crn](#input\_existing\_scc\_instance\_crn) | The CRN of an existing Security and Compliance Center instance. If not supplied, a new instance will be created. | `string` | `null` | no | | [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes | +| [ibmcloud\_kms\_api\_key](#input\_ibmcloud\_kms\_api\_key) | 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 Security and Compliance Centre instance. Leave this input empty if the same account owns both instances. | `string` | `null` | no | | [kms\_endpoint\_type](#input\_kms\_endpoint\_type) | The endpoint for communicating with the KMS instance. Possible values: `public`, `private.` | `string` | `"private"` | no | | [management\_endpoint\_type\_for\_bucket](#input\_management\_endpoint\_type\_for\_bucket) | The type of endpoint for the IBM Terraform provider to use to manage Object Storage buckets. Possible values: `public`, `private`m `direct`. If you specify `private`, enable virtual routing and forwarding in your account, and the Terraform runtime must have access to the the IBM Cloud private network. | `string` | `"private"` | no | | [prefix](#input\_prefix) | The prefix to add to all resources created by this solution. | `string` | `null` | no | @@ -86,7 +95,7 @@ This solution supports provisioning and configuring the following infrastructure | [scc\_workload\_protection\_instance\_tags](#input\_scc\_workload\_protection\_instance\_tags) | The list of tags to add to the Workload Protection instance. | `list(string)` | `[]` | no | | [scc\_workload\_protection\_resource\_key\_tags](#input\_scc\_workload\_protection\_resource\_key\_tags) | The tags associated with the Workload Protection resource key. | `list(string)` | `[]` | no | | [scc\_workload\_protection\_service\_plan](#input\_scc\_workload\_protection\_service\_plan) | The pricing plan for the Workload Protection instance service. Possible values: `free-trial`, `graduated-tier`. | `string` | `"graduated-tier"` | no | -| [skip\_cos\_kms\_auth\_policy](#input\_skip\_cos\_kms\_auth\_policy) | Set to `true` to skip the creation of an IAM authorization policy that permits the Object Storage instance to read the encryption key from the KMS instance. An authorization policy must exist before an encrypted bucket can be created. | `bool` | `false` | no | +| [skip\_cos\_kms\_auth\_policy](#input\_skip\_cos\_kms\_auth\_policy) | Set to `true` to skip the creation of an IAM authorization policy that permits the Object Storage instance created to read the encryption key from the KMS instance. If set to false, pass in a value for the KMS instance in the `existing_kms_instance_crn` variable. If a value is specified for `ibmcloud_kms_api_key`, the policy is created in the KMS account. | `bool` | `false` | no | | [skip\_scc\_cos\_auth\_policy](#input\_skip\_scc\_cos\_auth\_policy) | Set to `true` to skip creation of an IAM authorization policy that permits the Security and Compliance Center to write to the Object Storage instance created by this solution. Applies only if `existing_scc_instance_crn` is not provided. | `bool` | `false` | no | | [skip\_scc\_workload\_protection\_auth\_policy](#input\_skip\_scc\_workload\_protection\_auth\_policy) | Set to `true` to skip creating an IAM authorization policy that permits the Security and Compliance Center instance to read from the Workload Protection instance. Applies only if `provision_scc_workload_protection` is true. | `bool` | `false` | no | | [use\_existing\_resource\_group](#input\_use\_existing\_resource\_group) | Whether to use an existing resource group. | `bool` | `false` | no | diff --git a/solutions/instances/main.tf b/solutions/instances/main.tf index 73317464..db0941ae 100644 --- a/solutions/instances/main.tf +++ b/solutions/instances/main.tf @@ -4,7 +4,7 @@ locals { # tflint-ignore: terraform_unused_declarations - validate_inputs = var.existing_scc_cos_bucket_name == null && var.existing_scc_cos_kms_key_crn == null && var.existing_kms_instance_crn == null ? tobool("A value must be passed for 'existing_kms_instance_crn' if not supplying any value for 'existing_scc_cos_kms_key_crn' or 'existing_scc_cos_bucket_name'.") : true + validate_inputs = var.existing_scc_instance_crn == null && var.existing_scc_cos_bucket_name == null && var.existing_scc_cos_kms_key_crn == null && var.existing_kms_instance_crn == null ? tobool("A value must be passed for 'existing_kms_instance_crn' if not supplying any value for 'existing_scc_instance_crn', 'existing_scc_cos_kms_key_crn' or 'existing_scc_cos_bucket_name'.") : true # tflint-ignore: terraform_unused_declarations validate_cos_inputs = var.existing_scc_cos_bucket_name != null && var.existing_scc_cos_kms_key_crn != null ? tobool("A value should not be passed for 'existing_scc_cos_kms_key_crn' when passing a value for 'existing_scc_cos_bucket_name'. A key is only needed when creating a new COS bucket.") : true # tflint-ignore: terraform_unused_declarations @@ -26,10 +26,26 @@ module "resource_group" { # KMS Key ####################################################################################################################### +module "existing_kms_crn_parser" { + count = var.existing_kms_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_kms_instance_crn +} + +module "existing_kms_key_crn_parser" { + count = var.existing_scc_cos_kms_key_crn != null || var.existing_kms_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_scc_cos_kms_key_crn != null ? var.existing_scc_cos_kms_key_crn : module.kms[0].keys[format("%s.%s", local.scc_cos_key_ring_name, local.scc_cos_key_name)].crn +} + locals { - parsed_existing_kms_instance_crn = var.existing_kms_instance_crn != null ? split(":", var.existing_kms_instance_crn) : [] - kms_region = length(local.parsed_existing_kms_instance_crn) > 0 ? local.parsed_existing_kms_instance_crn[5] : null - existing_kms_guid = length(local.parsed_existing_kms_instance_crn) > 0 ? local.parsed_existing_kms_instance_crn[7] : null + kms_region = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].region : var.scc_region + existing_kms_guid = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].service_instance : null + kms_service_name = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].service_name : null + kms_account_id = var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].account_id : null + kms_key_id = var.existing_scc_instance_crn == null && length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].resource : null scc_cos_key_ring_name = var.prefix != null ? "${var.prefix}-${var.scc_cos_key_ring_name}" : var.scc_cos_key_ring_name scc_cos_key_name = var.prefix != null ? "${var.prefix}-${var.scc_cos_key_name}" : var.scc_cos_key_name @@ -38,6 +54,56 @@ locals { scc_workload_protection_instance_name = var.prefix != null ? "${var.prefix}-${var.scc_workload_protection_instance_name}" : var.scc_workload_protection_instance_name scc_workload_protection_resource_key_name = var.prefix != null ? "${var.prefix}-${var.scc_workload_protection_instance_name}-key" : "${var.scc_workload_protection_instance_name}-key" scc_cos_bucket_name = var.prefix != null ? "${var.prefix}-${var.scc_cos_bucket_name}" : var.scc_cos_bucket_name + + create_cross_account_auth_policy = !var.skip_cos_kms_auth_policy && var.ibmcloud_kms_api_key == null ? false : (data.ibm_iam_account_settings.iam_account_settings.account_id != module.existing_kms_crn_parser[0].account_id) +} + +# Create IAM Authorization Policy to allow COS to access KMS for the encryption key, if cross account KMS is passed in +resource "ibm_iam_authorization_policy" "cos_kms_policy" { + count = local.create_cross_account_auth_policy ? 1 : 0 + provider = ibm.kms + source_service_account = data.ibm_iam_account_settings.iam_account_settings.account_id + source_service_name = "cloud-object-storage" + source_resource_instance_id = local.cos_instance_guid + roles = ["Reader"] + description = "Allow the COS instance ${local.cos_instance_guid} to read the ${local.kms_service_name} key ${local.kms_key_id} from the instance ${local.existing_kms_guid}" + resource_attributes { + name = "serviceName" + operator = "stringEquals" + value = local.kms_service_name + } + resource_attributes { + name = "accountId" + operator = "stringEquals" + value = local.kms_account_id + } + resource_attributes { + name = "serviceInstance" + operator = "stringEquals" + value = local.existing_kms_guid + } + resource_attributes { + name = "resourceType" + operator = "stringEquals" + value = "key" + } + resource_attributes { + name = "resource" + operator = "stringEquals" + value = local.kms_key_id + } + # Scope of policy now includes the key, so ensure to create new policy before + # destroying old one to prevent any disruption to every day services. + lifecycle { + create_before_destroy = true + } +} + +resource "time_sleep" "wait_for_authorization_policy" { + depends_on = [ibm_iam_authorization_policy.cos_kms_policy] + count = local.create_cross_account_auth_policy ? 1 : 0 + + create_duration = "30s" } # KMS root key for SCC COS bucket @@ -45,7 +111,7 @@ module "kms" { providers = { ibm = ibm.kms } - count = (var.existing_scc_cos_kms_key_crn != null || var.existing_scc_cos_bucket_name != null) && var.existing_scc_instance_crn == null ? 0 : 1 # no need to create any KMS resources if passing an existing key or bucket, or SCC instance + count = var.existing_scc_cos_kms_key_crn != null || var.existing_scc_cos_bucket_name != null || var.existing_scc_instance_crn != null ? 0 : 1 # no need to create any KMS resources if passing an existing key or bucket, or SCC instance source = "terraform-ibm-modules/kms-all-inclusive/ibm" version = "4.15.13" create_key_protect_instance = false @@ -75,35 +141,26 @@ module "kms" { # COS ####################################################################################################################### -locals { - scc_cos_kms_key_crn = var.existing_scc_cos_bucket_name != null ? null : var.existing_scc_cos_kms_key_crn != null ? var.existing_scc_cos_kms_key_crn : module.kms[0].keys[format("%s.%s", local.scc_cos_key_ring_name, local.scc_cos_key_name)].crn - cos_instance_crn = var.existing_cos_instance_crn != null ? var.existing_cos_instance_crn : module.cos[0].cos_instance_crn - cos_bucket_name = var.existing_scc_cos_bucket_name != null ? var.existing_scc_cos_bucket_name : module.cos[0].buckets[local.scc_cos_bucket_name].bucket_name - +module "existing_cos_crn_parser" { + count = var.existing_cos_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_cos_instance_crn } -module "cos" { - providers = { - ibm = ibm.cos - } - count = var.existing_scc_cos_bucket_name == null && var.existing_scc_instance_crn == null ? 1 : 0 # no need to call COS module if consumer is passing existing SCC instance or COS bucket - source = "terraform-ibm-modules/cos/ibm//modules/fscloud" - version = "8.14.1" - resource_group_id = module.resource_group.resource_group_id - create_cos_instance = var.existing_cos_instance_crn == null ? true : false # don't create instance if existing one passed in - cos_instance_name = local.cos_instance_name - cos_tags = var.cos_instance_tags - existing_cos_instance_id = var.existing_cos_instance_crn - access_tags = var.cos_instance_access_tags - cos_plan = "standard" - bucket_configs = [{ +locals { + scc_cos_kms_key_crn = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? null : var.existing_scc_cos_kms_key_crn != null ? var.existing_scc_cos_kms_key_crn : module.kms[0].keys[format("%s.%s", local.scc_cos_key_ring_name, local.scc_cos_key_name)].crn : null + cos_instance_crn = var.existing_scc_instance_crn == null ? var.existing_cos_instance_crn != null ? var.existing_cos_instance_crn : module.cos[0].cos_instance_crn : null + cos_bucket_name = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? var.existing_scc_cos_bucket_name : local.create_cross_account_auth_policy ? module.buckets[0].buckets[local.scc_cos_bucket_name].bucket_name : module.cos[0].buckets[local.scc_cos_bucket_name].bucket_name : null + cos_instance_guid = var.existing_scc_instance_crn == null ? var.existing_cos_instance_crn != null ? module.existing_cos_crn_parser[0].service_instance : module.cos[0].cos_instance_guid : null + bucket_config = [{ access_tags = var.scc_cos_bucket_access_tags add_bucket_name_suffix = var.add_bucket_name_suffix bucket_name = local.scc_cos_bucket_name kms_encryption_enabled = true kms_guid = local.existing_kms_guid kms_key_crn = local.scc_cos_kms_key_crn - skip_iam_authorization_policy = var.skip_cos_kms_auth_policy + skip_iam_authorization_policy = local.create_cross_account_auth_policy || var.skip_cos_kms_auth_policy management_endpoint_type = var.management_endpoint_type_for_bucket storage_class = var.scc_cos_bucket_class resource_instance_id = local.cos_instance_crn @@ -121,16 +178,51 @@ module "cos" { metrics_monitoring_crn = var.existing_monitoring_crn } }] +} +module "cos" { + providers = { + ibm = ibm.cos + } + count = var.existing_scc_cos_bucket_name == null && var.existing_scc_instance_crn == null ? 1 : 0 # no need to call COS module if consumer is passing existing SCC instance or COS bucket + source = "terraform-ibm-modules/cos/ibm//modules/fscloud" + version = "8.14.1" + resource_group_id = module.resource_group.resource_group_id + create_cos_instance = var.existing_cos_instance_crn == null ? true : false # don't create instance if existing one passed in + cos_instance_name = local.cos_instance_name + cos_tags = var.cos_instance_tags + existing_cos_instance_id = var.existing_cos_instance_crn + access_tags = var.cos_instance_access_tags + cos_plan = "standard" + bucket_configs = local.create_cross_account_auth_policy ? [] : local.bucket_config +} + +# If doing cross-account kms, the COS instance needs to exist before the policy, and the policy needs to exist before the buckets can be created so the buckets are created separately +module "buckets" { + providers = { + ibm = ibm.cos + } + count = local.create_cross_account_auth_policy ? 1 : 0 + depends_on = [time_sleep.wait_for_authorization_policy[0]] + source = "terraform-ibm-modules/cos/ibm//modules/buckets" + version = "8.14.1" + bucket_configs = local.bucket_config } ####################################################################################################################### # SCC Instance ####################################################################################################################### + +module "existing_scc_crn_parser" { + count = var.existing_scc_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.0.0" + crn = var.existing_scc_instance_crn +} + locals { - parsed_existing_scc_instance_crn = var.existing_scc_instance_crn != null ? split(":", var.existing_scc_instance_crn) : [] - existing_scc_instance_region = length(local.parsed_existing_scc_instance_crn) > 0 ? local.parsed_existing_scc_instance_crn[5] : null - scc_instance_region = var.existing_scc_instance_crn == null ? var.scc_region : local.existing_scc_instance_region + existing_scc_instance_region = var.existing_scc_instance_crn != null ? module.existing_scc_crn_parser[0].region : null + scc_instance_region = var.existing_scc_instance_crn == null ? var.scc_region : local.existing_scc_instance_region } moved { @@ -141,7 +233,7 @@ moved { module "scc" { source = "terraform-ibm-modules/scc/ibm" existing_scc_instance_crn = var.existing_scc_instance_crn - version = "1.8.10" + version = "1.8.12" resource_group_id = module.resource_group.resource_group_id region = local.scc_instance_region instance_name = local.scc_instance_name @@ -243,11 +335,17 @@ module "scc_wp" { # SCC Event Notifications Configuration ####################################################################################################################### +module "existing_en_crn_parser" { + count = var.existing_en_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.0.0" + crn = var.existing_en_crn +} + locals { - parsed_existing_en_instance_crn = var.existing_en_crn != null ? split(":", var.existing_en_crn) : [] - existing_en_guid = length(local.parsed_existing_en_instance_crn) > 0 ? local.parsed_existing_en_instance_crn[7] : null - en_topic = var.prefix != null ? "${var.prefix} - SCC Topic" : "SCC Topic" - en_subscription_email = var.prefix != null ? "${var.prefix} - Email for Security and Compliance Center Subscription" : "Email for Security and Compliance Center Subscription" + existing_en_guid = var.existing_en_crn != null ? module.existing_en_crn_parser[0].service_instance : null + en_topic = var.prefix != null ? "${var.prefix} - SCC Topic" : "SCC Topic" + en_subscription_email = var.prefix != null ? "${var.prefix} - Email for Security and Compliance Center Subscription" : "Email for Security and Compliance Center Subscription" } data "ibm_en_destinations" "en_destinations" { diff --git a/solutions/instances/outputs.tf b/solutions/instances/outputs.tf index c3319dd1..5cf35172 100644 --- a/solutions/instances/outputs.tf +++ b/solutions/instances/outputs.tf @@ -87,22 +87,22 @@ output "scc_cos_kms_key_crn" { output "scc_cos_bucket_name" { description = "SCC COS bucket name" - value = var.existing_scc_cos_bucket_name != null ? var.existing_scc_cos_bucket_name : module.cos[0].buckets[local.scc_cos_bucket_name].bucket_name + value = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? var.existing_scc_cos_bucket_name : local.create_cross_account_auth_policy ? module.buckets[0].buckets[local.scc_cos_bucket_name].bucket_name : module.cos[0].buckets[local.scc_cos_bucket_name].bucket_name : null } output "scc_cos_bucket_config" { description = "List of buckets created" - value = var.existing_scc_cos_bucket_name != null ? null : module.cos[0].buckets[local.scc_cos_bucket_name] + value = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? null : local.create_cross_account_auth_policy ? module.buckets[0].buckets[local.scc_cos_bucket_name] : module.cos[0].buckets[local.scc_cos_bucket_name] : null } output "scc_cos_instance_id" { description = "SCC COS instance id" - value = var.existing_scc_cos_bucket_name != null ? null : module.cos[0].cos_instance_id + value = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? null : module.cos[0].cos_instance_id : null } output "scc_cos_instance_guid" { description = "SCC COS instance guid" - value = var.existing_scc_cos_bucket_name != null ? null : module.cos[0].cos_instance_guid + value = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? null : module.cos[0].cos_instance_guid : null } output "scc_cos_instance_name" { @@ -112,11 +112,11 @@ output "scc_cos_instance_name" { output "scc_cos_instance_crn" { description = "SCC COS instance crn" - value = var.existing_scc_cos_bucket_name != null ? null : module.cos[0].cos_instance_crn + value = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? null : module.cos[0].cos_instance_crn : null } output "scc_cos_resource_keys" { description = "List of resource keys" - value = var.existing_scc_cos_bucket_name != null ? null : module.cos[0].resource_keys + value = var.existing_scc_instance_crn == null ? var.existing_scc_cos_bucket_name != null ? null : module.cos[0].resource_keys : null sensitive = true } diff --git a/solutions/instances/provider.tf b/solutions/instances/provider.tf index 6ef99851..2a4642b8 100644 --- a/solutions/instances/provider.tf +++ b/solutions/instances/provider.tf @@ -9,7 +9,7 @@ provider "ibm" { provider "ibm" { alias = "kms" - ibmcloud_api_key = var.ibmcloud_api_key + ibmcloud_api_key = var.ibmcloud_kms_api_key != null ? var.ibmcloud_kms_api_key : var.ibmcloud_api_key region = local.kms_region } diff --git a/solutions/instances/variables.tf b/solutions/instances/variables.tf index 448bea42..11e19cc7 100644 --- a/solutions/instances/variables.tf +++ b/solutions/instances/variables.tf @@ -39,7 +39,7 @@ variable "prefix" { variable "existing_kms_instance_crn" { type = string default = null - description = "The CRN of the existing Hyper Protect Crypto Services or Key Protect instance. Applies only if not supplying an existing KMS root key and if `skip_cos_kms_auth_policy` is true." + description = "The CRN of the existing KMS instance (Hyper Protect Crypto Services or Key Protect). If the KMS instance is in different account you must also provide a value for `ibmcloud_kms_api_key`." } variable "existing_scc_cos_kms_key_crn" { @@ -70,6 +70,13 @@ variable "scc_cos_key_name" { description = "The name for the key created for the Security and Compliance Center Object Storage bucket. 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 "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 Security and Compliance Centre instance. Leave this input empty if the same account owns both instances." + sensitive = true + default = null +} + ######################################################################################################################## # COS variables ######################################################################################################################## @@ -142,7 +149,7 @@ variable "existing_scc_cos_bucket_name" { variable "skip_cos_kms_auth_policy" { type = bool - description = "Set to `true` to skip the creation of an IAM authorization policy that permits the Object Storage instance to read the encryption key from the KMS instance. An authorization policy must exist before an encrypted bucket can be created." + description = "Set to `true` to skip the creation of an IAM authorization policy that permits the Object Storage instance created to read the encryption key from the KMS instance. If set to false, pass in a value for the KMS instance in the `existing_kms_instance_crn` variable. If a value is specified for `ibmcloud_kms_api_key`, the policy is created in the KMS account." default = false }