diff --git a/README.md b/README.md index e0d7984..88a29bd 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) + * [controls](./modules/controls) * [Examples](./examples) * [Basic example](./examples/basic) * [Complete example with CBR rules](./examples/complete) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 7f9fb9f..cfc9ef7 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -88,6 +88,55 @@ module "create_scc_instance" { ] } +############################################################################## +# SCC controls +############################################################################## + +module "create_scc_controls" { + source = "../../modules/controls/." + instance_id = module.create_scc_instance.guid + control_library_name = "control_library_complete" + control_library_description = "control_library_complete_description" + latest = true + controls = [ + { + control_id = "032a81ca-6ef7-4ac2-81ac-20ee4a780e3b" + control_name = "${var.prefix}-control-name" + control_description = "Boundary Protection" + control_category = "System and Communications Protection" + control_requirement = true + status = "enabled" + control_tags = [] + control_docs = [{}] + control_specifications = [ + { + control_specification_id = "5c7d6f88-a92f-4734-9b49-bd22b0900184" + control_specification_description = "IBM Cloud" + component_id = "iam-identity" + component_name = "IAM Identity Service" + environment = "ibm-cloud" + assessments = [ + { + assessment_type = "automated" + assessment_method = "ibm-cloud-rule" + assessment_id = "rule-a637949b-7e51-46c4-afd4-b96619001bf1" + assessment_description = "All assessments related to iam_identity" + parameters = [ + { + parameter_name = "session_invalidation_in_seconds" + parameter_display_name = "Sign out due to inactivity in seconds" + parameter_type = "numeric" + } + ] + } + ] + responsibility = "user" + } + ] + } + ] +} + ############################################################################## # SCC attachment ############################################################################## diff --git a/modules/controls/README.md b/modules/controls/README.md new file mode 100644 index 0000000..cd39f1a --- /dev/null +++ b/modules/controls/README.md @@ -0,0 +1,162 @@ +# SCC Controls Module + +This module creates an SCC Control library (https://cloud.ibm.com/docs/security-compliance?topic=security-compliance-custom-library&interface=ui). A control library is a grouping of controls that are added to Security and Compliance Center. + +The module supports the following actions: +- Create SCC Controls Library + +### Usage + +```hcl +provider "ibm" { + ibmcloud_api_key = "XXXXXXXXXX" # pragma: allowlist secret + region = "us-south" +} + +# - SCC Controls Library +module "create_scc_controls" { + source = "../../controls/." + instance_id = module.create_scc_instance.guid + control_library_name = "control_library_name" + control_library_description = "control_library_description" + control_library_type = "custom" + latest = true + version_group_label = "de38e8c4-2212-4e4b-8dcf-b021b98d8e43" + controls = [ + { + control_id = "032a81ca-6ef7-4ac2-81ac-20ee4a780e3b" + control_name = "${var.prefix}-control-name" + control_description = "Boundary Protection" + control_category = "System and Communications Protection" + control_requirement = true + status = "enabled" + control_tags = [] + control_docs = [{}] + control_specifications = [ + { + control_specification_id = "5c7d6f88-a92f-4734-9b49-bd22b0900184" + control_specification_description = "IBM Cloud" + component_id = "iam-identity" + component_name = "IAM Identity Service" + environment = "ibm-cloud" + assessments = [ + { + assessment_type = "automated" + assessment_method = "ibm-cloud-rule" + assessment_id = "rule-a637949b-7e51-46c4-afd4-b96619001bf1" + assessment_description = "All assessments related to iam_identity" + parameters = [ + { + parameter_name = "session_invalidation_in_seconds" + parameter_display_name = "Sign out due to inactivity in seconds" + parameter_type = "numeric" + } + ] + } + ] + responsibility = "user" + } + ] + } + ] +} +``` + +The above will create a new scc controls library with the controls listed above and output them: +``` +scc_control_library_id = "c98d8210-0d30-4a4f-967b-c4fc8c91964f" +scc_controls = tolist([ + { + "control_category" = "System and Communications Protection" + "control_description" = "Boundary Protection" + "control_docs" = tolist([ + { + "control_docs_id" = tostring(null) + "control_docs_type" = tostring(null) + }, + ]) + "control_id" = "032a81ca-6ef7-4ac2-81ac-20ee4a780e3b" + "control_name" = "scc-control-name" + "control_parent" = "" + "control_requirement" = true + "control_specifications" = tolist([ + { + "assessments" = tolist([ + { + "assessment_description" = "All assessments related to iam_identity" + "assessment_id" = "rule-a637949b-7e51-46c4-afd4-b96619001bf1" + "assessment_method" = "ibm-cloud-rule" + "assessment_type" = "automated" + "parameter_count" = 1 + "parameters" = tolist([ + { + "parameter_display_name" = "Sign out due to inactivity in seconds" + "parameter_name" = "session_invalidation_in_seconds" + "parameter_type" = "numeric" + }, + ]) + }, + ]) + "assessments_count" = 1 + "component_id" = "iam-identity" + "component_name" = "IAM Identity Service" + "control_specification_description" = "IBM Cloud" + "control_specification_id" = "5c7d6f88-a92f-4734-9b49-bd22b0900184" + "environment" = "ibm-cloud" + "responsibility" = "user" + }, + ]) + "control_tags" = tolist([]) + "status" = "enabled" + }, +]) +``` + +### Required IAM access policies +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 + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0, <1.7.0 | +| [ibm](#requirement\_ibm) | >= 1.62.0, <2.0.0 | + +### Modules + +No modules. + +### Resources + +| Name | Type | +|------|------| +| [ibm_scc_control_library.scc_control_library_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/scc_control_library) | 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 | +|------|-------------|------|---------|:--------:| +| [control\_library\_description](#input\_control\_library\_description) | The control library description. Constraints: The maximum length is `256` characters. The minimum length is `2` characters. The value must match regular expression `/[A-Za-z0-9]+/`. | `string` | n/a | yes | +| [control\_library\_name](#input\_control\_library\_name) | The control library name. Constraints: The maximum length is `64` characters. The minimum length is `2` characters. The value must match regular expression `/^[a-zA-Z0-9_\s\-]*$/`. | `string` | n/a | yes | +| [controls](#input\_controls) | The list of controls that are used to create the profile. Constraints: The maximum length is `600` items. The minimum length is `0` items. Full nested schema description can be found here: https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/scc_control_library#controls. |
list(object({
control_id = optional(string)
control_library_version = optional(string)
control_name = optional(string)
control_description = optional(string)
control_category = optional(string)
control_parent = optional(string)
status = optional(string)
control_tags = optional(list(string))
control_requirement = optional(string)
control_docs = list(object({
control_docs_id = optional(string)
control_docs_type = optional(string)
}))
control_specifications_count = optional(string)
control_specifications = list(object({
control_specification_id = optional(string)
responsibility = optional(string)
component_id = optional(string)
component_name = optional(string)
environment = optional(string)
control_specification_description = optional(string)
assessments_count = optional(string)
assessments = list(object({
assessment_id = optional(string)
assessment_method = optional(string)
assessment_type = optional(string)
assessment_description = optional(string)
parameter_count = optional(string)
parameters = list(object({
parameter_name = optional(string)
parameter_display_name = optional(string)
parameter_type = optional(string)
}))
}))
}))
profile_description = optional(string)
profile_name = optional(string)
profile_type = optional(string)
}))
| `[]` | no | +| [instance\_id](#input\_instance\_id) | The ID of the SCC instance in a particular region. | `string` | n/a | yes | +| [latest](#input\_latest) | Choose whether you want the latest version of the control library. | `bool` | `true` | no | +| [version\_group\_label](#input\_version\_group\_label) | The version group label. | `string` | `null` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [control\_library\_id](#output\_control\_library\_id) | The id of the SCC control library created by this module | +| [controls](#output\_controls) | The SCC controls created in this module | + diff --git a/modules/controls/main.tf b/modules/controls/main.tf new file mode 100644 index 0000000..b710db4 --- /dev/null +++ b/modules/controls/main.tf @@ -0,0 +1,85 @@ +// Get list of all control libraries +data "ibm_scc_control_libraries" "scc_control_libraries" { + instance_id = var.instance_id +} + +locals { + // Create map of control libraries + control_library_map = { + for control_library in data.ibm_scc_control_libraries.scc_control_libraries.control_libraries : + control_library.control_library_name => control_library if control_library.control_library_name == var.control_library_name + } +} + +// Get specified control library by id +data "ibm_scc_control_library" "scc_control_library" { + count = lookup(local.control_library_map, var.control_library_name, null) != null ? 1 : 0 + instance_id = var.instance_id + control_library_id = local.control_library_map[var.control_library_name].id +} + +locals { + // Create map of controls + controls_map = { + for control in data.ibm_scc_control_library.scc_control_library[*].controls : + control[0].control_name => control[0] + } +} + +resource "ibm_scc_control_library" "scc_control_library_instance" { + instance_id = var.instance_id + control_library_name = var.control_library_name + control_library_description = var.control_library_description + control_library_type = "custom" + latest = var.latest + version_group_label = var.version_group_label == null ? data.ibm_scc_control_library.scc_control_library[0].version_group_label : var.version_group_label + + dynamic "controls" { + for_each = var.controls != null ? var.controls : [] + content { + control_name = controls.value.control_name + control_id = lookup(local.controls_map, controls.value.control_name, null) == null ? controls.value.control_id : local.controls_map[controls.value.control_name].control_id + control_description = controls.value.control_description + control_category = controls.value.control_category + control_parent = controls.value.control_parent + control_tags = controls.value.control_tags + dynamic "control_specifications" { + for_each = controls.value.control_specifications != null ? controls.value.control_specifications : [] + content { + control_specification_id = control_specifications.value.control_specification_id + responsibility = control_specifications.value.responsibility + component_id = control_specifications.value.component_id + component_name = control_specifications.value.component_name + environment = control_specifications.value.environment + control_specification_description = control_specifications.value.control_specification_description + dynamic "assessments" { + for_each = control_specifications.value.assessments != null ? control_specifications.value.assessments : [] + content { + assessment_id = assessments.value.assessment_id + assessment_method = assessments.value.assessment_method + assessment_type = assessments.value.assessment_type + assessment_description = assessments.value.assessment_description + dynamic "parameters" { + for_each = assessments.value.parameters != null ? assessments.value.parameters : [] + content { + parameter_name = parameters.value.parameter_name + parameter_display_name = parameters.value.parameter_display_name + parameter_type = parameters.value.parameter_type + } + } + } + } + } + } + dynamic "control_docs" { + for_each = controls.value.control_docs != null ? controls.value.control_docs : [] + content { + control_docs_id = control_docs.value.control_docs_id + control_docs_type = control_docs.value.control_docs_type + } + } + control_requirement = controls.value.control_requirement + status = controls.value.status + } + } +} diff --git a/modules/controls/outputs.tf b/modules/controls/outputs.tf new file mode 100644 index 0000000..ad0fa00 --- /dev/null +++ b/modules/controls/outputs.tf @@ -0,0 +1,13 @@ +######################################################################################################################## +# Outputs +######################################################################################################################## + +output "control_library_id" { + description = "The id of the SCC control library created by this module" + value = ibm_scc_control_library.scc_control_library_instance.control_library_id +} + +output "controls" { + description = "The SCC controls created in this module" + value = resource.ibm_scc_control_library.scc_control_library_instance.controls +} diff --git a/modules/controls/variables.tf b/modules/controls/variables.tf new file mode 100644 index 0000000..ce6bfb1 --- /dev/null +++ b/modules/controls/variables.tf @@ -0,0 +1,75 @@ +######################################################################################################################## +# Input variables +######################################################################################################################## + +variable "instance_id" { + type = string + description = "The ID of the SCC instance in a particular region." +} + +variable "control_library_name" { + type = string + description = "The control library name. Constraints: The maximum length is `64` characters. The minimum length is `2` characters. The value must match regular expression `/^[a-zA-Z0-9_\\s\\-]*$/`." +} + +variable "control_library_description" { + type = string + description = "The control library description. Constraints: The maximum length is `256` characters. The minimum length is `2` characters. The value must match regular expression `/[A-Za-z0-9]+/`." +} + +variable "latest" { + type = bool + description = "Choose whether you want the latest version of the control library." + default = true +} + +variable "version_group_label" { + type = string + description = "The version group label." + default = null +} + +variable "controls" { + type = list(object({ + control_id = optional(string) + control_library_version = optional(string) + control_name = optional(string) + control_description = optional(string) + control_category = optional(string) + control_parent = optional(string) + status = optional(string) + control_tags = optional(list(string)) + control_requirement = optional(string) + control_docs = list(object({ + control_docs_id = optional(string) + control_docs_type = optional(string) + })) + control_specifications_count = optional(string) + control_specifications = list(object({ + control_specification_id = optional(string) + responsibility = optional(string) + component_id = optional(string) + component_name = optional(string) + environment = optional(string) + control_specification_description = optional(string) + assessments_count = optional(string) + assessments = list(object({ + assessment_id = optional(string) + assessment_method = optional(string) + assessment_type = optional(string) + assessment_description = optional(string) + parameter_count = optional(string) + parameters = list(object({ + parameter_name = optional(string) + parameter_display_name = optional(string) + parameter_type = optional(string) + })) + })) + })) + profile_description = optional(string) + profile_name = optional(string) + profile_type = optional(string) + })) + default = [] + description = "The list of controls that are used to create the profile. Constraints: The maximum length is `600` items. The minimum length is `0` items. Full nested schema description can be found here: https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/scc_control_library#controls." +} diff --git a/modules/controls/version.tf b/modules/controls/version.tf new file mode 100644 index 0000000..3dd5fb1 --- /dev/null +++ b/modules/controls/version.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.3.0, <1.7.0" + + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = ">= 1.62.0, <2.0.0" + } + } +}