Skip to content

Commit

Permalink
Add Terraform support for watsonx.governance service (#162)
Browse files Browse the repository at this point in the history
* Create new file for resource_instance type aiopenscale (watsonx.governance)

* Update golangci-lint-action version in GitHub Actions

* Add func call & resource parameters for service watsonx.gov

* Add usage for wgov units

* Add vars to UsageSchema

* Add base content for cost components

* finish wgov

* fix merge

* remove duplicates in test

* add missing catalog ids for observability resources

---------

Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
luisarojas and hiltol authored Apr 25, 2024
1 parent a4398bb commit 435a6a0
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 7 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ jobs:
go-version: 1.19

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v2.5.2
uses: golangci/golangci-lint-action@v2.297.0
with:
# Required: the version of golangci-lint is required and must be specified without patch version: they always use the latest patch version.
version: v1.45
version: latest
skip-pkg-cache: true
args: --timeout 3m0s

- name: Install Terragrunt v0.31.8
Expand Down
8 changes: 8 additions & 0 deletions infracost-usage-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ resource_type_default_usage:
wd_collections: 301
scc_evaluations: 1
data-science-experience_CAPACITY_UNIT_HOURS: 1
aiopenscale_RESOURCE_UNITS: 1
aiopenscale_MODELS_PER_MONTH: 1
ibm_tg_gateway:
connection: 3
data_transfer_global: 1000
Expand Down Expand Up @@ -1335,6 +1337,12 @@ 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.watson_governance_essentials:
aiopenscale_RESOURCE_UNITS: 1

ibm_resource_instance.watson_governance_standard_v2:
aiopenscale_MODELS_PER_MONTH: 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
3 changes: 3 additions & 0 deletions internal/providers/terraform/ibm/ibm.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ var globalCatalogServiceId = map[string]catalogMetadata{
"wx": {"51c53b72-918f-4869-b834-2d99eb28422a", []string{}, nil},
"conversation": {"7045626d-55e3-4418-be11-683a26dbc1e5", []string{}, nil},
"aiopenscale": {"2ad019f3-0fd6-4c25-966d-f3952481a870", []string{}, nil},
"sysdig-monitor": {"090c2c10-8c38-11e8-bec2-493df9c49eb8", []string{}, nil},
"sysdig-secure": {"e831e900-82d6-11ec-95c5-c12c5a5d9687", []string{}, nil},
"logdna": {"e13e1860-959c-11e8-871e-ad157af61ad7", []string{}, nil},
}

func SetCatalogMetadata(d *schema.ResourceData, resourceType string, config map[string]any) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@
├─ Additional Monthly Documents 1,000 Documents $50.00
└─ Additional Monthly Queries 1,000 Queries $20.00

ibm_resource_instance.watson_governance_essentials
└─ Resource Units 100 RU $60.00

ibm_resource_instance.watson_governance_lite
└─ Lite plan 1 $0.00

ibm_resource_instance.watson_governance_standard_v2
└─ Deployed Models 1 Model $261.00

ibm_resource_instance.watson_studio_lite
└─ Lite plan 1 $0.00

Expand All @@ -139,7 +148,7 @@
├─ Class 2 Resource Units 50 RU $0.09
└─ Class 3 Resource Units 50 RU $0.25

OVERALL TOTAL $15,470.56
OVERALL TOTAL $15,791.56
──────────────────────────────────
32 cloud resources were detected:
32 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file
35 cloud resources were detected:
35 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 @@ -248,9 +248,33 @@ resource "ibm_resource_instance" "watson_studio_professional" {
}

resource "ibm_resource_instance" "watson_studio_lite" {
name = "ws_lie"
name = "ws_lite"
service = "data-science-experience"
plan = "free-v1"
location = "us-south"
resource_group_id = "default"
}

resource "ibm_resource_instance" "watson_governance_lite" {
name = "wgov_lite"
service = "aiopenscale"
plan = "lite"
location = "us-south"
resource_group_id = "default"
}

resource "ibm_resource_instance" "watson_governance_essentials" {
name = "wgov_essentials"
service = "aiopenscale"
plan = "essentials"
location = "us-south"
resource_group_id = "default"
}

resource "ibm_resource_instance" "watson_governance_standard_v2" {
name = "wgov_standard_v2"
service = "aiopenscale"
plan = "standard-v2"
location = "us-south"
resource_group_id = "default"
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,11 @@ resource_usage:

ibm_resource_instance.watson_studio_lite:
data-science-experience_CAPACITY_UNIT_HOURS: 10

ibm_resource_instance.watson_governance_essentials:
aiopenscale_RESOURCE_UNITS: 100

ibm_resource_instance.watson_governance_standard_v2:
aiopenscale_MODELS_PER_MONTH: 2


6 changes: 6 additions & 0 deletions internal/resources/ibm/resource_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ 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
WGOV_ru *float64 `infracost_usage:"aiopenscale_RESOURCE_UNITS"`
WGOV_Models *float64 `infracost_usage:"aiopenscale_MODELS_PER_MONTH"`
}

type ResourceCostComponentsFunc func(*ResourceInstance) []*schema.CostComponent
Expand Down Expand Up @@ -122,6 +125,8 @@ 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: "aiopenscale_RESOURCE_UNITS", DefaultValue: 1, ValueType: schema.Float64},
{Key: "aiopenscale_MODELS_PER_MONTH", DefaultValue: 1, ValueType: schema.Float64},
}

var ResourceInstanceCostMap map[string]ResourceCostComponentsFunc = map[string]ResourceCostComponentsFunc{
Expand All @@ -139,6 +144,7 @@ var ResourceInstanceCostMap map[string]ResourceCostComponentsFunc = map[string]R
"discovery": GetWDCostComponents,
"compliance": GetSCCCostComponents,
"data-science-experience": GetWSCostComponents,
"aiopenscale": GetWGOVCostComponents,
}

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

import (
"fmt"

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

/**
* Lite: 'lite' (Free)
* Essentials: 'essentials'
* Standard V2 == 'standard-v2'
*/
func GetWGOVCostComponents(r *ResourceInstance) []*schema.CostComponent {
if r.Plan == "essentials" {
return []*schema.CostComponent{
WGOVResourceUnitsCostComponent(r),
}
} else if r.Plan == "standard-v2" {
return []*schema.CostComponent{
WGOVModelCostComponent(r),
}
} else if r.Plan == "lite" {
costComponent := &schema.CostComponent{
Name: "Lite plan",
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),
MonthlyQuantity: decimalPtr(decimal.NewFromInt(1)),
}
costComponent.SetCustomPrice(decimalPtr(decimal.NewFromInt(0)))
return []*schema.CostComponent{
&costComponent,
}
}
}

/**
* 1 RU for every:
* 1 WGOV_PredictiveModelEvals
* 1 WGOV_FoundationalModelEvals
* 1 WGOV_GlobalExplanations
* 500 WGOV_LocalExplanations
* basically, everything converts into an RU for charging costs, with limits
*/
func WGOVResourceUnitsCostComponent(r *ResourceInstance) *schema.CostComponent {
var q *decimal.Decimal
if r.WGOV_ru != nil {
q = decimalPtr(decimal.NewFromFloat(*r.WGOV_ru))
}
return &schema.CostComponent{
Name: "Resource Units",
Unit: "RU",
UnitMultiplier: decimal.NewFromInt(1),
MonthlyQuantity: q,
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("RESOURCE_UNITS"),
},
}
}

/**
* No restrictions with unlimited evaluations performed on a model, charged on a per model basis instead
*/
func WGOVModelCostComponent(r *ResourceInstance) *schema.CostComponent {
var q *decimal.Decimal
if r.WGOV_Models != nil {
q = decimalPtr(decimal.NewFromFloat(*r.WGOV_Models))
} else {
q = decimalPtr(decimal.NewFromInt(1))
}
return &schema.CostComponent{
Name: "Deployed Models",
Unit: "Model",
UnitMultiplier: decimal.NewFromInt(1),
MonthlyQuantity: q,
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("MODELS_PER_MONTH"),
},
}
}

0 comments on commit 435a6a0

Please sign in to comment.