Skip to content

Commit

Permalink
feat: added support to attach COS bucket to instance<br>* new input v…
Browse files Browse the repository at this point in the history
…ariables: `cos_instance_crn`, `cos_bucket` and `skip_cos_iam_authorization_policy`<br>- added support to configure event notifications using new variable `en_instance_crn` (#21)
  • Loading branch information
mounika-nalla authored Feb 9, 2024
1 parent 7c4f11b commit d1e5852
Show file tree
Hide file tree
Showing 16 changed files with 303 additions and 14 deletions.
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@

<!-- Add a description of module(s) in this repo -->
This module configures an IBM Cloud Security and Compliance instance.
## Current Limitation
Currently, this module lacks the capability to configure an SCC instance with a Cloud Object Storage bucket. However, there is a provider issue to track this addition - https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4881


<!-- Below content is automatically populated via pre-commit hook -->
<!-- BEGIN OVERVIEW HOOK -->
## Overview
* [terraform-ibm-scc](#terraform-ibm-scc)
* [Examples](./examples)
* [Basic example](./examples/basic)
* [Complete example](./examples/complete)
* [Contributing](#contributing)
<!-- END OVERVIEW HOOK -->

Expand All @@ -37,12 +35,14 @@ https://terraform-ibm-modules.github.io/documentation/#/implementation-guideline

### Usage
```hcl
module "create_scc_instance" {
source = "terraform-ibm-modules/scc/ibm"
version = "X.X.X" # Replace "X.X.X" with a release version to lock into a specific release
instance_name = "my-scc-instance"
plan = "security-compliance-center-standard-plan"
region = "us-south"
resource_group_id = "xxXXxxXXxXxXXXXxxXxxxXXXXxXXXXX"
}
```

### Required IAM access policies
Expand All @@ -51,7 +51,11 @@ You need the following permissions to run this module.

- Account Management
- Security and Compliance Center service
- `Administrator` access
- `Administrator` platform access
- IAM Services
- Event Notifications service
- `Manager` service access


<!-- Below content is automatically populated via pre-commit hook -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Expand All @@ -60,7 +64,7 @@ You need the following permissions to run this module.
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0, <1.6.0 |
| <a name="requirement_ibm"></a> [ibm](#requirement\_ibm) | >=1.61.0, <2.0.0 |
| <a name="requirement_ibm"></a> [ibm](#requirement\_ibm) | >=1.62.0, <2.0.0 |

### Modules

Expand All @@ -70,17 +74,24 @@ No modules.

| Name | Type |
|------|------|
| [ibm_iam_authorization_policy.scc_cos_s2s_access](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource |
| [ibm_resource_instance.scc_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource |
| [ibm_scc_instance_settings.scc_instance_settings](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/scc_instance_settings) | resource |
| [ibm_iam_account_settings.iam_account_settings](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/iam_account_settings) | data source |

### Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cos_bucket"></a> [cos\_bucket](#input\_cos\_bucket) | The name of the Cloud Object Storage bucket to be used in SCC instance | `string` | n/a | yes |
| <a name="input_cos_instance_crn"></a> [cos\_instance\_crn](#input\_cos\_instance\_crn) | CRN of the Cloud Object Storage to store SCC data | `string` | n/a | yes |
| <a name="input_en_instance_crn"></a> [en\_instance\_crn](#input\_en\_instance\_crn) | The CRN of Event Notifications instance to be used with SCC. If no value is provided, Event Notifications will not be enabled for this SCC instance | `string` | `null` | no |
| <a name="input_instance_name"></a> [instance\_name](#input\_instance\_name) | Name of the security and compliance instance that will be provisioned by this module | `string` | n/a | yes |
| <a name="input_plan"></a> [plan](#input\_plan) | Pricing plan to create SCC instance. Options include security-compliance-center-standard-plan or security-compliance-center-trial-plan | `string` | `"security-compliance-center-standard-plan"` | no |
| <a name="input_region"></a> [region](#input\_region) | Region where SCC instance will be created | `string` | `"us-south"` | no |
| <a name="input_resource_group_id"></a> [resource\_group\_id](#input\_resource\_group\_id) | The id of the resource group to create the SCC instance | `string` | n/a | yes |
| <a name="input_resource_tags"></a> [resource\_tags](#input\_resource\_tags) | A list of tags applied to the resources created by the module | `list(string)` | `[]` | no |
| <a name="input_skip_cos_iam_authorization_policy"></a> [skip\_cos\_iam\_authorization\_policy](#input\_skip\_cos\_iam\_authorization\_policy) | Set to true to skip the creation of an IAM authorization policy that permits the SCC instance created by this module to write access to the provided COS instance | `bool` | `false` | no |

### Outputs

Expand Down
15 changes: 14 additions & 1 deletion cra-tf-validate-ignore-rules.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
{
"scc_rules": []
"scc_rules": [
{
"scc_rule_id": "rule-8cbd597c-7471-42bd-9c88-36b2696456e9",
"description": "Check whether Cloud Object Storage network access is restricted to a specific IP range",
"ignore_reason": "This rule is not relevant to the module itself, just the COS resource that is used in the example that is scanned",
"is_valid": false
},
{
"scc_rule_id": "rule-c97259ee-336d-4c5f-b436-1868107a9558",
"description": "Check whether Cloud Object Storage is enabled with customer-managed encryption and Keep Your Own Key (KYOK)",
"ignore_reason": "This rule is not relevant to the module itself, just the COS resource that is used in the example that is scanned",
"is_valid": false
}
]
}
2 changes: 1 addition & 1 deletion examples/basic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ The text below should describe exactly what resources are provisioned / configur

A basic example that will provision the following:
- A new resource group if one is not passed in.
- A new Security and Compliance Center instance.
- A new Security and Compliance Center instance with COS bucket configuration
23 changes: 18 additions & 5 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ module "resource_group" {
existing_resource_group_name = var.resource_group
}

module "cos" {
source = "terraform-ibm-modules/cos/ibm"
version = "7.2.2"
cos_instance_name = "${var.prefix}-cos"
kms_encryption_enabled = false
retention_enabled = false
resource_group_id = module.resource_group.resource_group_id
bucket_name = "${var.prefix}-cb"
}

module "create_scc_instance" {
source = "../.."
instance_name = "${var.prefix}-instance"
region = var.region
resource_group_id = module.resource_group.resource_group_id
resource_tags = var.resource_tags
source = "../.."
instance_name = "${var.prefix}-instance"
region = var.region
resource_group_id = module.resource_group.resource_group_id
resource_tags = var.resource_tags
cos_bucket = module.cos.bucket_name
cos_instance_crn = module.cos.cos_instance_id
skip_cos_iam_authorization_policy = false
}
10 changes: 10 additions & 0 deletions examples/basic/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,13 @@ output "plan" {
description = "The pricing plan used to create SCC instance in this module"
value = module.create_scc_instance.plan
}

output "cos_instance_id" {
description = "The COS instance ID created in this example"
value = module.cos.cos_instance_id
}

output "cos_bucket" {
description = "The COS bucket created in this example"
value = module.cos.bucket_name
}
2 changes: 1 addition & 1 deletion examples/basic/version.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ terraform {
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = "1.61.0"
version = "1.62.0"
}
}
}
6 changes: 6 additions & 0 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Complete example

A complete example that will provision the following:
- A new resource group if one is not passed in.
- A new event notification service instance
- A new Security and Compliance Center instance with COS bucket and event notification configuration
39 changes: 39 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module "resource_group" {
source = "terraform-ibm-modules/resource-group/ibm"
version = "1.1.4"
resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null
existing_resource_group_name = var.resource_group
}

module "cos" {
source = "terraform-ibm-modules/cos/ibm"
version = "7.2.2"
cos_instance_name = "${var.prefix}-cos"
kms_encryption_enabled = false
retention_enabled = false
resource_group_id = module.resource_group.resource_group_id
bucket_name = "${var.prefix}-cb"
}

module "event_notification" {
source = "terraform-ibm-modules/event-notifications/ibm"
version = "1.0.4"
resource_group_id = module.resource_group.resource_group_id
name = "${var.prefix}-en"
tags = var.resource_tags
plan = "lite"
service_endpoints = "public-and-private"
region = var.region
}

module "create_scc_instance" {
source = "../.."
instance_name = "${var.prefix}-instance"
region = var.region
resource_group_id = module.resource_group.resource_group_id
resource_tags = var.resource_tags
cos_bucket = module.cos.bucket_name
cos_instance_crn = module.cos.cos_instance_id
en_instance_crn = module.event_notification.crn
skip_cos_iam_authorization_policy = false
}
53 changes: 53 additions & 0 deletions examples/complete/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
########################################################################################################################
# Outputs
########################################################################################################################

output "resource_group_id" {
description = "The id of the resource group where SCC instance is created by this module"
value = module.resource_group.resource_group_id
}

output "id" {
description = "The id of the SCC instance created by this module"
value = module.create_scc_instance.id
}

output "guid" {
description = "The GUID of the SCC instance created by this module"
value = module.create_scc_instance.guid
}

output "crn" {
description = "The CRN of the SCC instance created by this module"
value = module.create_scc_instance.crn
}

output "name" {
description = "The name of the SCC instance created by this module"
value = module.create_scc_instance.name
}

output "location" {
description = "The location of the SCC instance created by this module"
value = module.create_scc_instance.location
}

output "plan" {
description = "The pricing plan used to create SCC instance in this module"
value = module.create_scc_instance.plan
}

output "en_crn" {
description = "The CRN of the event notification instance created in this module"
value = module.event_notification.crn
}

output "cos_instance_id" {
description = "The COS instance ID created in this example"
value = module.cos.cos_instance_id
}

output "cos_bucket" {
description = "The COS bucket created in this example"
value = module.cos.bucket_name
}
8 changes: 8 additions & 0 deletions examples/complete/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
########################################################################################################################
# Provider config
########################################################################################################################

provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = var.region
}
33 changes: 33 additions & 0 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
########################################################################################################################
# Input variables
########################################################################################################################

variable "ibmcloud_api_key" {
type = string
description = "The IBM Cloud API Key"
sensitive = true
}

variable "region" {
type = string
description = "Region to provision all resources created by this example"
default = "us-south"
}

variable "prefix" {
type = string
description = "Prefix to append to all resources created by this example"
default = "scc"
}

variable "resource_group" {
type = string
description = "The name of an existing resource group to provision resources in to. If not set a new resource group will be created using the prefix variable"
default = null
}

variable "resource_tags" {
type = list(string)
description = "Optional list of tags to be added to created resources"
default = []
}
12 changes: 12 additions & 0 deletions examples/complete/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
terraform {
required_version = ">= 1.3.0, <1.6.0"

# Ensure that there is always 1 example locked into the lowest provider version of the range defined in the main
# module's version.tf (usually a basic example), and 1 example that will always use the latest provider version.
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = ">= 1.62.0"
}
}
}
43 changes: 43 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,46 @@ resource "ibm_resource_instance" "scc_instance" {
resource_group_id = var.resource_group_id
tags = var.resource_tags
}

data "ibm_iam_account_settings" "iam_account_settings" {
}

resource "ibm_iam_authorization_policy" "scc_cos_s2s_access" {
count = var.skip_cos_iam_authorization_policy ? 0 : 1
source_service_name = "compliance"
source_resource_instance_id = ibm_resource_instance.scc_instance.guid
roles = ["Writer"]

resource_attributes {
name = "serviceName"
operator = "stringEquals"
value = "cloud-object-storage"
}

resource_attributes {
name = "serviceInstance"
operator = "stringEquals"
value = local.cos_instance_guid
}

resource_attributes {
name = "accountId"
operator = "stringEquals"
value = data.ibm_iam_account_settings.iam_account_settings.account_id
}
}

resource "ibm_scc_instance_settings" "scc_instance_settings" {
instance_id = resource.ibm_resource_instance.scc_instance.guid
event_notifications {
instance_crn = var.en_instance_crn
}
object_storage {
instance_crn = var.cos_instance_crn
bucket = var.cos_bucket
}
}

locals {
cos_instance_guid = var.cos_instance_crn != null ? element(split(":", var.cos_instance_crn), length(split(":", var.cos_instance_crn)) - 3) : null
}
26 changes: 26 additions & 0 deletions tests/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// Use existing resource group
const resourceGroup = "geretain-test-resources"
const basicExampleDir = "examples/basic"
const completeExampleDir = "examples/complete"

func setupOptions(t *testing.T, prefix string, dir string) *testhelper.TestOptions {
options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{
Expand All @@ -23,6 +24,31 @@ func setupOptions(t *testing.T, prefix string, dir string) *testhelper.TestOptio
return options
}

func setupCompleteExampleOptions(t *testing.T, prefix string, dir string) *testhelper.TestOptions {
options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{
Testing: t,
TerraformDir: dir,
Prefix: prefix,
BestRegionYAMLPath: "../common-dev-assets/common-go-assets/cloudinfo-region-scc-prefs.yaml",
/*
To prevent clashes, comment out the 'ResourceGroup' input in the tests to create a unique resource group,
as only one instance of Event Notification (Lite) is allowed per resource group.
*/
//ResourceGroup: resourceGroup,
})
return options
}

func TestRunCompleteExample(t *testing.T) {
t.Parallel()

options := setupCompleteExampleOptions(t, "scc-cmp", completeExampleDir)

output, err := options.RunTestConsistency()
assert.Nil(t, err, "This should not have errored")
assert.NotNil(t, output, "Expected some output")
}

func TestRunBasicExample(t *testing.T) {
t.Parallel()

Expand Down
Loading

0 comments on commit d1e5852

Please sign in to comment.