diff --git a/README.md b/README.md index 41a97fbe..8f046f71 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ You need the following permissions to run this module. | Name | Source | Version | |------|--------|---------| | [cbr\_rule](#module\_cbr\_rule) | terraform-ibm-modules/cbr/ibm//modules/cbr-rule-module | 1.29.0 | +| [kms\_key\_crn\_parser](#module\_kms\_key\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | | [secrets](#module\_secrets) | ./modules/secrets | n/a | ### Resources @@ -86,9 +87,11 @@ You need the following permissions to run this module. | [ibm_iam_authorization_policy.iam_groups_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource | | [ibm_iam_authorization_policy.iam_identity_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource | | [ibm_iam_authorization_policy.kms_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource | +| [ibm_iam_authorization_policy.secrets_manager_hpcs_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource | | [ibm_resource_instance.secrets_manager_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource | | [ibm_sm_en_registration.sm_en_registration](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/sm_en_registration) | resource | | [time_sleep.wait_for_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | +| [time_sleep.wait_for_sm_hpcs_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | | [ibm_resource_instance.sm_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/resource_instance) | data source | ### Inputs @@ -100,8 +103,8 @@ You need the following permissions to run this module. | [enable\_event\_notification](#input\_enable\_event\_notification) | Set this to true to enable lifecycle notifications for your Secrets Manager instance by connecting an Event Notifications service. When setting this to true, a value must be passed for `existing_en_instance_crn` and `existing_sm_instance_crn` must be null. | `bool` | `false` | no | | [endpoint\_type](#input\_endpoint\_type) | The type of endpoint (public or private) to connect to the Secrets Manager API. The Terraform provider uses this endpoint type to interact with the Secrets Manager API and configure Event Notifications. | `string` | `"public"` | no | | [existing\_en\_instance\_crn](#input\_existing\_en\_instance\_crn) | The CRN of the Event Notifications service to enable lifecycle notifications for your Secrets Manager instance. | `string` | `null` | no | -| [existing\_kms\_instance\_guid](#input\_existing\_kms\_instance\_guid) | The GUID of the Hyper Protect Crypto Services or Key Protect instance in which the key specified in `kms_key_crn` is coming from. Required only if `kms_encryption_enabled` is set to true, and `skip_kms_iam_authorization_policy` is set to false. | `string` | `null` | no | | [existing\_sm\_instance\_crn](#input\_existing\_sm\_instance\_crn) | An existing Secrets Manager instance CRN. If not provided an new instance will be provisioned. | `string` | `null` | no | +| [is\_hpcs\_key](#input\_is\_hpcs\_key) | Set it to true if the key provided through the `kms_key_crn` is Hyper Protect Crypto Services key. | `bool` | `false` | no | | [kms\_encryption\_enabled](#input\_kms\_encryption\_enabled) | Set this to true to control the encryption keys used to encrypt the data that you store in Secrets Manager. If set to false, the data that you store is encrypted at rest by using envelope encryption. For more details, see https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-mng-data&interface=ui#about-encryption. | `bool` | `false` | no | | [kms\_key\_crn](#input\_kms\_key\_crn) | The root key CRN of a Key Management Service like Key Protect or Hyper Protect Crypto Services (HPCS) that you want to use for encryption. Only used if `kms_encryption_enabled` is set to true. | `string` | `null` | no | | [region](#input\_region) | The region where the resource will be provisioned.Its not required if passing a value for `existing_sm_instance_crn`. | `string` | `null` | no | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 0cafbea5..337acdd0 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -32,7 +32,6 @@ module "event_notification" { name = "${var.prefix}-en" tags = var.resource_tags plan = "lite" - service_endpoints = "public" region = var.en_region } @@ -55,18 +54,18 @@ resource "time_sleep" "wait_for_en_policy" { } module "secrets_manager" { - depends_on = [time_sleep.wait_for_en_policy] - source = "../.." - resource_group_id = module.resource_group.resource_group_id - region = var.region - secrets_manager_name = "${var.prefix}-secrets-manager" #tfsec:ignore:general-secrets-no-plaintext-exposure - sm_service_plan = var.sm_service_plan - sm_tags = var.resource_tags - kms_encryption_enabled = true - existing_kms_instance_guid = module.key_protect.kms_guid - kms_key_crn = module.key_protect.keys["${var.prefix}-sm.${var.prefix}-sm-key"].crn - enable_event_notification = true - existing_en_instance_crn = module.event_notification.crn + depends_on = [time_sleep.wait_for_en_policy] + source = "../.." + resource_group_id = module.resource_group.resource_group_id + region = var.region + secrets_manager_name = "${var.prefix}-secrets-manager" #tfsec:ignore:general-secrets-no-plaintext-exposure + sm_service_plan = var.sm_service_plan + sm_tags = var.resource_tags + kms_encryption_enabled = true + is_hpcs_key = false + kms_key_crn = module.key_protect.keys["${var.prefix}-sm.${var.prefix}-sm-key"].crn + enable_event_notification = true + existing_en_instance_crn = module.event_notification.crn secrets = [ { secret_group_name = "${var.prefix}-secret-group" diff --git a/examples/fscloud/main.tf b/examples/fscloud/main.tf index f0f89823..58efac39 100644 --- a/examples/fscloud/main.tf +++ b/examples/fscloud/main.tf @@ -51,15 +51,29 @@ module "event_notification" { region = var.region } +############################################################################## +# Parse info from KMS key crn +############################################################################## + +module "kms_key_crn_parser" { + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.kms_key_crn +} + +locals { + kms_service = module.kms_key_crn_parser.service_name +} + module "secrets_manager" { - source = "../../modules/fscloud" - resource_group_id = module.resource_group.resource_group_id - region = var.region - secrets_manager_name = "${var.prefix}-secrets-manager" #tfsec:ignore:general-secrets-no-plaintext-exposure - sm_tags = var.resource_tags - existing_kms_instance_guid = var.existing_kms_instance_guid - kms_key_crn = var.kms_key_crn - existing_en_instance_crn = module.event_notification.crn + source = "../../modules/fscloud" + resource_group_id = module.resource_group.resource_group_id + region = var.region + secrets_manager_name = "${var.prefix}-secrets-manager" #tfsec:ignore:general-secrets-no-plaintext-exposure + sm_tags = var.resource_tags + is_hpcs_key = local.kms_service == "hs-crypto" ? true : false + kms_key_crn = var.kms_key_crn + existing_en_instance_crn = module.event_notification.crn cbr_rules = [ { description = "${var.prefix}-secrets-manager access only from vpc" diff --git a/examples/fscloud/variables.tf b/examples/fscloud/variables.tf index 7bd97882..e3657595 100644 --- a/examples/fscloud/variables.tf +++ b/examples/fscloud/variables.tf @@ -32,11 +32,6 @@ variable "resource_tags" { # Key Management Service (KMS) ############################################################################## -variable "existing_kms_instance_guid" { - type = string - description = "The GUID of the Hyper Protect Crypto Services instance in which the key specified in `kms_key_crn` is coming from." -} - variable "kms_key_crn" { type = string description = "The root key CRN of Hyper Protect Crypto Services (HPCS) that you want to use for encryption." diff --git a/main.tf b/main.tf index c6416132..3d3da9eb 100644 --- a/main.tf +++ b/main.tf @@ -6,17 +6,19 @@ locals { # Validation (approach based on https://github.com/hashicorp/terraform/issues/25609#issuecomment-1057614400) # tflint-ignore: terraform_unused_declarations - validate_kms_values = (!var.kms_encryption_enabled && var.kms_key_crn != null && var.existing_sm_instance_crn == null) ? tobool("When passing values for var.kms_key_crn, you must set 'kms_encryption_enabled' to true. Otherwise set 'kms_encryption_enabled' to false to use default encryption") : (!var.kms_encryption_enabled && var.existing_kms_instance_guid != null) ? tobool("When passing values for var.existing_kms_instance_guid, you must set var.kms_encryption_enabled to true. Otherwise unset them to use default encryption") : true + validate_kms_values = (!var.kms_encryption_enabled && var.kms_key_crn != null && var.existing_sm_instance_crn == null) ? tobool("When passing values for var.kms_key_crn, you must set 'kms_encryption_enabled' to true. Otherwise set 'kms_encryption_enabled' to false to use default encryption") : true # tflint-ignore: terraform_unused_declarations validate_kms_vars = var.kms_encryption_enabled && var.kms_key_crn == null && var.existing_sm_instance_crn == null ? tobool("When setting var.kms_encryption_enabled to true, a value must be passed for var.kms_key_crn") : true # tflint-ignore: terraform_unused_declarations - validate_auth_policy = var.kms_encryption_enabled && var.skip_kms_iam_authorization_policy == false && var.existing_kms_instance_guid == null && var.existing_sm_instance_crn == null ? tobool("When var.skip_kms_iam_authorization_policy is set to false, and var.kms_encryption_enabled to true, a value must be passed for var.existing_kms_instance_guid in order to create the auth policy.") : true + validate_auth_policy = var.kms_encryption_enabled && var.skip_kms_iam_authorization_policy == false && var.kms_key_crn == null && var.existing_sm_instance_crn == null ? tobool("When var.skip_kms_iam_authorization_policy is set to false, and var.kms_encryption_enabled to true, a value must be passed for var.kms_key_crn in order to create the auth policy.") : true # tflint-ignore: terraform_unused_declarations validate_event_notification = var.enable_event_notification && var.existing_en_instance_crn == null ? tobool("When setting var.enable_event_notification to true, a value must be passed for var.existing_en_instance_crn") : true # tflint-ignore: terraform_unused_declarations validate_endpoint = var.endpoint_type == "public" && var.allowed_network == "private-only" && var.existing_sm_instance_crn == null ? tobool("It is not allowed to have conflicting var.endpoint_type and var.allowed_network values.") : true # tflint-ignore: terraform_unused_declarations validate_region = var.existing_sm_instance_crn == null && var.region == null ? tobool("When existing_sm_instance_crn is null, a value must be passed for var.region") : true + # tflint-ignore: terraform_unused_declarations + validate_is_hpcs_key = var.is_hpcs_key && local.kms_service_name != "hs-crypto" ? tobool("When is_hpcs_key is set to true then the key provided through kms_key_crn must be a Hyper Protect Crypto Services key") : true } locals { @@ -34,7 +36,7 @@ data "ibm_resource_instance" "sm_instance" { # Create Secrets Manager Instance resource "ibm_resource_instance" "secrets_manager_instance" { count = var.existing_sm_instance_crn == null ? 1 : 0 - depends_on = [time_sleep.wait_for_authorization_policy] + depends_on = [time_sleep.wait_for_authorization_policy, time_sleep.wait_for_sm_hpcs_authorization_policy] name = var.secrets_manager_name service = "secrets-manager" plan = var.sm_service_plan @@ -43,7 +45,7 @@ resource "ibm_resource_instance" "secrets_manager_instance" { tags = var.sm_tags parameters = { "allowed_network" = var.allowed_network - "kms_instance" = var.existing_kms_instance_guid + "kms_instance" = local.kms_instance_guid "kms_key" = var.kms_key_crn } @@ -71,23 +73,68 @@ resource "ibm_iam_authorization_policy" "iam_groups_policy" { description = "Allows Secrets Manager instance ${local.secrets_manager_guid} `Groups Service Member Manage` access to the IAM Groups service to enable creating IAM credentials." } +####################################################################################################################### +# KMS Key +####################################################################################################################### locals { - # determine which service name to use for the policy - kms_service_name = var.kms_encryption_enabled && var.kms_key_crn != null ? ( - can(regex(".*kms.*", var.kms_key_crn)) ? "kms" : ( - can(regex(".*hs-crypto.*", var.kms_key_crn)) ? "hs-crypto" : null - ) - ) : null + create_kms_auth_policy = var.kms_encryption_enabled && !var.skip_kms_iam_authorization_policy && var.existing_sm_instance_crn == null + create_hpcs_auth_policy = local.create_kms_auth_policy == true && var.is_hpcs_key ? 1 : 0 + + kms_service_name = var.kms_encryption_enabled && var.kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : null + kms_account_id = var.kms_encryption_enabled && var.kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : null + kms_key_id = var.kms_encryption_enabled && var.kms_key_crn != null ? module.kms_key_crn_parser[0].resource : null + kms_instance_guid = var.kms_encryption_enabled && var.kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : null +} + +######################################################################################################################## +# Parse KMS info from CRN +######################################################################################################################## + +module "kms_key_crn_parser" { + count = local.create_kms_auth_policy ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.kms_key_crn } +# Create auth policy (scoped to exact KMS key) resource "ibm_iam_authorization_policy" "kms_policy" { - count = var.kms_encryption_enabled && !var.skip_kms_iam_authorization_policy && var.existing_sm_instance_crn == null ? 1 : 0 - source_service_name = "secrets-manager" - source_resource_group_id = var.resource_group_id - target_service_name = local.kms_service_name - target_resource_instance_id = var.existing_kms_instance_guid - roles = ["Reader"] - description = "Allow all Secrets Manager instances in the resource group ${var.resource_group_id} to read from the ${local.kms_service_name} instance GUID ${var.existing_kms_instance_guid}" + count = local.create_kms_auth_policy ? 1 : 0 + source_service_name = "secrets-manager" + source_resource_group_id = var.resource_group_id + roles = ["Reader"] + description = "Allow all Secrets Manager instances in the resource group ${var.resource_group_id} to read the ${local.kms_service_name} key ${local.kms_key_id} from the instance GUID ${local.kms_instance_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.kms_instance_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 + } + } # workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478 @@ -98,6 +145,24 @@ resource "time_sleep" "wait_for_authorization_policy" { create_duration = "30s" } +# if using HPCS ,create a second IAM authorization that assigns the Viewer platform access in Hyper Protect Crypto Services .[Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-mng-data#using-byok) +resource "ibm_iam_authorization_policy" "secrets_manager_hpcs_policy" { + count = local.create_hpcs_auth_policy + source_service_name = "secrets-manager" + source_resource_group_id = var.resource_group_id + target_service_name = local.kms_service_name + target_resource_instance_id = local.kms_instance_guid + roles = ["Viewer"] + description = "Allow all Secrets Manager instances in the resource group ${var.resource_group_id} viewer access to the ${local.kms_service_name} instance GUID ${local.kms_instance_guid}." +} + +# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478 +resource "time_sleep" "wait_for_sm_hpcs_authorization_policy" { + count = local.create_hpcs_auth_policy + depends_on = [ibm_iam_authorization_policy.secrets_manager_hpcs_policy] + + create_duration = "30s" +} locals { secrets_manager_guid = var.existing_sm_instance_crn != null ? local.existing_sm_guid : tolist(ibm_resource_instance.secrets_manager_instance[*].guid)[0] diff --git a/modules/fscloud/README.md b/modules/fscloud/README.md index 2c640fa3..fc02cb5d 100644 --- a/modules/fscloud/README.md +++ b/modules/fscloud/README.md @@ -50,8 +50,8 @@ No resources. | [cbr\_rules](#input\_cbr\_rules) | (list) List of CBR rules to create |
list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
operations = optional(list(object({
api_types = list(object({
api_type_id = string
}))
})))
})) | `[]` | no |
| [enable\_event\_notification](#input\_enable\_event\_notification) | Set this to true to enable lifecycle notifications for your Secrets Manager instance by connecting an Event Notifications service. When setting this to true, a value must be passed for `existing_en_instance_crn` variable. | `bool` | `false` | no |
| [existing\_en\_instance\_crn](#input\_existing\_en\_instance\_crn) | The CRN of the Event Notifications service to enable lifecycle notifications for your Secrets Manager instance. | `string` | `null` | no |
-| [existing\_kms\_instance\_guid](#input\_existing\_kms\_instance\_guid) | The GUID of the Key Management Service (KMS) instance in which the key specified in `kms_key_crn` is coming from. | `string` | n/a | yes |
| [existing\_sm\_instance\_crn](#input\_existing\_sm\_instance\_crn) | The CRN of an existing Secrets Manager instance. If not supplied, a new instance is created. | `string` | `null` | no |
+| [is\_hpcs\_key](#input\_is\_hpcs\_key) | Set to true if the key is hpcs, otherwise false. | `bool` | `false` | no |
| [kms\_key\_crn](#input\_kms\_key\_crn) | The root key CRN of Key Management Service (KMS) key that you want to use for encryption. | `string` | n/a | yes |
| [region](#input\_region) | The region to provision the Secrets Manager instance to. | `string` | n/a | yes |
| [resource\_group\_id](#input\_resource\_group\_id) | The ID of the resource group to provision the Secrets Manager instance to. | `string` | n/a | yes |
diff --git a/modules/fscloud/main.tf b/modules/fscloud/main.tf
index 47b6ba57..00e9535c 100644
--- a/modules/fscloud/main.tf
+++ b/modules/fscloud/main.tf
@@ -9,12 +9,12 @@ module "secrets_manager" {
allowed_network = "private-only"
endpoint_type = "private"
kms_encryption_enabled = true
- existing_kms_instance_guid = var.existing_kms_instance_guid
enable_event_notification = var.enable_event_notification
existing_en_instance_crn = var.existing_en_instance_crn
skip_iam_authorization_policy = var.skip_iam_authorization_policy
skip_en_iam_authorization_policy = var.skip_en_iam_authorization_policy
skip_kms_iam_authorization_policy = var.skip_kms_iam_authorization_policy
+ is_hpcs_key = var.is_hpcs_key
kms_key_crn = var.kms_key_crn
cbr_rules = var.cbr_rules
secrets = var.secrets
diff --git a/modules/fscloud/variables.tf b/modules/fscloud/variables.tf
index 9a116957..481de08f 100644
--- a/modules/fscloud/variables.tf
+++ b/modules/fscloud/variables.tf
@@ -50,17 +50,16 @@ variable "skip_kms_iam_authorization_policy" {
##############################################################################
# Key Management Service (KMS)
##############################################################################
-
-variable "existing_kms_instance_guid" {
- type = string
- description = "The GUID of the Key Management Service (KMS) instance in which the key specified in `kms_key_crn` is coming from."
-}
-
variable "kms_key_crn" {
type = string
description = "The root key CRN of Key Management Service (KMS) key that you want to use for encryption."
}
+variable "is_hpcs_key" {
+ type = bool
+ description = "Set to true if the key is hpcs, otherwise false."
+ default = false
+}
##############################################################################
# Event Notification
##############################################################################
diff --git a/outputs.tf b/outputs.tf
index 941dbdf2..769d593e 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -37,5 +37,4 @@ output "secrets" {
value = module.secrets.secrets
description = "List of secret mananger secret config data"
}
-
##############################################################################
diff --git a/solutions/standard/catalogValidationValues.json.template b/solutions/standard/catalogValidationValues.json.template
index 069d9f92..5a9fe734 100644
--- a/solutions/standard/catalogValidationValues.json.template
+++ b/solutions/standard/catalogValidationValues.json.template
@@ -3,5 +3,5 @@
"resource_group_name": $PREFIX,
"service_plan": "trial",
"existing_kms_instance_crn": $HPCS_US_SOUTH_CRN,
- "region": "ca-tor"
+ "region": "eu-de"
}
diff --git a/solutions/standard/main.tf b/solutions/standard/main.tf
index 640dbbe8..da932fdb 100644
--- a/solutions/standard/main.tf
+++ b/solutions/standard/main.tf
@@ -27,37 +27,111 @@ 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
- create_cross_account_auth_policy = !var.skip_kms_iam_authorization_policy && var.ibmcloud_kms_api_key != null
- kms_service_name = local.kms_key_crn != null ? (
- can(regex(".*kms.*", local.kms_key_crn)) ? "kms" : can(regex(".*hs-crypto.*", local.kms_key_crn)) ? "hs-crypto" : null
- ) : null
-}
+ parsed_service_name = var.existing_kms_instance_crn != null ? module.kms_instance_crn_parser[0].service_name : module.kms_key_crn_parser[0].service_name
+ is_hpcs_key = local.parsed_service_name == "hs-crypto" ? true : false
+
+ create_cross_account_auth_policy = var.existing_secrets_manager_crn == null && !var.skip_kms_iam_authorization_policy && var.ibmcloud_kms_api_key != null
+ create_cross_account_hpcs_auth_policy = local.create_cross_account_auth_policy == true && local.is_hpcs_key ? 1 : 0
+ kms_service_name = var.existing_secrets_manager_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name
+ kms_key_id = var.existing_secrets_manager_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms_instance_crn_parser[0].resource
+ kms_instance_guid = var.existing_secrets_manager_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance
+ kms_account_id = var.existing_secrets_manager_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id
+
+}
+# Lookup account ID
data "ibm_iam_account_settings" "iam_account_settings" {
count = local.create_cross_account_auth_policy ? 1 : 0
}
+########################################################################################################################
+# Parse KMS info from given CRNs
+########################################################################################################################
+
+module "kms_instance_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 "kms_key_crn_parser" {
+ count = var.existing_secrets_manager_kms_key_crn != null ? 1 : 0
+ source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
+ version = "1.1.0"
+ crn = var.existing_secrets_manager_kms_key_crn
+}
+
+# Create auth policy (scoped to exact KMS key)
resource "ibm_iam_authorization_policy" "kms_policy" {
- count = local.create_cross_account_auth_policy ? 1 : 0
+ count = local.create_cross_account_auth_policy ? 1 : 0
+ provider = ibm.kms
+ source_service_account = data.ibm_iam_account_settings.iam_account_settings[0].account_id
+ source_service_name = "secrets-manager"
+ source_resource_group_id = module.resource_group[0].resource_group_id
+ roles = ["Reader"]
+ description = "Allow all Secrets Manager instances in the resource group ${module.resource_group[0].resource_group_id} in the account ${data.ibm_iam_account_settings.iam_account_settings[0].account_id} to read the ${local.kms_service_name} key ${local.kms_key_id} from the instance GUID ${local.kms_instance_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.kms_instance_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
+ }
+
+}
+# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
+resource "time_sleep" "wait_for_authorization_policy" {
+ count = local.create_cross_account_auth_policy ? 1 : 0
+ depends_on = [ibm_iam_authorization_policy.kms_policy]
+ create_duration = "30s"
+}
+
+# if using HPCS ,create a second IAM authorization that assigns the Viewer platform access in Hyper Protect Crypto Services .[Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-mng-data#using-byok)
+resource "ibm_iam_authorization_policy" "secrets_manager_hpcs_policy" {
+ count = local.create_cross_account_hpcs_auth_policy
provider = ibm.kms
source_service_account = data.ibm_iam_account_settings.iam_account_settings[0].account_id
source_service_name = "secrets-manager"
source_resource_group_id = module.resource_group[0].resource_group_id
target_service_name = local.kms_service_name
- target_resource_instance_id = local.existing_kms_guid
- roles = ["Reader"]
- description = "Allow all Secrets Manager instances in the resource group ${module.resource_group[0].resource_group_id} in the account ${data.ibm_iam_account_settings.iam_account_settings[0].account_id} to read from the ${local.kms_service_name} instance GUID ${local.existing_kms_guid}"
+ target_resource_instance_id = local.kms_instance_guid
+ roles = ["Viewer"]
+ description = "Allow all Secrets Manager instances in the resource group ${module.resource_group[0].resource_group_id} in the account ${data.ibm_iam_account_settings.iam_account_settings[0].account_id} to view from the ${local.kms_service_name} instance GUID ${local.kms_instance_guid}"
}
# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
-resource "time_sleep" "wait_for_authorization_policy" {
- count = local.create_cross_account_auth_policy ? 1 : 0
- depends_on = [ibm_iam_authorization_policy.kms_policy]
+resource "time_sleep" "wait_for_sm_hpcs_authorization_policy" {
+ count = local.create_cross_account_hpcs_auth_policy
+ depends_on = [ibm_iam_authorization_policy.secrets_manager_hpcs_policy]
create_duration = "30s"
}
+
# KMS root key for Secrets Manager secret encryption
module "kms" {
providers = {
@@ -100,7 +174,7 @@ locals {
}
module "secrets_manager" {
- depends_on = [time_sleep.wait_for_authorization_policy]
+ depends_on = [time_sleep.wait_for_authorization_policy, time_sleep.wait_for_sm_hpcs_authorization_policy]
source = "../../modules/fscloud"
existing_sm_instance_crn = var.existing_secrets_manager_crn
resource_group_id = var.existing_secrets_manager_crn == null ? module.resource_group[0].resource_group_id : data.ibm_resource_instance.existing_sm[0].resource_group_id
@@ -108,8 +182,8 @@ module "secrets_manager" {
secrets_manager_name = try("${local.prefix}-${var.secrets_manager_instance_name}", var.secrets_manager_instance_name)
service_plan = var.service_plan
sm_tags = var.secrets_manager_tags
+ is_hpcs_key = local.is_hpcs_key
# kms dependency
- existing_kms_instance_guid = local.existing_kms_guid
kms_key_crn = local.kms_key_crn
skip_kms_iam_authorization_policy = var.skip_kms_iam_authorization_policy || local.create_cross_account_auth_policy
# event notifications dependency
diff --git a/variables.tf b/variables.tf
index 3bb88f14..11da4ec8 100644
--- a/variables.tf
+++ b/variables.tf
@@ -61,18 +61,18 @@ variable "skip_kms_iam_authorization_policy" {
default = false
}
-variable "existing_kms_instance_guid" {
- type = string
- description = "The GUID of the Hyper Protect Crypto Services or Key Protect instance in which the key specified in `kms_key_crn` is coming from. Required only if `kms_encryption_enabled` is set to true, and `skip_kms_iam_authorization_policy` is set to false."
- default = null
-}
-
variable "kms_key_crn" {
type = string
description = "The root key CRN of a Key Management Service like Key Protect or Hyper Protect Crypto Services (HPCS) that you want to use for encryption. Only used if `kms_encryption_enabled` is set to true."
default = null
}
+variable "is_hpcs_key" {
+ type = bool
+ description = "Set it to true if the key provided through the `kms_key_crn` is Hyper Protect Crypto Services key."
+ default = false
+}
+
variable "existing_sm_instance_crn" {
type = string
description = "An existing Secrets Manager instance CRN. If not provided an new instance will be provisioned."