diff --git a/README.md b/README.md index e0d7984..05b8175 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This module configures an IBM Cloud Security and Compliance instance. * [terraform-ibm-scc](#terraform-ibm-scc) * [Submodules](./modules) * [attachment](./modules/attachment) + * [profile](./modules/profile) * [Examples](./examples) * [Basic example](./examples/basic) * [Complete example with CBR rules](./examples/complete) @@ -54,9 +55,6 @@ You need the following permissions to run this module. - Account Management - Security and Compliance Center service - `Administrator` platform access -- IAM Services - - Event Notifications service - - `Manager` service access @@ -66,7 +64,7 @@ You need the following permissions to run this module. | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.3.0 | -| [ibm](#requirement\_ibm) | >=1.64.1, <2.0.0 | +| [ibm](#requirement\_ibm) | >=1.65.1, <2.0.0 | | [time](#requirement\_time) | >= 0.9.1, <1.0.0 | ### Modules diff --git a/examples/basic/version.tf b/examples/basic/version.tf index d2c4a2c..e4b3c27 100644 --- a/examples/basic/version.tf +++ b/examples/basic/version.tf @@ -3,7 +3,7 @@ terraform { required_providers { ibm = { source = "IBM-Cloud/ibm" - version = ">= 1.66.0" + version = "1.66.0" } } } diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 7f9fb9f..11ca37c 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -88,6 +88,47 @@ module "create_scc_instance" { ] } +############################################################################## +# SCC custom profile +############################################################################## + +module "create_scc_profile" { + source = "../../modules/profile/." + instance_id = module.create_scc_instance.guid + controls = [ + # Apply 3 controls from IBM Cloud Framework for Financial Services control library version 1.6.0 + { + control_library_name = "IBM Cloud Framework for Financial Services", + control_library_version = "1.6.0" + control_name_list = [ + "AC", + "AC-1", + "AC-1(a)", + ] + }, + # Apply 4 controls from CIS IBM Cloud Foundations Benchmark control library version 1.0.0 + { + control_library_name = "CIS IBM Cloud Foundations Benchmark", + control_library_version = "1.0.0" + control_name_list = [ + "1.16", + "1.18", + "1.19", + "1.4", + ] + }, + # Apply all controls from SOC 2 control library version 1.0.0 + { + control_library_name = "SOC 2", + control_library_version = "1.0.0" + add_all_controls = true + }, + ] + profile_name = "${var.prefix}-profile" + profile_description = "scc-custom" + profile_version = "1.0.0" +} + ############################################################################## # SCC attachment ############################################################################## diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 19063db..677115c 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -53,14 +53,14 @@ output "cos_bucket" { depends_on = [module.create_scc_instance] } -output "scc_profile_attachment_id" { - description = "SCC profile attachment ID" - value = module.create_profile_attachment.id +output "profile_id" { + description = "The id of the SCC profile created by this module" + value = module.create_scc_profile.profile_id } -output "scc_profile_attachment_parameters" { +output "scc_profile_attachment_id" { description = "SCC profile attachment ID" - value = module.create_profile_attachment.attachment_parameters + value = module.create_profile_attachment.id } output "wp_crn" { diff --git a/examples/complete/version.tf b/examples/complete/version.tf index 5414c79..8419754 100644 --- a/examples/complete/version.tf +++ b/examples/complete/version.tf @@ -6,7 +6,7 @@ terraform { required_providers { ibm = { source = "IBM-Cloud/ibm" - version = ">= 1.64.1" + version = ">= 1.65.1" } } } diff --git a/modules/attachment/README.md b/modules/attachment/README.md index d5370e8..b69c0ec 100644 --- a/modules/attachment/README.md +++ b/modules/attachment/README.md @@ -38,7 +38,7 @@ module "create_scc_profile_attachment " { | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.3.0 | -| [ibm](#requirement\_ibm) | >=1.64.1, <2.0.0 | +| [ibm](#requirement\_ibm) | >=1.65.1, <2.0.0 | ### Modules diff --git a/modules/attachment/version.tf b/modules/attachment/version.tf index 2eafbc3..cf044bd 100644 --- a/modules/attachment/version.tf +++ b/modules/attachment/version.tf @@ -4,7 +4,7 @@ terraform { required_providers { ibm = { source = "IBM-Cloud/ibm" - version = ">=1.64.1, <2.0.0" + version = ">=1.65.1, <2.0.0" } } } diff --git a/modules/profile/README.md b/modules/profile/README.md new file mode 100644 index 0000000..0e921a9 --- /dev/null +++ b/modules/profile/README.md @@ -0,0 +1,96 @@ +# SCC Profile Module + +This module creates an SCC Profile (https://cloud.ibm.com/docs/security-compliance?topic=security-compliance-build-custom-profiles&interface=ui). A profile is a grouping of controls that can be evaluated for compliance. + +### Usage + +```hcl +provider "ibm" { + ibmcloud_api_key = "XXXXXXXXXX" # pragma: allowlist secret + region = "us-south" +} + +# - SCC Profile +module "create_scc_profile" { + source = "terraform-ibm-modules/scc/ibm//modules/profile" + instance_id = "00000000-1111-2222-3333-444444444444" + controls = [ + # Apply 3 controls from IBM Cloud Framework for Financial Services control library version 1.6.0 + { + control_library_name = "IBM Cloud Framework for Financial Services", + control_library_version = "1.6.0" + control_name_list = [ + "AC", + "AC-1", + "AC-1(a)", + ] + }, + # Apply 4 controls from CIS IBM Cloud Foundations Benchmark control library version 1.0.0 + { + control_library_name = "CIS IBM Cloud Foundations Benchmark", + control_library_version = "1.0.0" + control_name_list = [ + "1.16", + "1.18", + "1.19", + "1.4", + ] + }, + # Apply all controls from SOC 2 control library version 1.0.0 + { + control_library_name = "SOC 2", + control_library_version = "1.0.0" + add_all_controls = true + }, + ] + profile_name = "scc-profile" + profile_description = "scc-custom" + profile_version = "1.0.0" +} +``` + +### Required IAM access policies +You need the following permissions to run this module. + +- Account Management + - Security and Compliance Center service + - `Editor` platform access + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0, <1.7.0 | +| [ibm](#requirement\_ibm) | >= 1.65.1, <2.0.0 | + +### Modules + +No modules. + +### Resources + +| Name | Type | +|------|------| +| [ibm_scc_profile.scc_profile_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/scc_profile) | resource | +| [ibm_scc_control_libraries.scc_control_libraries](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/scc_control_libraries) | data source | +| [ibm_scc_control_library.scc_control_library](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/scc_control_library) | data source | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [controls](#input\_controls) | The list of control\_library\_ids that are used to create the profile. Constraints: The maximum length is `600` items. The minimum length is `0` items. |
list(object({
control_library_name = string
control_library_version = string
control_name_list = optional(list(string), ["all_rules"])
add_all_controls = optional(bool, false)
}))
| `[]` | no | +| [default\_parameters](#input\_default\_parameters) | Each assessment must be assigned a value to evaluate your resources. To customize parameters for your profile, set a new default value. This is optional and if no values are passed then the default values will be used. |
list(object({
assessment_type = optional(string)
assessment_id = optional(string)
parameter_name = optional(string)
parameter_default_value = optional(string)
parameter_display_name = optional(string)
parameter_type = optional(string)
}))
| `[]` | no | +| [instance\_id](#input\_instance\_id) | The ID of the SCC instance in a particular region. | `string` | n/a | yes | +| [profile\_description](#input\_profile\_description) | The description of the profile to be created. | `string` | n/a | yes | +| [profile\_name](#input\_profile\_name) | The name of the profile to be created. | `string` | n/a | yes | +| [profile\_version](#input\_profile\_version) | The version status of the profile. | `string` | n/a | yes | + +### Outputs + +| Name | Description | +|------|-------------| +| [profile\_id](#output\_profile\_id) | The id of the SCC profile created by this module | +| [scc\_control\_libraries](#output\_scc\_control\_libraries) | The scc control libraries applied to the profile in this module | + diff --git a/modules/profile/main.tf b/modules/profile/main.tf new file mode 100644 index 0000000..2351dfc --- /dev/null +++ b/modules/profile/main.tf @@ -0,0 +1,69 @@ +data "ibm_scc_control_libraries" "scc_control_libraries" { + instance_id = var.instance_id +} + +locals { + # Get control libraries id from their name and version specified in var.controls.control_library_name + control_libraries = flatten([for control_library in data.ibm_scc_control_libraries.scc_control_libraries.control_libraries : [ + for ctrl in var.controls : + control_library if ctrl.control_library_name == control_library.control_library_name && ctrl.control_library_version == control_library.control_library_version + ] + ]) +} + +data "ibm_scc_control_library" "scc_control_library" { + count = length(var.controls) + instance_id = var.instance_id + control_library_id = local.control_libraries[count.index].id +} + +locals { + # Map out all controls from relevant control libraries + all_controls_map = flatten([ + for index, control_library in local.control_libraries : [ + for control in data.ibm_scc_control_library.scc_control_library[index].controls : { + control_library_id = control_library.id + control_library_name = control_library.control_library_name + control_id = control.control_id + control_name = control.control_name + } + ] + ]) + + # Get chosen controls from var.controls.control_name_list in local.all_controls_map + relevant_controls_map = flatten([ + for ctrl_map in local.all_controls_map : [ + for control in var.controls : [ + for ctrl in control.control_name_list : + ctrl_map if(ctrl_map.control_name == ctrl && ctrl_map.control_library_name == control.control_library_name) || control.add_all_controls + ] + ] + ]) +} + +resource "ibm_scc_profile" "scc_profile_instance" { + instance_id = var.instance_id + profile_description = var.profile_description + profile_name = var.profile_name + profile_type = "custom" + profile_version = var.profile_version + + dynamic "controls" { + for_each = local.relevant_controls_map + content { + control_library_id = controls.value.control_library_id + control_id = controls.value.control_id + } + } + dynamic "default_parameters" { + for_each = var.default_parameters != null ? var.default_parameters : [] + content { + assessment_type = default_parameters.value.assessment_type + assessment_id = default_parameters.value.assessment_id + parameter_name = default_parameters.value.parameter_name + parameter_default_value = default_parameters.value.parameter_default_value + parameter_display_name = default_parameters.value.parameter_display_name + parameter_type = default_parameters.value.parameter_type + } + } +} diff --git a/modules/profile/outputs.tf b/modules/profile/outputs.tf new file mode 100644 index 0000000..17c42a8 --- /dev/null +++ b/modules/profile/outputs.tf @@ -0,0 +1,20 @@ +######################################################################################################################## +# Outputs +######################################################################################################################## + +output "profile_id" { + description = "The id of the SCC profile created by this module" + value = ibm_scc_profile.scc_profile_instance.profile_id +} + +output "scc_control_libraries" { + description = "The scc control libraries applied to the profile in this module" + value = [ + for control_lib in local.control_libraries : { + name = control_lib.control_library_name + id = control_lib.id + version = control_lib.control_library_version + controls_count = control_lib.controls_count + } + ] +} diff --git a/modules/profile/variables.tf b/modules/profile/variables.tf new file mode 100644 index 0000000..b04f63b --- /dev/null +++ b/modules/profile/variables.tf @@ -0,0 +1,47 @@ +######################################################################################################################## +# Input variables +######################################################################################################################## + +variable "instance_id" { + type = string + description = "The ID of the SCC instance in a particular region." +} + +variable "profile_name" { + type = string + description = "The name of the profile to be created." +} + +variable "profile_description" { + type = string + description = "The description of the profile to be created." +} + +variable "profile_version" { + type = string + description = "The version status of the profile." +} + +variable "controls" { + type = list(object({ + control_library_name = string + control_library_version = string + control_name_list = optional(list(string), ["all_rules"]) + add_all_controls = optional(bool, false) + })) + default = [] + description = "The list of control_library_ids that are used to create the profile. Constraints: The maximum length is `600` items. The minimum length is `0` items." +} + +variable "default_parameters" { + type = list(object({ + assessment_type = optional(string) + assessment_id = optional(string) + parameter_name = optional(string) + parameter_default_value = optional(string) + parameter_display_name = optional(string) + parameter_type = optional(string) + })) + default = [] + description = "Each assessment must be assigned a value to evaluate your resources. To customize parameters for your profile, set a new default value. This is optional and if no values are passed then the default values will be used." +} diff --git a/modules/profile/version.tf b/modules/profile/version.tf new file mode 100644 index 0000000..ed30e5b --- /dev/null +++ b/modules/profile/version.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.3.0, <1.7.0" + + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = ">= 1.65.1, <2.0.0" + } + } +} diff --git a/version.tf b/version.tf index 675e573..fca1fe7 100644 --- a/version.tf +++ b/version.tf @@ -6,7 +6,7 @@ terraform { required_providers { ibm = { source = "IBM-Cloud/ibm" - version = ">=1.64.1, <2.0.0" + version = ">=1.65.1, <2.0.0" } time = {