Skip to content

Commit

Permalink
feat: support to create service credentials in secrets manager (#687)…
Browse files Browse the repository at this point in the history
…<br>This enhancement will enable users to create service credentials in an existing secrets manager for a COS instance. Users can choose to use an existing secret group or create a new one for the service credentials.

* support to create service credentials in secrets manager
  • Loading branch information
Soaib024 authored Aug 5, 2024
1 parent 15c287d commit b10af71
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 38 deletions.
12 changes: 11 additions & 1 deletion .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "go.sum|^.secrets.baseline$",
"lines": null
},
"generated_at": "2024-07-04T15:46:18Z",
"generated_at": "2024-08-01T14:50:58Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -123,6 +123,16 @@
"verified_result": null
}
],
"solutions/instance/DA-types.md": [
{
"hashed_secret": "1e5c2f367f02e47a8c160cda1cd9d91decbac441",
"is_secret": false,
"is_verified": false,
"line_number": 99,
"type": "Secret Keyword",
"verified_result": null
}
],
"tests/pr_test.go": [
{
"hashed_secret": "3e4bdbe0b80e63c22b178576e906810777387b50",
Expand Down
33 changes: 0 additions & 33 deletions solutions/instance/DA-resource-keys.md

This file was deleted.

111 changes: 111 additions & 0 deletions solutions/instance/DA-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Configuring complex inputs in IBM Cloud Object Storage in IBM Cloud projects
Several optional input variables in the IBM Cloud Object Storage [deployable architecture](https://cloud.ibm.com/catalog#deployable_architecture) use complex object types. You specify these inputs when you configure your deployable architecture.

- [Resource keys](#resource-keys) (`resource_keys`)
- [Service credential secrets](#service-credential-secrets) (`service_credential_secrets`)

## Resource keys <a name="resource-keys"></a>
When you add an IBM Cloud Object Storage service from the IBM Cloud catalog to an IBM Cloud Projects service, you can configure resource keys. In the edit mode for the projects configuration, select the Configure panel and then click the optional tab.

In the configuration, specify the name of the resource key, whether HMAC credentials should be included, the Role of the key and an optional Service ID CRN to create with a Service ID.

To enter a custom value, use the edit action to open the "Edit Array" panel. Add the resource key configurations to the array here.

[Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_key) about resource keys.

- Variable name: `resource_keys`.
- Type: A list of objects that represent a resource key
- Default value: An empty list (`[]`)

### Options for resource_key

- `name` (required): A unique human-readable name that identifies this resource key.
- `generate_hmac_credentials` (optional, default = `false`): Set to true to include COS HMAC keys in the resource key. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_key#example-to-create-by-using-hmac).
- `role` (optional, default = `Reader`): The name of the user role.
- `service_id_crn` (optional, default = `null`): Pass a Service ID CRN to create credentials for a resource with a Service ID. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_key#example-to-create-by-using-serviceid).

The following example includes all the configuration options for two resource keys. One is a key with a `Reader` role, the other with a `Writer` role.
```hcl
[
{
"name": "da-reader-resource-key",
"generate_hmac_credentials": "false",
"role": "Reader",
"service_id_crn": null
},
{
"name": "da-writer-resource-key",
"role": "Writer"
}
]
```

## Service credential secrets <a name="service-credential-secrets"></a>
When you add an IBM Cloud Object Storage service from the IBM Cloud catalog to an IBM Cloud Projects service, you can configure service credentials. In the edit mode for the projects configuration, select the Configure panel and then click the optional tab.

In the configuration, specify the secret group name, whether it already exists or will be created and include all the necessary service credential secrets that need to be created within that secret group.

To enter a custom value, use the edit action to open the "Edit Array" panel. Add the service credential secrets configurations to the array here.

[Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/sm_service_credentials_secret) about service credential secrets.

- Variable name: `service_credential_secrets`.
- Type: A list of objects that represent a service credential secret groups and secrets
- Default value: An empty list (`[]`)

### Options for service_credential_secrets

- `secret_group_name` (required): A unique human-readable name that identifies this service credential secret group.
- `secret_group_description` (optional, default = `null`): A human-readable description for this secret group.
- `existing_secret_group`: (optional, default = `false`): Set to true, if secret group name provided in the variable `secret_group_name` already exists.
- `service_credentials`: (optional, default = `[]`): A list of object that represents a service credential secret.

### Options for service_credentials

- `secret_name`: (required): A unique human-readable name of the secret to create.
- `service_credentials_source_service_role`: (required): The role to give the service credential in the COS service. Acceptable values are `Reader`, `Writer`, `Manager`, `Content Reader`, `Object Reader`, `Object Writer`, `NONE`
- `secret_labels`: (optional, default = `[]`): Labels of the secret to create. Up to 30 labels can be created. Labels can be 2 - 30 characters, including spaces. Special characters that are not permitted include the angled brackets (<>), comma (,), colon (:), ampersand (&), and vertical pipe character (|).
- `secret_auto_rotation`: (optional, default = `true`): Whether to configure automatic rotation of service credential.
- `secret_auto_rotation_unit`: (optional, default = `day`): Specifies the unit of time for rotation of a secret. Acceptable values are `day` or `month`.
- `secret_auto_rotation_interval`: (optional, default = `89`): Specifies the rotation interval for the rotation unit.
- `service_credentials_ttl`: (optional, default = `7776000`): The time-to-live (TTL) to assign to generated service credentials (in seconds).
- `service_credential_secret_description`: (optional, default = `null`): Description of the secret to create.

The following example includes all the configuration options for four service credentials and two secret groups.
```hcl
[
{
"secret_group_name": "sg-1"
"existing_secret_group": true
"service_credentials": [
{
"secret_name": "cred-1"
"service_credentials_source_service_role": "Reader"
"secret_labels": ["test-reader-1", "test-reader-2"]
"secret_auto_rotation": true
"secret_auto_rotation_unit": "day"
"secret_auto_rotation_interval": 89
"service_credentials_ttl": 7776000
"service_credential_secret_description": "sample description"
},
{
"secret_name": "cred-2"
"service_credentials_source_service_role": "Writer"
}
]
},
{
"secret_group_name": "sg-2"
"service_credentials": [
{
"secret_name": "cred-3"
"service_credentials_source_service_role": "Manager"
},
{
"secret_name": "cred-4"
"service_credentials_source_service_role": "Content Reader"
}
]
}
]
```
54 changes: 54 additions & 0 deletions solutions/instance/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,57 @@ module "cos" {
cos_tags = var.cos_tags
access_tags = var.access_tags
}

resource "ibm_iam_authorization_policy" "policy" {
count = var.skip_cos_kms_auth_policy ? 0 : 1
depends_on = [module.cos]
source_service_name = "secrets-manager"
source_resource_instance_id = local.existing_secrets_manager_instance_guid
target_service_name = "cloud-object-storage"
target_resource_instance_id = module.cos.cos_instance_guid
roles = ["Key Manager"]
}

# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
resource "time_sleep" "wait_for_cos_authorization_policy" {
depends_on = [ibm_iam_authorization_policy.policy]
create_duration = "30s"
}

locals {
service_credential_secrets = [
for service_credentials in var.service_credential_secrets : {
secret_group_name = service_credentials.secret_group_name
secret_group_description = service_credentials.secret_group_description
existing_secret_group = service_credentials.existing_secret_group
secrets = [
for secret in service_credentials.service_credentials : {
secret_name = secret.secret_name
secret_labels = secret.secret_labels
secret_auto_rotation = secret.secret_auto_rotation
secret_auto_rotation_unit = secret.secret_auto_rotation_unit
secret_auto_rotation_interval = secret.secret_auto_rotation_interval
service_credentials_ttl = secret.service_credentials_ttl
service_credential_secret_description = secret.service_credential_secret_description
service_credentials_source_service_role = secret.service_credentials_source_service_role
service_credentials_source_service_crn = module.cos.cos_instance_id
secret_type = "service_credentials" #checkov:skip=CKV_SECRET_6
}
]
}
]

existing_secrets_manager_instance_crn_split = var.existing_secrets_manager_instance_crn != null ? split(":", var.existing_secrets_manager_instance_crn) : null
existing_secrets_manager_instance_guid = var.existing_secrets_manager_instance_crn != null ? element(local.existing_secrets_manager_instance_crn_split, length(local.existing_secrets_manager_instance_crn_split) - 3) : null
existing_secrets_manager_instance_region = var.existing_secrets_manager_instance_crn != null ? element(local.existing_secrets_manager_instance_crn_split, length(local.existing_secrets_manager_instance_crn_split) - 5) : null
}

module "secrets_manager_service_credentials" {
depends_on = [time_sleep.wait_for_cos_authorization_policy]
source = "terraform-ibm-modules/secrets-manager/ibm//modules/secrets"
version = "1.16.1"
existing_sm_instance_guid = local.existing_secrets_manager_instance_guid
existing_sm_instance_region = local.existing_secrets_manager_instance_region
endpoint_type = var.existing_secrets_manager_endpoint_type
secrets = local.service_credential_secrets
}
10 changes: 10 additions & 0 deletions solutions/instance/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ output "resource_keys" {
value = module.cos.resource_keys
sensitive = true
}

output "service_credential_secrets" {
description = "Service credential secrets"
value = module.secrets_manager_service_credentials.secrets
}

output "service_credential_secret_groups" {
description = "Service credential secret groups"
value = module.secrets_manager_service_credentials.secret_groups
}
59 changes: 58 additions & 1 deletion solutions/instance/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ variable "resource_group_name" {
}

variable "resource_keys" {
description = "The definition of the resource keys to generate. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-cos/tree/main/solutions/instance/DA-resource-keys.md)."
description = "The definition of the resource keys to generate. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-cos/tree/main/solutions/instance/DA-types.md#resource-keys)."
type = list(object({
name = string
generate_hmac_credentials = optional(bool, false)
Expand Down Expand Up @@ -56,3 +56,60 @@ variable "access_tags" {
description = "A list of access tags to apply to the Object Storage instance created by the module. [Learn more](https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial)."
default = []
}

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 COS instance."
}

variable "existing_secrets_manager_endpoint_type" {
type = string
description = "The endpoint type to use if `existing_secrets_manager_instance_crn` is specified. Possible values: public, private."
default = "private"
validation {
condition = contains(["public", "private"], var.existing_secrets_manager_endpoint_type)
error_message = "Only \"public\" and \"private\" are allowed values for 'existing_secrets_endpoint_type'."
}
}

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 = 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 COS. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-cos/tree/main/solutions/instance/DA-types.md#service-credential-secrets)."

validation {
# Service roles (for Cloud Object Storage) https://cloud.ibm.com/iam/roles
# Reader, Writer, Manager, Content Reader, Object Reader, Object Writer, NONE
condition = alltrue([
for group in var.service_credential_secrets : alltrue([
for credential in group.service_credentials : contains(
["Writer", "Reader", "Manager", "Content Reader", "Object Reader", "Object Writer", "NONE"], credential.service_credentials_source_service_role
)
])
])
error_message = "service_credentials_source_service_role role must be one of 'Writer', 'Reader', 'Manager', 'Content Reader', 'Object Reader', 'Object Writer', 'NONE', reference https://cloud.ibm.com/iam/roles and `Cloud Object Storage`"

}
}

variable "skip_cos_kms_auth_policy" {
type = bool
default = false
description = "Whether an IAM authorization policy is created for Secrets Manager instance to create a service credential secrets for Cloud Object Storage. Set to `true` to use an existing policy."
}
4 changes: 4 additions & 0 deletions solutions/instance/version.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ terraform {
source = "IBM-Cloud/ibm"
version = "1.67.1"
}
time = {
source = "hashicorp/time"
version = ">= 0.9.1"
}
}
}
21 changes: 19 additions & 2 deletions tests/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,25 @@ func TestRunSolutions(t *testing.T) {

instanceOptions := setupOptions(t, prefix, solutionInstanceDir)
instanceOptions.TerraformVars = map[string]interface{}{
"cos_instance_name": prefix,
"resource_group_name": fmt.Sprintf("%s-resource-group", prefix),
"cos_instance_name": prefix,
"resource_group_name": fmt.Sprintf("%s-resource-group", prefix),
"existing_secrets_manager_instance_crn": permanentResources["secretsManagerCRN"],
"existing_secrets_manager_endpoint_type": "public",
"service_credential_secrets": []map[string]interface{}{
{
"secret_group_name": fmt.Sprintf("%s-secret-group", prefix),
"service_credentials": []map[string]string{
{
"secret_name": fmt.Sprintf("%s-cred-manager", prefix),
"service_credentials_source_service_role": "Manager",
},
{
"secret_name": fmt.Sprintf("%s-cred-writer", prefix),
"service_credentials_source_service_role": "Writer",
},
},
},
},
}
instanceOptions.SkipTestTearDown = true
output, err := instanceOptions.RunTestConsistency()
Expand Down
2 changes: 1 addition & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ variable "resource_keys" {
condition = alltrue([
for key in var.resource_keys : contains(["Writer", "Reader", "Manager", "Content Reader", "Object Reader", "Object Writer", "NONE"], key.role)
])
error_message = "resource_keys role must be one of 'Writer', 'Reader', 'Manager', 'Content Reader', 'Onject Reader', 'Object Writer', 'NONE', reference https://cloud.ibm.com/iam/roles and `Cloud Object Storage`"
error_message = "resource_keys role must be one of 'Writer', 'Reader', 'Manager', 'Content Reader', 'Object Reader', 'Object Writer', 'NONE', reference https://cloud.ibm.com/iam/roles and `Cloud Object Storage`"
}
}

Expand Down

0 comments on commit b10af71

Please sign in to comment.