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"
+ }
+ }
+}