Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: resource keys and service credentials #255

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
21 changes: 21 additions & 0 deletions ibm_catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,27 @@
},
{
"key": "metrics_router_routes"
},
{
"key": "cloud_logs_resource_keys"
},
{
"key": "cloud_logs_service_credential_secrets"
},
{
"key": "cloud_monitoring_resource_keys"
},
{
"key": "cloud_monitoring_service_credential_secrets"
},
{
"key": "existing_secrets_manager_endpoint_type"
},
{
"key": "existing_secrets_manager_instance_crn"
},
{
"key": "skip_secrets_manager_auth_policy"
}
],
"architecture": {
Expand Down
108 changes: 108 additions & 0 deletions solutions/instances/DA-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Several optional input variables in the IBM Cloud [Observability instances deplo
* Metrics Router Routes (`metrics_router_routes`)
* Activity Tracker Event Routing COS bucket retention policy (`at_cos_bucket_retention_policy`)
* Cloud Logs data bucket retention policy(`cloud_log_data_bucket_retention_policy`)
* [Resource keys](#resource-keys) (`resource_keys`)
* [Service credential secrets](#service-credential-secrets) (`service_credential_secrets`)


## Cloud Logs Event Notification Instances <a name="cloud_logs_existing_en_instances"></a>
Expand Down Expand Up @@ -186,3 +188,109 @@ cloud_log_data_bucket_retention_policy = {
permanent = false
}
```

## Resource keys <a name="resource-keys"></a>
When you add an IBM Cloud Logs or IBM Cloud Monitoring services from the IBM Cloud catalog to an IBM Cloud Projects service, you can configure resource keys via the cloud_logs_resource_keys and cloud_monitoring_resource_keys inputs. 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: `cloud_logs_resource_keys` and `cloud_monitoring_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 Logs or IBM Cloud Monitoring services 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: `cloud_monitoring_service_credential_secrets` and `cloud_logs_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_crn`: (required): The CRN of the role to give the service credential in the COS service. Service credentials role CRNs can be found at https://cloud.ibm.com/iam/roles, select Cloud Object Storage and select the role.
- `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": [ # pragma: allowlist secret
{
"secret_name": "cred-1"
"service_credentials_source_service_role_crn": "crn:v1:bluemix:public:iam::::serviceRole: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_crn": "crn:v1:bluemix:public:iam::::serviceRole:Writer"
}
]
},
{
"secret_group_name": "sg-2"
"service_credentials": [ # pragma: allowlist secret
{
"secret_name": "cred-3"
"service_credentials_source_service_role_crn": "crn:v1:bluemix:public:iam::::serviceRole:Manager"
},
{
"secret_name": "cred-4"
"service_credentials_source_service_role_crn": "crn:v1:bluemix:public:cloud-object-storage::::serviceRole:ContentReader"
}
]
}
]
```
163 changes: 163 additions & 0 deletions solutions/instances/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,166 @@ module "cos_bucket" {
}
]
}

########################################################################################################################
# Resource keys and service credentials for Cloud Logs
########################################################################################################################

module "secrets_manager_instance_crn_parser" {
count = var.existing_secrets_manager_instance_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.1.0"
crn = var.existing_secrets_manager_instance_crn
}

module "cloud_logs_instance_crn_parser" {
count = var.cloud_logs_provision ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.1.0"
crn = module.observability_instance.cloud_logs_crn
}

resource "ibm_resource_key" "cloud_logs_resource_keys" {
for_each = { for key in var.cloud_logs_resource_keys : key.name => key }
name = each.value.key_name == null ? each.key : each.value.key_name
resource_instance_id = module.cloud_logs_instance_crn_parser[0].service_instance
role = each.value.role
parameters = {
"serviceid_crn" = each.value.service_id_crn
"HMAC" = each.value.generate_hmac_credentials
}
}

locals {
cloud_logs_service_credential_secrets = [
for service_credentials in var.cloud_logs_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_crn = secret.service_credentials_source_service_role_crn
service_credentials_source_service_crn = module.observability_instance.cloud_logs_crn
secret_type = "service_credentials" #checkov:skip=CKV_SECRET_6
}
]
}
]

# tflint-ignore: terraform_unused_declarations
validate_logs_sm_crn = length(var.cloud_logs_service_credential_secrets) > 0 && var.existing_secrets_manager_instance_crn == null ? tobool("`existing_secrets_manager_instance_crn` is required when adding service credentials as a secrets manager secret.") : false
}

resource "ibm_iam_authorization_policy" "cloud_logs_key_manager" {
count = var.skip_secrets_manager_auth_policy || var.existing_secrets_manager_instance_crn == null ? 0 : 1
depends_on = [module.observability_instance]
source_service_name = "secrets-manager"
source_resource_instance_id = module.secrets_manager_instance_crn_parser[0].service_instance
target_service_name = "cloud-logs"
target_resource_instance_id = module.observability_instance.cloud_logs_crn
roles = ["Key Manager"]
description = "Allow Secrets Manager with instance id ${module.secrets_manager_instance_crn_parser[0].service_instance} to manage key for the Cloud logs instance"
}

# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
resource "time_sleep" "wait_for_cloud_logs_authorization_policy" {
count = var.skip_secrets_manager_auth_policy || var.existing_secrets_manager_instance_crn == null ? 0 : 1
depends_on = [ibm_iam_authorization_policy.cloud_logs_key_manager]
create_duration = "30s"
}

module "cloud_logs_secrets_manager_service_credentials" {
count = length(local.cloud_logs_service_credential_secrets) > 0 ? 1 : 0
depends_on = [time_sleep.wait_for_cloud_logs_authorization_policy]
source = "terraform-ibm-modules/secrets-manager/ibm//modules/secrets"
version = "1.22.0"
existing_sm_instance_guid = module.secrets_manager_instance_crn_parser[0].service_instance
existing_sm_instance_region = module.secrets_manager_instance_crn_parser[0].region
endpoint_type = var.existing_secrets_manager_endpoint_type
secrets = local.cloud_logs_service_credential_secrets
}

########################################################################################################################
# Resource keys and service credentials for Cloud Monitoring
########################################################################################################################

module "cloud_monitoring_instance_crn_parser" {
count = var.cloud_monitoring_provision ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.1.0"
crn = module.observability_instance.cloud_monitoring_crn
}

resource "ibm_resource_key" "cloud_monitoring_resource_keys" {
for_each = { for key in var.cloud_monitoring_resource_keys : key.name => key }
name = each.value.key_name == null ? each.key : each.value.key_name
resource_instance_id = module.cloud_monitoring_instance_crn_parser[0].service_instance
role = each.value.role
parameters = {
"serviceid_crn" = each.value.service_id_crn
"HMAC" = each.value.generate_hmac_credentials
}
}

locals {
cloud_monitoring_service_credential_secrets = [
for service_credentials in var.cloud_monitoring_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_unit = secret.secret_auto_rotation_unit
secret_auto_rotation = secret.secret_auto_rotation
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_crn = secret.service_credentials_source_service_role_crn
service_credentials_source_service_crn = module.observability_instance.cloud_monitoring_crn
secret_type = "service_credentials" #checkov:skip=CKV_SECRET_6
}
]
}
]

# tflint-ignore: terraform_unused_declarations
validate_monitoring_sm_crn = length(var.cloud_monitoring_service_credential_secrets) > 0 && var.existing_secrets_manager_instance_crn == null ? tobool("`existing_secrets_manager_instance_crn` is required when adding service credentials as a secrets manager secret.") : false
}

resource "ibm_iam_authorization_policy" "cloud_monitoring_key_manager" {
count = var.skip_secrets_manager_auth_policy || var.existing_secrets_manager_instance_crn == null ? 0 : 1
depends_on = [module.observability_instance]
source_service_name = "secrets-manager"
source_resource_instance_id = module.secrets_manager_instance_crn_parser[0].service_instance
target_service_name = "cloud-monitoring"
target_resource_instance_id = module.cloud_monitoring_instance_crn_parser[0].service_instance
roles = ["Key Manager"]
description = "Allow Secrets Manager with instance id ${module.secrets_manager_instance_crn_parser[0].service_instance} to manage key for the Cloud monitoring instance"
}

# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
resource "time_sleep" "wait_for_cloud_monitoring_authorization_policy" {
count = var.skip_secrets_manager_auth_policy || var.existing_secrets_manager_instance_crn == null ? 0 : 1
depends_on = [ibm_iam_authorization_policy.cloud_monitoring_key_manager[0]]
create_duration = "30s"
}

module "cloud_monitoring_secrets_manager_service_credentials" {
count = length(local.cloud_monitoring_service_credential_secrets) > 0 ? 1 : 0
depends_on = [time_sleep.wait_for_cloud_monitoring_authorization_policy]
source = "terraform-ibm-modules/secrets-manager/ibm//modules/secrets"
version = "1.22.0"
existing_sm_instance_guid = module.secrets_manager_instance_crn_parser[0].service_instance
existing_sm_instance_region = module.secrets_manager_instance_crn_parser[0].region
endpoint_type = var.existing_secrets_manager_endpoint_type
secrets = local.cloud_monitoring_service_credential_secrets
}
23 changes: 23 additions & 0 deletions solutions/instances/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,26 @@ output "metrics_router_routes" {
description = "The map of created metrics routing routes."
value = var.enable_metrics_routing_to_cloud_monitoring ? module.observability_instance.metrics_router_routes : null
}

## Resource keys and service credentials
output "cloud_monitoring_resource_keys" {
description = "List of resource keys"
value = resource.ibm_resource_key.cloud_monitoring_resource_keys
sensitive = true
}

output "cloud_logs_resource_keys" {
description = "List of resource keys"
value = resource.ibm_resource_key.cloud_logs_resource_keys
sensitive = true
}

output "cloud_monitoring_service_credential_secrets" {
description = "Service credential secrets"
value = length(local.cloud_monitoring_service_credential_secrets) > 0 ? module.cloud_monitoring_secrets_manager_service_credentials[0].secrets : null
}

output "cloud_logs_service_credential_secrets" {
description = "Service credential secrets"
value = length(local.cloud_logs_service_credential_secrets) > 0 ? module.cloud_logs_secrets_manager_service_credentials[0].secrets : null
}
Loading