Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ You need the following permissions to run this module.
| <a name="input_kms_key_crn"></a> [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 |
| <a name="input_region"></a> [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 |
| <a name="input_resource_group_id"></a> [resource\_group\_id](#input\_resource\_group\_id) | The ID of the resource group | `string` | n/a | yes |
| <a name="input_secrets"></a> [secrets](#input\_secrets) | Secret Manager secrets configurations. | <pre>list(object({<br/> secret_group_name = string<br/> secret_group_description = optional(string)<br/> existing_secret_group = optional(bool, false)<br/> secrets = optional(list(object({<br/> secret_name = string<br/> secret_description = optional(string)<br/> secret_type = optional(string)<br/> imported_cert_certificate = optional(string)<br/> imported_cert_private_key = optional(string)<br/> imported_cert_intermediate = optional(string)<br/> secret_username = optional(string)<br/> secret_labels = optional(list(string), [])<br/> secret_payload_password = optional(string, "")<br/> secret_auto_rotation = optional(bool, true)<br/> secret_auto_rotation_unit = optional(string, "day")<br/> secret_auto_rotation_interval = optional(number, 89)<br/> service_credentials_ttl = optional(string, "7776000") # 90 days<br/> service_credentials_source_service_crn = optional(string)<br/> service_credentials_source_service_role_crn = optional(string)<br/> })))<br/> }))</pre> | `[]` | no |
| <a name="input_secrets"></a> [secrets](#input\_secrets) | Secret Manager secrets configurations. | <pre>list(object({<br/> secret_group_name = string<br/> secret_group_description = optional(string)<br/> existing_secret_group = optional(bool, false)<br/> create_access_group = optional(bool, false)<br/> access_group_name = optional(string)<br/> access_group_roles = optional(list(string))<br/> access_group_tags = optional(list(string))<br/> secrets = optional(list(object({<br/> secret_name = string<br/> secret_description = optional(string)<br/> secret_type = optional(string)<br/> imported_cert_certificate = optional(string)<br/> imported_cert_private_key = optional(string)<br/> imported_cert_intermediate = optional(string)<br/> secret_username = optional(string)<br/> secret_labels = optional(list(string), [])<br/> secret_payload_password = optional(string, "")<br/> secret_auto_rotation = optional(bool, true)<br/> secret_auto_rotation_unit = optional(string, "day")<br/> secret_auto_rotation_interval = optional(number, 89)<br/> service_credentials_ttl = optional(string, "7776000") # 90 days<br/> service_credentials_source_service_crn = optional(string)<br/> service_credentials_source_service_role_crn = optional(string)<br/> })))<br/> }))</pre> | `[]` | no |
| <a name="input_secrets_manager_name"></a> [secrets\_manager\_name](#input\_secrets\_manager\_name) | The name of the Secrets Manager instance to create | `string` | n/a | yes |
| <a name="input_skip_en_iam_authorization_policy"></a> [skip\_en\_iam\_authorization\_policy](#input\_skip\_en\_iam\_authorization\_policy) | Set to true to skip the creation of an IAM authorization policy that permits all Secrets Manager instances (scoped to the resource group) an 'Event Source Manager' role to the given Event Notifications instance passed in the `existing_en_instance_crn` input variable. In addition, no policy is created if `enable_event_notification` is set to false. | `bool` | `false` | no |
| <a name="input_skip_iam_authorization_policy"></a> [skip\_iam\_authorization\_policy](#input\_skip\_iam\_authorization\_policy) | Whether to skip the creation of the IAM authorization policies required to enable the IAM credentials engine. If set to false, policies will be created that grants the Secrets Manager instance 'Operator' access to the IAM identity service, and 'Groups Service Member Manage' access to the IAM groups service. | `bool` | `false` | no |
Expand Down
34 changes: 20 additions & 14 deletions ibm_catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@
"key": "existing_resource_group_name",
"required": true,
"custom_config": {
"type": "resource_group",
"grouping": "deployment",
"original_grouping": "deployment",
"config_constraints": {
"identifier": "rg_name"
}
"type": "resource_group",
"grouping": "deployment",
"original_grouping": "deployment",
"config_constraints": {
"identifier": "rg_name"
}
}
},
{
Expand Down Expand Up @@ -169,7 +169,7 @@
"config_constraints": {
"type": "string"
}
}
}
},
{
"key": "service_plan",
Expand Down Expand Up @@ -252,6 +252,12 @@
},
{
"key": "secrets_manager_cbr_rules"
},
{
"key": "create_general_secret_group"
},
{
"key": "create_general_secret_group_access_group"
}
],
"architecture": {
Expand Down Expand Up @@ -401,7 +407,7 @@
"config_constraints": {
"type": "string"
}
}
}
},
{
"key": "service_plan",
Expand All @@ -423,12 +429,12 @@
"key": "existing_resource_group_name",
"required": true,
"custom_config": {
"type": "resource_group",
"grouping": "deployment",
"original_grouping": "deployment",
"config_constraints": {
"identifier": "rg_name"
}
"type": "resource_group",
"grouping": "deployment",
"original_grouping": "deployment",
"config_constraints": {
"identifier": "rg_name"
}
}
},
{
Expand Down
4 changes: 2 additions & 2 deletions modules/secrets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ module "secrets_manager" {

| Name | Source | Version |
|------|--------|---------|
| <a name="module_secret_groups"></a> [secret\_groups](#module\_secret\_groups) | terraform-ibm-modules/secrets-manager-secret-group/ibm | 1.2.3 |
| <a name="module_secret_groups"></a> [secret\_groups](#module\_secret\_groups) | terraform-ibm-modules/secrets-manager-secret-group/ibm | 1.3.2 |
| <a name="module_secrets"></a> [secrets](#module\_secrets) | terraform-ibm-modules/secrets-manager-secret/ibm | 1.7.0 |

### Resources
Expand All @@ -66,7 +66,7 @@ module "secrets_manager" {
| <a name="input_endpoint_type"></a> [endpoint\_type](#input\_endpoint\_type) | The service endpoint type to communicate with the provided secrets manager instance. Possible values are `public` or `private` | `string` | `"public"` | no |
| <a name="input_existing_sm_instance_guid"></a> [existing\_sm\_instance\_guid](#input\_existing\_sm\_instance\_guid) | Instance ID of Secrets Manager instance in which the Secret will be added. | `string` | n/a | yes |
| <a name="input_existing_sm_instance_region"></a> [existing\_sm\_instance\_region](#input\_existing\_sm\_instance\_region) | Region which the Secret Manager is deployed. | `string` | n/a | yes |
| <a name="input_secrets"></a> [secrets](#input\_secrets) | Secret Manager secrets configurations. | <pre>list(object({<br/> secret_group_name = string<br/> secret_group_description = optional(string)<br/> existing_secret_group = optional(bool, false)<br/> secrets = optional(list(object({<br/> secret_name = string<br/> secret_description = optional(string)<br/> secret_type = optional(string)<br/> imported_cert_certificate = optional(string)<br/> imported_cert_private_key = optional(string)<br/> imported_cert_intermediate = optional(string)<br/> secret_username = optional(string)<br/> secret_labels = optional(list(string), [])<br/> secret_payload_password = optional(string, "")<br/> secret_auto_rotation = optional(bool, true)<br/> secret_auto_rotation_unit = optional(string, "day")<br/> secret_auto_rotation_interval = optional(number, 89)<br/> service_credentials_ttl = optional(string, "7776000") # 90 days<br/> service_credentials_source_service_crn = optional(string)<br/> service_credentials_source_service_role_crn = optional(string)<br/> service_credentials_source_service_hmac = optional(bool, false)<br/> })))<br/> }))</pre> | `[]` | no |
| <a name="input_secrets"></a> [secrets](#input\_secrets) | Secret Manager secrets configurations. | <pre>list(object({<br/> secret_group_name = string<br/> secret_group_description = optional(string)<br/> existing_secret_group = optional(bool, false)<br/> create_access_group = optional(bool, false)<br/> access_group_name = optional(string)<br/> access_group_roles = optional(list(string))<br/> access_group_tags = optional(list(string))<br/> secrets = optional(list(object({<br/> secret_name = string<br/> secret_description = optional(string)<br/> secret_type = optional(string)<br/> imported_cert_certificate = optional(string)<br/> imported_cert_private_key = optional(string)<br/> imported_cert_intermediate = optional(string)<br/> secret_username = optional(string)<br/> secret_labels = optional(list(string), [])<br/> secret_payload_password = optional(string, "")<br/> secret_auto_rotation = optional(bool, true)<br/> secret_auto_rotation_unit = optional(string, "day")<br/> secret_auto_rotation_interval = optional(number, 89)<br/> service_credentials_ttl = optional(string, "7776000") # 90 days<br/> service_credentials_source_service_crn = optional(string)<br/> service_credentials_source_service_role_crn = optional(string)<br/> service_credentials_source_service_hmac = optional(bool, false)<br/> })))<br/> }))</pre> | `[]` | no |

### Outputs

Expand Down
14 changes: 11 additions & 3 deletions modules/secrets/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ locals {
secret_groups = flatten([
for secret_group in var.secrets :
secret_group.existing_secret_group ? [] : [{
secret_group_name = secret_group.secret_group_name
secret_group_description = secret_group.secret_group_description
secret_group_name = secret_group.secret_group_name
secret_group_description = secret_group.secret_group_description
secret_group_create_access_group = secret_group.create_access_group
secret_group_access_group_name = secret_group.access_group_name
secret_group_access_group_roles = secret_group.access_group_roles
secret_group_access_group_tags = secret_group.access_group_tags
}]
])
}
Expand All @@ -21,12 +25,16 @@ data "ibm_sm_secret_groups" "existing_secret_groups" {
module "secret_groups" {
for_each = { for obj in local.secret_groups : obj.secret_group_name => obj }
source = "terraform-ibm-modules/secrets-manager-secret-group/ibm"
version = "1.2.3"
version = "1.3.2"
region = var.existing_sm_instance_region
secrets_manager_guid = var.existing_sm_instance_guid
secret_group_name = each.value.secret_group_name
secret_group_description = each.value.secret_group_description
endpoint_type = var.endpoint_type
create_access_group = each.value.secret_group_create_access_group
access_group_name = each.value.secret_group_access_group_name
access_group_roles = each.value.secret_group_access_group_roles
access_group_tags = each.value.secret_group_access_group_tags
}

##############################################################################
Expand Down
11 changes: 11 additions & 0 deletions modules/secrets/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ variable "secrets" {
secret_group_name = string
secret_group_description = optional(string)
existing_secret_group = optional(bool, false)
create_access_group = optional(bool, false)
access_group_name = optional(string)
access_group_roles = optional(list(string))
access_group_tags = optional(list(string))
secrets = optional(list(object({
secret_name = string
secret_description = optional(string)
Expand Down Expand Up @@ -58,4 +62,11 @@ variable "secrets" {
true if(secret.secret_group_name == "default" && secret.existing_secret_group == false)
]) == 0
}
validation {
error_message = "When creating an access group, a list of roles must be specified."
condition = length([
for secret in var.secrets :
true if(secret.create_access_group && secret.access_group_roles == null)
]) == 0
}
}
3 changes: 3 additions & 0 deletions solutions/fully-configurable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This solution supports the following:
| <a name="module_kms_key_crn_parser"></a> [kms\_key\_crn\_parser](#module\_kms\_key\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 |
| <a name="module_resource_group"></a> [resource\_group](#module\_resource\_group) | terraform-ibm-modules/resource-group/ibm | 1.1.6 |
| <a name="module_secrets_manager"></a> [secrets\_manager](#module\_secrets\_manager) | ../.. | n/a |
| <a name="module_secrets_manager_group"></a> [secrets\_manager\_group](#module\_secrets\_manager\_group) | terraform-ibm-modules/secrets-manager-secret-group/ibm | 1.3.2 |

### Resources

Expand All @@ -48,6 +49,8 @@ This solution supports the following:
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allowed_network"></a> [allowed\_network](#input\_allowed\_network) | The types of service endpoints to set on the Secrets Manager instance. Possible values are `private-only` or `public-and-private`. | `string` | `"private-only"` | no |
| <a name="input_create_general_secret_group"></a> [create\_general\_secret\_group](#input\_create\_general\_secret\_group) | Whether to create a secret group named 'General' in your Secrets Manager instance. | `bool` | `true` | no |
| <a name="input_create_general_secret_group_access_group"></a> [create\_general\_secret\_group\_access\_group](#input\_create\_general\_secret\_group\_access\_group) | Whether to create an access group with 'SecretsReader' access to the 'General' secret group. | `bool` | `true` | no |
| <a name="input_event_notifications_email_list"></a> [event\_notifications\_email\_list](#input\_event\_notifications\_email\_list) | The list of email address to target out when Secrets Manager triggers an event | `list(string)` | `[]` | no |
| <a name="input_event_notifications_from_email"></a> [event\_notifications\_from\_email](#input\_event\_notifications\_from\_email) | The email address used to send any Secrets Manager event coming via Event Notifications | `string` | `"[email protected]"` | no |
| <a name="input_event_notifications_reply_to_email"></a> [event\_notifications\_reply\_to\_email](#input\_event\_notifications\_reply\_to\_email) | The email address specified in the 'reply\_to' section for any Secret Manager event coming via Event Notifications | `string` | `"[email protected]"` | no |
Expand Down
17 changes: 17 additions & 0 deletions solutions/fully-configurable/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ locals {
secrets_manager_guid = var.existing_secrets_manager_crn != null ? (length(local.parsed_existing_secrets_manager_crn) > 0 ? local.parsed_existing_secrets_manager_crn[7] : null) : module.secrets_manager.secrets_manager_guid
secrets_manager_crn = var.existing_secrets_manager_crn != null ? var.existing_secrets_manager_crn : module.secrets_manager.secrets_manager_crn
secrets_manager_region = var.existing_secrets_manager_crn != null ? (length(local.parsed_existing_secrets_manager_crn) > 0 ? local.parsed_existing_secrets_manager_crn[5] : null) : module.secrets_manager.secrets_manager_region
secrets_manager_endpoint_type = var.existing_secrets_manager_crn != null ? (length(local.parsed_existing_secrets_manager_crn) > 0 ? local.parsed_existing_secrets_manager_crn[3] : null) : var.secrets_manager_endpoint_type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a variable for this var.secrets_manager_endpoint_type

enable_event_notifications = var.existing_event_notifications_instance_crn != null ? true : false
}

Expand Down Expand Up @@ -194,6 +195,22 @@ data "ibm_resource_instance" "existing_sm" {
identifier = var.existing_secrets_manager_crn
}

module "secrets_manager_group" {
depends_on = [module.secrets_manager]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the explicit depends_on? Its a bad practise, there is already an implicit dependency by passing the guid to this module

count = var.create_general_secret_group ? 1 : 0
source = "terraform-ibm-modules/secrets-manager-secret-group/ibm"
version = "1.3.2"
region = local.secrets_manager_region
secrets_manager_guid = local.secrets_manager_guid
#tfsec:ignore:general-secrets-no-plaintext-exposure
secret_group_name = "General" #checkov:skip=CKV_SECRET_6: does not require high entropy string as is static value
secret_group_description = "Initially created secret group" #tfsec:ignore:general-secrets-no-plaintext-exposure
create_access_group = var.create_general_secret_group_access_group
access_group_name = "${var.prefix}-General-secrets-group-access-group"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefix is optional (it can be null). Ensure to account for this like we do everywhere else prefix is used

access_group_roles = ["SecretsReader"]
endpoint_type = local.secrets_manager_endpoint_type
}

#######################################################################################################################
# Secrets Manager Event Notifications Configuration
#######################################################################################################################
Expand Down
12 changes: 12 additions & 0 deletions solutions/fully-configurable/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ variable "allowed_network" {
}
}

variable "create_general_secret_group" {
type = bool
description = "Whether to create a secret group named 'General' in your Secrets Manager instance."
default = true
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this has to be set to nullable = false since there is a for loop used here. You should add it to the secrets input in both the root module and submodule too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ocofaigh Is it possible to set one field inside the variable as not nullable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, but the whole variable should be set to nullable = false because the for loop would fail if it was null. Use would just pass [] if they didnt wan't to create any groups


variable "create_general_secret_group_access_group" {
type = bool
description = "Whether to create an access group with 'SecretsReader' access to the 'General' secret group."
default = true
}

########################################################################################################################
# Key Protect
########################################################################################################################
Expand Down
Loading