Skip to content
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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ A module for provisioning an [IBM Cloud Security and Compliance Center Workload
<!-- BEGIN OVERVIEW HOOK -->
## Overview
* [terraform-ibm-scc-workload-protection](#terraform-ibm-scc-workload-protection)
* [Submodules](./modules)
* [account_check](./modules/account_check)
* [Examples](./examples)
* [Advanced example](./examples/advanced)
* [Basic example](./examples/basic)
Expand Down Expand Up @@ -114,6 +116,7 @@ statement instead the previous block.

| Name | Source | Version |
|------|--------|---------|
| <a name="module_account_type_check"></a> [account\_type\_check](#module\_account\_type\_check) | ./modules/account_check | n/a |
| <a name="module_cbr_rule"></a> [cbr\_rule](#module\_cbr\_rule) | terraform-ibm-modules/cbr/ibm//modules/cbr-rule-module | 1.33.6 |
| <a name="module_trusted_profile_scc_wp"></a> [trusted\_profile\_scc\_wp](#module\_trusted\_profile\_scc\_wp) | terraform-ibm-modules/trusted-profile/ibm | 3.1.1 |

Expand All @@ -135,6 +138,7 @@ statement instead the previous block.
| <a name="input_cbr_rules"></a> [cbr\_rules](#input\_cbr\_rules) | The list of context-based restriction rules to create. | <pre>list(object({<br/> description = string<br/> account_id = string<br/> tags = optional(list(object({<br/> name = string<br/> value = string<br/> })), [])<br/> rule_contexts = list(object({<br/> attributes = optional(list(object({<br/> name = string<br/> value = string<br/> }))) }))<br/> enforcement_mode = string<br/> }))</pre> | `[]` | no |
| <a name="input_cloud_monitoring_instance_crn"></a> [cloud\_monitoring\_instance\_crn](#input\_cloud\_monitoring\_instance\_crn) | To collect and analyze metrics and security data on hosts using both Monitoring and Workload Protection, pass the CRN of an existing IBM Cloud Monitoring instance to create a connection between instances. Both instances must be in the same region. | `string` | `null` | no |
| <a name="input_cspm_enabled"></a> [cspm\_enabled](#input\_cspm\_enabled) | Enable Cloud Security Posture Management (CSPM) for the Workload Protection instance. This will create a trusted profile associated with the SCC Workload Protection instance that has viewer / reader access to the App Config service and viewer access to the Enterprise service. [Learn more](https://cloud.ibm.com/docs/workload-protection?topic=workload-protection-about). | `bool` | `true` | no |
| <a name="input_ibmcloud_api_key"></a> [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | The name to give the SCC Workload Protection instance that will be provisioned by this module. | `string` | n/a | yes |
| <a name="input_region"></a> [region](#input\_region) | IBM Cloud region where all resources will be deployed | `string` | `"us-south"` | no |
| <a name="input_resource_group_id"></a> [resource\_group\_id](#input\_resource\_group\_id) | The resource group ID where resources will be provisioned. | `string` | n/a | yes |
Expand All @@ -150,6 +154,7 @@ statement instead the previous block.
|------|-------------|
| <a name="output_access_key"></a> [access\_key](#output\_access\_key) | Workload Protection instance access key. |
| <a name="output_account_id"></a> [account\_id](#output\_account\_id) | Account ID of created SCC WP instance. |
| <a name="output_account_type"></a> [account\_type](#output\_account\_type) | The determined type of the IBM Cloud account. |
| <a name="output_api_endpoint"></a> [api\_endpoint](#output\_api\_endpoint) | API endpoint. |
| <a name="output_crn"></a> [crn](#output\_crn) | CRN of created SCC WP instance. |
| <a name="output_guid"></a> [guid](#output\_guid) | GUID of created SCC WP instance. |
Expand Down
1 change: 1 addition & 0 deletions examples/advanced/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,5 @@ module "scc_wp" {
}]
}
]
ibmcloud_api_key = var.ibmcloud_api_key
}
1 change: 1 addition & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ module "scc_wp" {
resource_tags = var.resource_tags
access_tags = var.access_tags
cspm_enabled = false
ibmcloud_api_key = var.ibmcloud_api_key
}
5 changes: 5 additions & 0 deletions examples/basic/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ output "access_key" {
value = module.scc_wp.access_key
sensitive = true
}

output "account_type" {
description = "The determined type of the IBM Cloud account."
value = module.scc_wp.account_type
}
2 changes: 1 addition & 1 deletion examples/basic/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ variable "ibmcloud_api_key" {
variable "prefix" {
description = "Display name of the prefix for related resources"
type = string
default = "scc-wp"
default = "scc-wp-new"
}

variable "region" {
Expand Down
1 change: 1 addition & 0 deletions examples/enterprise/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ module "scc_wp" {
cspm_enabled = true
app_config_crn = module.app_config.app_config_crn
scc_workload_protection_trusted_profile_name = "${var.prefix}-scc-wp-tp"
ibmcloud_api_key = var.ibmcloud_api_key
}
16 changes: 16 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
# SCC WP
##############################################################################

locals {
target_account_id = ibm_resource_instance.scc_wp.account_id
}

resource "ibm_resource_instance" "scc_wp" {
name = var.name
resource_group_id = var.resource_group_id
Expand All @@ -20,6 +24,18 @@ resource "ibm_resource_instance" "scc_wp" {
}
}

##############################################################################
# Check Account Type
##############################################################################


module "account_type_check" {
source = "./modules/account_check"
target_account_id = local.target_account_id
ibmcloud_api_key = var.ibmcloud_api_key
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output of this has to be used in the restapi_object block as a new parameter. This should also have a count around it as its only needed if CSPM is enabled



##############################################################################
# SCC WP Instance Key
##############################################################################
Expand Down
36 changes: 36 additions & 0 deletions modules/account_check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Account Check

This module determines whether a given IBM Cloud account is part of an `Enterprise` or is a `Standalone (Normal)` account.
It uses the IBM Cloud Enterprise Management API and can be easily integrated into Terraform configurations via the external data source.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the usage and required permissions here


<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
### Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.0 |
| <a name="requirement_external"></a> [external](#requirement\_external) | 2.3.5 |

### Modules

No modules.

### Resources

| Name | Type |
|------|------|
| [external_external.account_check](https://registry.terraform.io/providers/hashicorp/external/2.3.5/docs/data-sources/external) | data source |

### Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_ibmcloud_api_key"></a> [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes |
| <a name="input_target_account_id"></a> [target\_account\_id](#input\_target\_account\_id) | The ID of the target account to check for type. | `string` | n/a | yes |

### Outputs

| Name | Description |
|------|-------------|
| <a name="output_account_type"></a> [account\_type](#output\_account\_type) | The determined type of the IBM Cloud account. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
12 changes: 12 additions & 0 deletions modules/account_check/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
locals {
# Set account_type variable from the external data source's JSON output.
account_type = data.external.account_check.result.account_type
}

data "external" "account_check" {
program = ["/bin/bash", "${path.module}/../scripts/account-check.sh"]
query = {
account_id = var.target_account_id
api_key = var.ibmcloud_api_key
}
}
4 changes: 4 additions & 0 deletions modules/account_check/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "account_type" {
description = "The determined type of the IBM Cloud account."
value = local.account_type
}
10 changes: 10 additions & 0 deletions modules/account_check/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
variable "ibmcloud_api_key" {
description = "The IBM Cloud platform API key needed to deploy IAM enabled resources."
type = string
sensitive = true
}

variable "target_account_id" {
description = "The ID of the target account to check for type."
type = string
}
9 changes: 9 additions & 0 deletions modules/account_check/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.9.0"
required_providers {
external = {
source = "hashicorp/external"
version = "2.3.5"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modules should use a range. EG: >=2.3.5, <3.0.0

}
}
}
26 changes: 26 additions & 0 deletions modules/scripts/account-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

read -r TF_INPUT
ACCOUNT_ID=$(echo "$TF_INPUT" | jq -r '.account_id')
IBM_CLOUD_API_KEY=$(echo "$TF_INPUT" | jq -r '.api_key')

# --- Obtain IAM Token ---
IAM_TOKEN=$(curl -s -X POST "https://iam.cloud.ibm.com/identity/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey=${IBM_CLOUD_API_KEY}" \
| jq -r '.access_token')

# --- Query Enterprise API ---
HTTP_CODE=$(curl -s -w "%{http_code}" -o /tmp/account.json \
-X GET "https://enterprise.cloud.ibm.com/v1/accounts/${ACCOUNT_ID}" \
-H "Authorization: Bearer ${IAM_TOKEN}")

# --- Determine Account Type ---
ACCOUNT_TYPE="NORMAL"
if [ "$HTTP_CODE" == "200" ] && grep -q '"enterprise_id"' /tmp/account.json; then
ACCOUNT_TYPE="ENTERPRISE"
fi

# --- Output for Terraform ---
echo "{\"account_type\": \"${ACCOUNT_TYPE}\"}"
exit 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script needs to be updated so the endpoints can be overridden by environment variables, incase someone is using the to deploy to stage for example. See example

5 changes: 5 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ output "access_key" {
value = ibm_resource_key.scc_wp_resource_key.credentials["Sysdig Access Key"]
sensitive = true
}

output "account_type" {
description = "The determined type of the IBM Cloud account."
value = module.account_type_check.account_type
}
1 change: 1 addition & 0 deletions solutions/fully-configurable/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ module "scc_wp" {
cspm_enabled = var.cspm_enabled
app_config_crn = var.app_config_crn
scc_workload_protection_trusted_profile_name = local.scc_workload_protection_trusted_profile_name
ibmcloud_api_key = var.ibmcloud_api_key
}
4 changes: 4 additions & 0 deletions tests/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ func TestFullyConfigurable(t *testing.T) {
Prefix: "wp-da",
TarIncludePatterns: []string{
"*.tf",
"modules/*/*.tf",
"modules/*/*.sh",
fullyConfigurableDADir + "/*.tf",
},
ResourceGroup: resourceGroup,
Expand Down Expand Up @@ -192,6 +194,8 @@ func TestFullyConfigurableUpgrade(t *testing.T) {
Prefix: "wp-da",
TarIncludePatterns: []string{
"*.tf",
"modules/*/*.tf",
"modules/*/*.sh",
fullyConfigurableDADir + "/*.tf",
},
ResourceGroup: resourceGroup,
Expand Down
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
# Input Variables
##############################################################################

variable "ibmcloud_api_key" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of added a new required input here, maybe it would be better to get the IAM token using a data lookup in the new submodule and pass the token value directly to the script?

description = "The IBM Cloud platform API key needed to deploy IAM enabled resources."
type = string
sensitive = true
}

variable "region" {
description = "IBM Cloud region where all resources will be deployed"
type = string
Expand Down