Skip to content

Commit

Permalink
Add support for Security Compliance Center (SCC) (#166)
Browse files Browse the repository at this point in the history
* Create new resource_instance file for 'compliance' (SCC) sevice

* Create cost components

* Add example usage units

* Add resource instance variables

* Write TF tests

* Add usage units for tests

* Update test golden file with SCC results

* Fix Watson Assistant usage units variable name

* Add free SCC resources
  • Loading branch information
luisarojas authored Apr 24, 2024
1 parent 3c4eda8 commit 2e9507b
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 7 deletions.
7 changes: 7 additions & 0 deletions infracost-usage-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ resource_type_default_usage:
wd_queries: 11000
wd_custom_models: 4
wd_collections: 301
scc_evaluations: 1
ibm_tg_gateway:
connection: 3
data_transfer_global: 1000
Expand Down Expand Up @@ -1324,6 +1325,12 @@ resource_usage:
wd_custom_models: 4 # Number of monthly custom models created; 3 included in the Enterprise plan; $500 for every additional custom model.
wd_collections: 301 # Number of monthly collections created; 300 included in the Enterprise plan. $500 for every additional 100 collections.

ibm_resource_instance.scc_standard:
scc_evaluations: 1

ibm_resource_instance.scc_trial:
scc_evaluations: 1

ibm_tg_gateway.tg_gateway:
connection: 25 # Monthly number of connections to the gateway
data_transfer_local: 2500 # Monthly local traffic through the gateway in GB
Expand Down
7 changes: 6 additions & 1 deletion internal/providers/terraform/ibm/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ var FreeResources = []string{
"ibm_is_vpc_address_prefix",
"ibm_is_vpn_gateway_connection",
"ibm_kms_key",
"ibm_kms_key_rings",
"ibm_kms_key_policies",
"ibm_kms_key_rings",
"ibm_pi_capture",
"ibm_pi_cloud_connection",
"ibm_pi_cloud_connection_network_attach",
Expand All @@ -118,11 +118,16 @@ var FreeResources = []string{
"ibm_resource_group",
"ibm_resource_key",
"ibm_scc_account_settings",
"ibm_scc_control_library",
"ibm_scc_instance_settings",
"ibm_scc_posture_collector",
"ibm_scc_posture_credential",
"ibm_scc_posture_profile_import",
"ibm_scc_posture_scan_initiate_validation",
"ibm_scc_posture_scope",
"ibm_scc_profile",
"ibm_scc_profile_attachment",
"ibm_scc_provider_type_instance",
"ibm_scc_rule",
"ibm_scc_rule_attachment",
"ibm_scc_template",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@
├─ Instance 1 Instance $321.00
└─ Active Secrets 400 Secrets $86.00

ibm_resource_instance.scc_standard
└─ Evaluations 1,000 Evaluations $13.39

ibm_resource_instance.scc_trial
└─ Trial 1 $0.00

ibm_resource_instance.wa_instance_enterprise
├─ Instance (50000 MAU included) 1 Instance $6,000.00
├─ Additional Monthly Active Users 1 1K MAU $120.00
Expand Down Expand Up @@ -118,7 +124,7 @@
├─ Class 2 Resource Units 50 RU $0.09
└─ Class 3 Resource Units 50 RU $0.25

OVERALL TOTAL $15,460.14
OVERALL TOTAL $15,473.53
──────────────────────────────────
25 cloud resources were detected:
25 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file
27 cloud resources were detected:
27 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ resource "ibm_resource_instance" "wa_instance_enterprise" {
resource_group_id = "default"
}

# Watson Discovery
resource "ibm_resource_instance" "watson_discovery_plus" {
name = "wd_plus"
service = "discovery"
Expand All @@ -200,3 +201,21 @@ resource "ibm_resource_instance" "watson_discovery_enterprise" {
location = "us-south"
resource_group_id = "default"
}

# Security and Compliance Center (SCC)

resource "ibm_resource_instance" "scc_standard" {
name = "scc_standard"
service = "compliance"
plan = "security-compliance-center-standard-plan"
location = "us-south"
resource_group_id = "default"
}

resource "ibm_resource_instance" "scc_trial" {
name = "scc_trial"
service = "compliance"
plan = "security-compliance-center-trial-plan"
location = "us-south"
resource_group_id = "default"
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ resource_usage:
wd_documents: 101000 # Number of monthly documents created; 100,000 included in the Enterprise plan; $5 for every additional 1,000 documents.
wd_queries: 101000 # Number of queries documents created; 100,000 included in the Enterprise plan; $5 for every additional 1,000 queries.
wd_custom_models: 4 # Number of monthly custom models created; 3 included in the Enterprise plan; $500 for every additional custom model.
wd_collections: 301 # Number of monthly collections created; 300 included in the Enterprise plan. $500 for every additional 100 collections.
wd_collections: 301 # Number of monthly collections created; 300 included in the Enterprise plan. $500 for every additional 100 collections.

ibm_resource_instance.scc_standard:
scc_evaluations: 1000 # Large enough to make sure all decimals are correct

ibm_resource_instance.scc_trial:
scc_evaluations: 1000 # Large enough to make sure any potential cost will be picked up by the test
8 changes: 6 additions & 2 deletions internal/resources/ibm/resource_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ type ResourceInstance struct {
// Watson Assistant
WA_Instance *float64 `infracost_usage:"wa_instance"`
WA_mau *float64 `infracost_usage:"wa_monthly_active_users"`
WA_vu *float64 `infracost_usage:"wa_voice_users"`
WA_vu *float64 `infracost_usage:"wa_monthly_voice_users"`
// Watson Discovery
WD_Instance *float64 `infracost_usage:"wd_instance"`
WD_Documents *float64 `infracost_usage:"wd_documents"`
WD_Queries *float64 `infracost_usage:"wd_queries"`
WD_CustomModels *float64 `infracost_usage:"wd_custom_models"`
WD_Collections *float64 `infracost_usage:"wd_collections"`
// Security and Compliance Center (SCC)
SCC_Evaluations *float64 `infracost_usage:"scc_evaluations"`
}

type ResourceCostComponentsFunc func(*ResourceInstance) []*schema.CostComponent
Expand Down Expand Up @@ -110,12 +112,13 @@ var ResourceInstanceUsageSchema = []*schema.UsageItem{
{Key: "wml_class3_ru", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wa_instance", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wa_monthly_active_users", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wa_voice_users", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wa_monthly_voice_users", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wd_instance", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wd_documents", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wd_queries", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wd_custom_models", DefaultValue: 0, ValueType: schema.Float64},
{Key: "wd_collections", DefaultValue: 0, ValueType: schema.Float64},
{Key: "scc_evaluations", DefaultValue: 0, ValueType: schema.Float64},
}

var ResourceInstanceCostMap map[string]ResourceCostComponentsFunc = map[string]ResourceCostComponentsFunc{
Expand All @@ -131,6 +134,7 @@ var ResourceInstanceCostMap map[string]ResourceCostComponentsFunc = map[string]R
"pm-20": GetWMLCostComponents,
"conversation": GetWACostComponents,
"discovery": GetWDCostComponents,
"compliance": GetSCCCostComponents,
}

func KMSKeyVersionsFreeCostComponent(r *ResourceInstance) *schema.CostComponent {
Expand Down
66 changes: 66 additions & 0 deletions internal/resources/ibm/resource_instance_scc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ibm

import (
"fmt"

"github.com/infracost/infracost/internal/schema"
"github.com/shopspring/decimal"
)

const STANDARD_PLAN_PROGRAMMATIC_NAME string = "security-compliance-center-standard-plan"
const TRIAL_PLAN_PROGRAMMATIC_NAME string = "security-compliance-center-trial-plan"

func GetSCCCostComponents(r *ResourceInstance) []*schema.CostComponent {
if r.Plan == STANDARD_PLAN_PROGRAMMATIC_NAME {
return []*schema.CostComponent{
SCCMonthlyEvaluationsCostComponent(r),
}
} else if r.Plan == TRIAL_PLAN_PROGRAMMATIC_NAME {
costComponent := schema.CostComponent{
Name: "Trial",
UnitMultiplier: decimal.NewFromInt(1),
MonthlyQuantity: decimalPtr(decimal.NewFromInt(1)),
}
costComponent.SetCustomPrice(decimalPtr(decimal.NewFromInt(0)))
return []*schema.CostComponent{
&costComponent,
}
} else {
costComponent := schema.CostComponent{
Name: fmt.Sprintf("Plan %s with customized pricing", r.Plan),
UnitMultiplier: decimal.NewFromInt(1), // Final quantity for this cost component will be divided by this amount
MonthlyQuantity: decimalPtr(decimal.NewFromInt(1)),
}
costComponent.SetCustomPrice(decimalPtr(decimal.NewFromInt(0)))
return []*schema.CostComponent{
&costComponent,
}
}
}

/*
* Evaluations:
* - Standard: $USD/evaluation/month
*/
func SCCMonthlyEvaluationsCostComponent(r *ResourceInstance) *schema.CostComponent {

var quantity *decimal.Decimal = decimalPtr(decimal.NewFromFloat(*r.SCC_Evaluations)) // Quantity of current cost component (i.e. Number of evaluations performed in a month)

return &schema.CostComponent{
Name: "Evaluations",
Unit: "Evaluations",
UnitMultiplier: decimal.NewFromFloat(1), // Final quantity for this cost component will be divided by this amount
MonthlyQuantity: quantity,
ProductFilter: &schema.ProductFilter{
VendorName: strPtr("ibm"),
Region: strPtr(r.Location),
Service: &r.Service,
AttributeFilters: []*schema.AttributeFilter{
{Key: "planName", Value: &r.Plan},
},
},
PriceFilter: &schema.PriceFilter{
Unit: strPtr("EVALUATION"),
},
}
}

0 comments on commit 2e9507b

Please sign in to comment.