diff --git a/infracost-usage-example.yml b/infracost-usage-example.yml index b0621205b9a..95d417f70b5 100644 --- a/infracost-usage-example.yml +++ b/infracost-usage-example.yml @@ -79,6 +79,9 @@ resource_type_default_usage: wd_collections: 301 scc_evaluations: 1 data-science-experience_CAPACITY_UNIT_HOURS: 1 + sysdig-secure_MULTI_CLOUD_CSPM_COMPUTE_INSTANCES: 0 + sysdig-secure_NODE_HOURS: 0 + sysdig-secure_VM_NODE_HOUR: 501 aiopenscale_RESOURCE_UNITS: 1 aiopenscale_MODELS_PER_MONTH: 1 ibm_tg_gateway: @@ -1337,6 +1340,11 @@ resource_usage: ibm_resource_instance.watson_studio_professional: data-science-experience_CAPACITY_UNIT_HOURS: 1 # Amount of Capacity Unit-Hours used in a month + ibm_resource_instance.sccwp_graduated_tier: + sysdig-secure_MULTI_CLOUD_CSPM_COMPUTE_INSTANCES: 0 + sysdig-secure_NODE_HOURS: 0 + sysdig-secure_VM_NODE_HOUR: 501 + ibm_resource_instance.watson_governance_essentials: aiopenscale_RESOURCE_UNITS: 1 diff --git a/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.golden b/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.golden index d554baa85ac..9ab47333f33 100644 --- a/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.golden +++ b/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.golden @@ -89,6 +89,26 @@ ibm_resource_instance.scc_trial └─ Trial 1 $0.00 + ibm_resource_instance.sccwp_graduated_tier + ├─ Multi-Cloud CSPM Compute Instance Hours (first 25 Instance-Hours) 25 Instance-Hours $206.00 + ├─ Multi-Cloud CSPM Compute Instance Hours (next 25 Instance-Hours) 25 Instance-Hours $175.10 + ├─ Multi-Cloud CSPM Compute Instance Hours (next 50 Instance-Hours) 50 Instance-Hours $309.00 + ├─ Multi-Cloud CSPM Compute Instance Hours (next 150 Instance-Hours) 150 Instance-Hours $865.20 + ├─ Multi-Cloud CSPM Compute Instance Hours (next 250 Instance-Hours) 250 Instance-Hours $1,236.00 + ├─ Multi-Cloud CSPM Compute Instance Hours (over 500 Instance-Hours) 1 Instance-Hours $4.53 + ├─ Node Hours (first 3 Instance-Hours) 3 Instance-Hours $0.19 + ├─ Node Hours (next 2 Instance-Hours) 2 Instance-Hours $0.11 + ├─ Node Hours (next 5 Instance-Hours) 5 Instance-Hours $0.24 + ├─ Node Hours (next 15 Instance-Hours) 15 Instance-Hours $0.68 + ├─ Node Hours (next 25 Instance-Hours) 25 Instance-Hours $0.97 + ├─ Node Hours (over 50 Instance-Hours) 1 Instance-Hours $0.04 + └─ VM Node Hours (first 25 Instance-Hours) 25 Instance-Hours $0.56 + └─ VM Node Hours (next 25 Instance-Hours) 25 Instance-Hours $0.47 + └─ VM Node Hours (next 50 Instance-Hours) 50 Instance-Hours $0.83 + └─ VM Node Hours (next 150 Instance-Hours) 150 Instance-Hours $2.33 + └─ VM Node Hours (next 250 Instance-Hours) 250 Instance-Hours $3.33 + └─ VM Node Hours (over 500 Instance-Hours) 1 Instance-Hours $0.01 + ibm_resource_instance.wa_instance_enterprise ├─ Instance (50000 MAU included) 1 Instance $6,000.00 ├─ Additional Monthly Active Users 1 1K MAU $120.00 @@ -148,7 +168,7 @@ ├─ Class 2 Resource Units 50 RU $0.09 └─ Class 3 Resource Units 50 RU $0.25 - OVERALL TOTAL $15,791.56 + OVERALL TOTAL $18,597.15 ────────────────────────────────── -35 cloud resources were detected: -∙ 35 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file \ No newline at end of file +36 cloud resources were detected: +∙ 36 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file \ No newline at end of file diff --git a/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.tf b/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.tf index b3945faa73d..220e3bb49cb 100644 --- a/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.tf +++ b/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.tf @@ -239,6 +239,7 @@ resource "ibm_resource_instance" "scc_trial" { resource_group_id = "default" } +# Watson Studio resource "ibm_resource_instance" "watson_studio_professional" { name = "ws_professional" service = "data-science-experience" @@ -255,6 +256,16 @@ resource "ibm_resource_instance" "watson_studio_lite" { resource_group_id = "default" } +# Security and Compliance Center (SCC) Workload Protection +resource "ibm_resource_instance" "sccwp_graduated_tier" { + name = "sccwp_graduated_tier" + service = "sysdig-secure" + plan = "graduated-tier" + location = "us-south" + resource_group_id = "default" +} + +# Watsonx.governance resource "ibm_resource_instance" "watson_governance_lite" { name = "wgov_lite" service = "aiopenscale" diff --git a/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.usage.yml b/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.usage.yml index 5f95186e032..02f4b01e1fa 100644 --- a/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.usage.yml +++ b/internal/providers/terraform/ibm/testdata/resource_instance_test/resource_instance_test.usage.yml @@ -87,10 +87,13 @@ resource_usage: ibm_resource_instance.watson_studio_lite: data-science-experience_CAPACITY_UNIT_HOURS: 10 + ibm_resource_instance.sccwp_graduated_tier: + sysdig-secure_MULTI_CLOUD_CSPM_COMPUTE_INSTANCES: 501 # Tier 6: 500-999999999 + sysdig-secure_NODE_HOURS: 51 # Tier 6: 50-999999999999999 + sysdig-secure_VM_NODE_HOUR: 501 # Tier 6: 500-999999999 + ibm_resource_instance.watson_governance_essentials: aiopenscale_RESOURCE_UNITS: 100 ibm_resource_instance.watson_governance_standard_v2: aiopenscale_MODELS_PER_MONTH: 2 - - diff --git a/internal/resources/ibm/resource_instance.go b/internal/resources/ibm/resource_instance.go index 480ad33a1a1..a7efbba9a76 100644 --- a/internal/resources/ibm/resource_instance.go +++ b/internal/resources/ibm/resource_instance.go @@ -78,7 +78,11 @@ type ResourceInstance struct { SCC_Evaluations *float64 `infracost_usage:"scc_evaluations"` // Watson Studio WS_CUH *float64 `infracost_usage:"data-science-experience_CAPACITY_UNIT_HOURS"` - // Watson.governance + // SCC Workload Protection (Sysdig Secure) + SCCWP_MulticloudCSPMComputeInstances *float64 `infracost_usage:"sysdig-secure_MULTI_CLOUD_CSPM_COMPUTE_INSTANCES"` + SCCWP_NodeHours *float64 `infracost_usage:"sysdig-secure_NODE_HOURS"` + SCCWP_VMNodeHours *float64 `infracost_usage:"sysdig-secure_VM_NODE_HOUR"` + // Watsonx.governance WGOV_ru *float64 `infracost_usage:"aiopenscale_RESOURCE_UNITS"` WGOV_Models *float64 `infracost_usage:"aiopenscale_MODELS_PER_MONTH"` } @@ -125,6 +129,9 @@ var ResourceInstanceUsageSchema = []*schema.UsageItem{ {Key: "wd_collections", DefaultValue: 0, ValueType: schema.Float64}, {Key: "scc_evaluations", DefaultValue: 0, ValueType: schema.Float64}, {Key: "data-science-experience_CAPACITY_UNIT_HOURS", DefaultValue: 1, ValueType: schema.Float64}, + {Key: "sysdig-secure_MULTI_CLOUD_CSPM_COMPUTE_INSTANCES", DefaultValue: 0, ValueType: schema.Float64}, + {Key: "sysdig-secure_NODE_HOURS", DefaultValue: 0, ValueType: schema.Float64}, + {Key: "sysdig-secure_VM_NODE_HOUR", DefaultValue: 0, ValueType: schema.Float64}, {Key: "aiopenscale_RESOURCE_UNITS", DefaultValue: 1, ValueType: schema.Float64}, {Key: "aiopenscale_MODELS_PER_MONTH", DefaultValue: 1, ValueType: schema.Float64}, } @@ -144,6 +151,7 @@ var ResourceInstanceCostMap map[string]ResourceCostComponentsFunc = map[string]R "discovery": GetWDCostComponents, "compliance": GetSCCCostComponents, "data-science-experience": GetWSCostComponents, + "sysdig-secure": GetSCCWPCostComponents, "aiopenscale": GetWGOVCostComponents, } diff --git a/internal/resources/ibm/resource_instance_scc.go b/internal/resources/ibm/resource_instance_scc.go index 34aa2e1c9c5..6497b197f11 100644 --- a/internal/resources/ibm/resource_instance_scc.go +++ b/internal/resources/ibm/resource_instance_scc.go @@ -7,15 +7,15 @@ import ( "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" +const SCC_STANDARD_PLAN_PROGRAMMATIC_NAME string = "security-compliance-center-standard-plan" +const SCC_TRIAL_PLAN_PROGRAMMATIC_NAME string = "security-compliance-center-trial-plan" func GetSCCCostComponents(r *ResourceInstance) []*schema.CostComponent { - if r.Plan == STANDARD_PLAN_PROGRAMMATIC_NAME { + if r.Plan == SCC_STANDARD_PLAN_PROGRAMMATIC_NAME { return []*schema.CostComponent{ SCCMonthlyEvaluationsCostComponent(r), } - } else if r.Plan == TRIAL_PLAN_PROGRAMMATIC_NAME { + } else if r.Plan == SCC_TRIAL_PLAN_PROGRAMMATIC_NAME { costComponent := schema.CostComponent{ Name: "Trial", UnitMultiplier: decimal.NewFromInt(1), diff --git a/internal/resources/ibm/resource_instance_sysdig-secure.go b/internal/resources/ibm/resource_instance_sysdig-secure.go new file mode 100644 index 00000000000..9dfed84a7c3 --- /dev/null +++ b/internal/resources/ibm/resource_instance_sysdig-secure.go @@ -0,0 +1,131 @@ +package ibm + +import ( + "fmt" + + "github.com/infracost/infracost/internal/schema" + "github.com/shopspring/decimal" +) + +const SCCWP_GRADUATED_PLAN_PROGRAMMATIC_NAME string = "graduated-tier" +const SCCWP_TRIAL_PLAN_PROGRAMMATIC_NAME string = "free-trial" + +func GetSCCWPCostComponents(r *ResourceInstance) []*schema.CostComponent { + if r.Plan == SCCWP_TRIAL_PLAN_PROGRAMMATIC_NAME { + costComponent := schema.CostComponent{ + Name: "Free Trial", + UnitMultiplier: decimal.NewFromInt(1), + MonthlyQuantity: decimalPtr(decimal.NewFromInt(1)), + } + costComponent.SetCustomPrice(decimalPtr(decimal.NewFromInt(0))) + return []*schema.CostComponent{ + &costComponent, + } + } else if r.Plan == SCCWP_GRADUATED_PLAN_PROGRAMMATIC_NAME { + return []*schema.CostComponent{ + SCCWPMultiCloudCSPMComputeInstancesCostComponent(r), + SCCWPNodeHoursCostComponent(r), + SCCWPVMNodeHoursCostComponent(r), + } + } 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, + } + } +} + +/* + * Graduated Tier Plan: 6 tiers + */ +func SCCWPMultiCloudCSPMComputeInstancesCostComponent(r *ResourceInstance) *schema.CostComponent { + + var quantity *decimal.Decimal + if r.SCCWP_MulticloudCSPMComputeInstances != nil { + quantity = decimalPtr(decimal.NewFromFloat(*r.SCCWP_MulticloudCSPMComputeInstances)) + } + + costComponent := schema.CostComponent{ + Name: "Multi-Cloud CSPM Compute Instance Hours", + Unit: "Instance-Hours", + UnitMultiplier: decimal.NewFromInt(1), + 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("MULTI_CLOUD_CSPM_COMPUTE_INSTANCES"), + }, + } + return &costComponent +} + +/* + * Graduated Tier Plan: 6 tiers + */ +func SCCWPNodeHoursCostComponent(r *ResourceInstance) *schema.CostComponent { + + var quantity *decimal.Decimal + if r.SCCWP_NodeHours != nil { + quantity = decimalPtr(decimal.NewFromFloat(*r.SCCWP_NodeHours)) + } + + costComponent := schema.CostComponent{ + Name: "Node Hours", + Unit: "Instance-Hours", + UnitMultiplier: decimal.NewFromInt(1), + 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("NODE_HOURS"), + }, + } + return &costComponent +} + +/* + * Graduated Tier Plan: 6 tiers + */ +func SCCWPVMNodeHoursCostComponent(r *ResourceInstance) *schema.CostComponent { + + var quantity *decimal.Decimal + if r.SCCWP_VMNodeHours != nil { + quantity = decimalPtr(decimal.NewFromFloat(*r.SCCWP_VMNodeHours)) + } + + costComponent := schema.CostComponent{ + Name: "VM Node Hours", + Unit: "Instance-Hours", + UnitMultiplier: decimal.NewFromInt(1), + 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("VM_NODE_HOUR"), + }, + } + return &costComponent +}