diff --git a/README.md b/README.md index b2023bc..d8ccc56 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ A module for provisioning an [IBM Cloud Security and Compliance Center Workload ## 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) @@ -114,6 +116,7 @@ statement instead the previous block. | Name | Source | Version | |------|--------|---------| +| [account\_type\_check](#module\_account\_type\_check) | ./modules/account_check | n/a | | [cbr\_rule](#module\_cbr\_rule) | terraform-ibm-modules/cbr/ibm//modules/cbr-rule-module | 1.33.6 | | [trusted\_profile\_scc\_wp](#module\_trusted\_profile\_scc\_wp) | terraform-ibm-modules/trusted-profile/ibm | 3.1.1 | @@ -135,6 +138,7 @@ statement instead the previous block. | [cbr\_rules](#input\_cbr\_rules) | The list of context-based restriction rules to create. |
list(object({
description = string
account_id = string
tags = optional(list(object({
name = string
value = string
})), [])
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
})) | `[]` | no |
| [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 |
| [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 |
+| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes |
| [name](#input\_name) | The name to give the SCC Workload Protection instance that will be provisioned by this module. | `string` | n/a | yes |
| [region](#input\_region) | IBM Cloud region where all resources will be deployed | `string` | `"us-south"` | no |
| [resource\_group\_id](#input\_resource\_group\_id) | The resource group ID where resources will be provisioned. | `string` | n/a | yes |
@@ -150,6 +154,7 @@ statement instead the previous block.
|------|-------------|
| [access\_key](#output\_access\_key) | Workload Protection instance access key. |
| [account\_id](#output\_account\_id) | Account ID of created SCC WP instance. |
+| [account\_type](#output\_account\_type) | The determined type of the IBM Cloud account. |
| [api\_endpoint](#output\_api\_endpoint) | API endpoint. |
| [crn](#output\_crn) | CRN of created SCC WP instance. |
| [guid](#output\_guid) | GUID of created SCC WP instance. |
diff --git a/examples/advanced/main.tf b/examples/advanced/main.tf
index 2c0d408..1055a76 100644
--- a/examples/advanced/main.tf
+++ b/examples/advanced/main.tf
@@ -110,4 +110,5 @@ module "scc_wp" {
}]
}
]
+ ibmcloud_api_key = var.ibmcloud_api_key
}
diff --git a/examples/basic/main.tf b/examples/basic/main.tf
index 31152cd..eedcf84 100644
--- a/examples/basic/main.tf
+++ b/examples/basic/main.tf
@@ -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
}
diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf
index b210f3f..c06f16d 100644
--- a/examples/basic/outputs.tf
+++ b/examples/basic/outputs.tf
@@ -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
+}
diff --git a/examples/basic/variables.tf b/examples/basic/variables.tf
index a372112..c1b5946 100644
--- a/examples/basic/variables.tf
+++ b/examples/basic/variables.tf
@@ -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" {
diff --git a/examples/enterprise/main.tf b/examples/enterprise/main.tf
index fe84360..9e31402 100644
--- a/examples/enterprise/main.tf
+++ b/examples/enterprise/main.tf
@@ -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
}
diff --git a/main.tf b/main.tf
index 48b2828..17535b5 100644
--- a/main.tf
+++ b/main.tf
@@ -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
@@ -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
+}
+
+
##############################################################################
# SCC WP Instance Key
##############################################################################
diff --git a/modules/account_check/README.md b/modules/account_check/README.md
new file mode 100644
index 0000000..fb7055e
--- /dev/null
+++ b/modules/account_check/README.md
@@ -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.
+
+
+### Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.9.0 |
+| [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 |
+|------|-------------|------|---------|:--------:|
+| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes |
+| [target\_account\_id](#input\_target\_account\_id) | The ID of the target account to check for type. | `string` | n/a | yes |
+
+### Outputs
+
+| Name | Description |
+|------|-------------|
+| [account\_type](#output\_account\_type) | The determined type of the IBM Cloud account. |
+
diff --git a/modules/account_check/main.tf b/modules/account_check/main.tf
new file mode 100644
index 0000000..df03fec
--- /dev/null
+++ b/modules/account_check/main.tf
@@ -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
+ }
+}
diff --git a/modules/account_check/outputs.tf b/modules/account_check/outputs.tf
new file mode 100644
index 0000000..81079b8
--- /dev/null
+++ b/modules/account_check/outputs.tf
@@ -0,0 +1,4 @@
+output "account_type" {
+ description = "The determined type of the IBM Cloud account."
+ value = local.account_type
+}
diff --git a/modules/account_check/variables.tf b/modules/account_check/variables.tf
new file mode 100644
index 0000000..768438e
--- /dev/null
+++ b/modules/account_check/variables.tf
@@ -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
+}
diff --git a/modules/account_check/version.tf b/modules/account_check/version.tf
new file mode 100644
index 0000000..4f743a1
--- /dev/null
+++ b/modules/account_check/version.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 1.9.0"
+ required_providers {
+ external = {
+ source = "hashicorp/external"
+ version = "2.3.5"
+ }
+ }
+}
diff --git a/modules/scripts/account-check.sh b/modules/scripts/account-check.sh
new file mode 100755
index 0000000..49b960f
--- /dev/null
+++ b/modules/scripts/account-check.sh
@@ -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
diff --git a/outputs.tf b/outputs.tf
index d580b14..06518fc 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -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
+}
diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf
index a931eb1..cf8b7cb 100644
--- a/solutions/fully-configurable/main.tf
+++ b/solutions/fully-configurable/main.tf
@@ -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
}
diff --git a/tests/pr_test.go b/tests/pr_test.go
index 2ef7cba..1796d65 100644
--- a/tests/pr_test.go
+++ b/tests/pr_test.go
@@ -103,6 +103,8 @@ func TestFullyConfigurable(t *testing.T) {
Prefix: "wp-da",
TarIncludePatterns: []string{
"*.tf",
+ "modules/*/*.tf",
+ "modules/*/*.sh",
fullyConfigurableDADir + "/*.tf",
},
ResourceGroup: resourceGroup,
@@ -192,6 +194,8 @@ func TestFullyConfigurableUpgrade(t *testing.T) {
Prefix: "wp-da",
TarIncludePatterns: []string{
"*.tf",
+ "modules/*/*.tf",
+ "modules/*/*.sh",
fullyConfigurableDADir + "/*.tf",
},
ResourceGroup: resourceGroup,
diff --git a/variables.tf b/variables.tf
index 839ff92..565d602 100644
--- a/variables.tf
+++ b/variables.tf
@@ -3,6 +3,12 @@
# Input Variables
##############################################################################
+variable "ibmcloud_api_key" {
+ 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