This is an automated email from the ASF dual-hosted git repository.
kiranchavala pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/cloudstack-terraform-provider.git
The following commit(s) were added to refs/heads/main by this push:
new f0615b8 feat: Add service_offering_details support for GPU
configuration (#247)
f0615b8 is described below
commit f0615b8238b28b275e0e7022da10a8465f6e4bcc
Author: Jtolelo <[email protected]>
AuthorDate: Fri Oct 17 10:12:45 2025 -0300
feat: Add service_offering_details support for GPU configuration (#247)
* feat: Add service_offering_details support for GPU configuration
- Add service_offering_details attribute to cloudstack_service_offering
resource
- Support for GPU configuration with pciDevice and vgpuType parameters
- Include comprehensive test coverage and documentation
- Add practical examples for GPU service offerings
- Addresses issue #246
* docs: Add documentation for service_offering_details feature
- Update service offering documentation with GPU examples
- Add service_offering_details parameter documentation
- Update CHANGELOG with new feature entry
- Include practical examples for GPU configuration
* fix: Apply gofmt formatting to resource_cloudstack_service_offering.go
- Fix code formatting to comply with Go standards
- Align map fields and remove trailing whitespace
- Required for CI/CD pipeline to pass
* Add missing cpu_speed to GPU service offering test
add missing cpu_speed
---------
Co-authored-by: jean <[email protected]>
---
CHANGELOG.md | 4 ++
cloudstack/resource_cloudstack_service_offering.go | 75 +++++++++++++++++-----
.../resource_cloudstack_service_offering_test.go | 37 +++++++++++
website/docs/r/service_offering.html.markdown | 23 +++++++
4 files changed, 123 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59f1a35..ffd8a9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
## 0.4.0 (Unreleased)
+FEATURES:
+
+* **New Resource Attribute**: `cloudstack_service_offering` now supports
`service_offering_details` for GPU configuration and other advanced settings
[GH-246]
+
IMPROVEMENTS:
* Restore support for managing resource tags as CloudStack 4.11.3+ and 4.12+
support tags again [GH-65]
diff --git a/cloudstack/resource_cloudstack_service_offering.go
b/cloudstack/resource_cloudstack_service_offering.go
index 107938d..b2b2b92 100644
--- a/cloudstack/resource_cloudstack_service_offering.go
+++ b/cloudstack/resource_cloudstack_service_offering.go
@@ -140,6 +140,15 @@ func resourceCloudStackServiceOffering() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
+ "service_offering_details": {
+ Description: "Service offering details for GPU
configuration and other advanced settings",
+ Type: schema.TypeMap,
+ Optional: true,
+ ForceNew: true,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
},
}
}
@@ -216,6 +225,14 @@ func resourceCloudStackServiceOfferingCreate(d
*schema.ResourceData, meta interf
p.SetTags(v.(string))
}
+ if details, ok := d.GetOk("service_offering_details"); ok {
+ serviceOfferingDetails := make(map[string]string)
+ for k, v := range details.(map[string]interface{}) {
+ serviceOfferingDetails[k] = v.(string)
+ }
+ p.SetServiceofferingdetails(serviceOfferingDetails)
+ }
+
log.Printf("[DEBUG] Creating Service Offering %s", name)
s, err := cs.ServiceOffering.CreateServiceOffering(p)
@@ -248,22 +265,23 @@ func resourceCloudStackServiceOfferingRead(d
*schema.ResourceData, meta interfac
d.SetId(s.Id)
fields := map[string]interface{}{
- "name": s.Name,
- "display_text": s.Displaytext,
- "cpu_number": s.Cpunumber,
- "cpu_speed": s.Cpuspeed,
- "host_tags": s.Hosttags,
- "limit_cpu_use": s.Limitcpuuse,
- "memory": s.Memory,
- "offer_ha": s.Offerha,
- "storage_type": s.Storagetype,
- "customized": s.Iscustomized,
- "min_cpu_number": getIntFromDetails(s.Serviceofferingdetails,
"mincpunumber"),
- "max_cpu_number": getIntFromDetails(s.Serviceofferingdetails,
"maxcpunumber"),
- "min_memory": getIntFromDetails(s.Serviceofferingdetails,
"minmemory"),
- "max_memory": getIntFromDetails(s.Serviceofferingdetails,
"maxmemory"),
- "encrypt_root": s.Encryptroot,
- "storage_tags": s.Storagetags,
+ "name": s.Name,
+ "display_text": s.Displaytext,
+ "cpu_number": s.Cpunumber,
+ "cpu_speed": s.Cpuspeed,
+ "host_tags": s.Hosttags,
+ "limit_cpu_use": s.Limitcpuuse,
+ "memory": s.Memory,
+ "offer_ha": s.Offerha,
+ "storage_type": s.Storagetype,
+ "customized": s.Iscustomized,
+ "min_cpu_number":
getIntFromDetails(s.Serviceofferingdetails, "mincpunumber"),
+ "max_cpu_number":
getIntFromDetails(s.Serviceofferingdetails, "maxcpunumber"),
+ "min_memory":
getIntFromDetails(s.Serviceofferingdetails, "minmemory"),
+ "max_memory":
getIntFromDetails(s.Serviceofferingdetails, "maxmemory"),
+ "encrypt_root": s.Encryptroot,
+ "storage_tags": s.Storagetags,
+ "service_offering_details":
getServiceOfferingDetails(s.Serviceofferingdetails),
}
for k, v := range fields {
@@ -381,3 +399,28 @@ func getIntFromDetails(details map[string]string, key
string) interface{} {
}
return nil
}
+
+// getServiceOfferingDetails extracts custom service offering details while
excluding
+// built-in details that are handled as separate schema fields
+func getServiceOfferingDetails(details map[string]string)
map[string]interface{} {
+ if details == nil {
+ return make(map[string]interface{})
+ }
+
+ // List of built-in details that are handled as separate schema fields
+ builtInKeys := map[string]bool{
+ "mincpunumber": true,
+ "maxcpunumber": true,
+ "minmemory": true,
+ "maxmemory": true,
+ }
+
+ result := make(map[string]interface{})
+ for k, v := range details {
+ if !builtInKeys[k] {
+ result[k] = v
+ }
+ }
+
+ return result
+}
diff --git a/cloudstack/resource_cloudstack_service_offering_test.go
b/cloudstack/resource_cloudstack_service_offering_test.go
index d4634c9..c403428 100644
--- a/cloudstack/resource_cloudstack_service_offering_test.go
+++ b/cloudstack/resource_cloudstack_service_offering_test.go
@@ -122,3 +122,40 @@ resource "cloudstack_service_offering" "custom" {
storage_tags = "production,ssd"
}
`
+
+func TestAccCloudStackServiceOffering_gpu(t *testing.T) {
+ var so cloudstack.ServiceOffering
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccCloudStackServiceOffering_gpu,
+ Check: resource.ComposeTestCheckFunc(
+
testAccCheckCloudStackServiceOfferingExists("cloudstack_service_offering.gpu",
&so),
+
resource.TestCheckResourceAttr("cloudstack_service_offering.gpu", "name",
"gpu_service_offering"),
+
resource.TestCheckResourceAttr("cloudstack_service_offering.gpu",
"display_text", "GPU Test"),
+
resource.TestCheckResourceAttr("cloudstack_service_offering.gpu", "cpu_number",
"4"),
+
resource.TestCheckResourceAttr("cloudstack_service_offering.gpu", "memory",
"16384"),
+
resource.TestCheckResourceAttr("cloudstack_service_offering.gpu",
"service_offering_details.pciDevice", "Group of NVIDIA A6000 GPUs"),
+
resource.TestCheckResourceAttr("cloudstack_service_offering.gpu",
"service_offering_details.vgpuType", "A6000-8A"),
+ ),
+ },
+ },
+ })
+}
+
+const testAccCloudStackServiceOffering_gpu = `
+resource "cloudstack_service_offering" "gpu" {
+ name = "gpu_service_offering"
+ display_text = "GPU Test"
+ cpu_number = 4
+ memory = 16384
+ cpu_speed = 1000
+
+ service_offering_details = {
+ pciDevice = "Group of NVIDIA A6000 GPUs"
+ vgpuType = "A6000-8A"
+ }
+}
+`
diff --git a/website/docs/r/service_offering.html.markdown
b/website/docs/r/service_offering.html.markdown
index 33852cb..57cfe84 100644
--- a/website/docs/r/service_offering.html.markdown
+++ b/website/docs/r/service_offering.html.markdown
@@ -12,10 +12,30 @@ A `cloudstack_service_offering` resource manages a service
offering within Cloud
## Example Usage
+### Basic Service Offering
+
```hcl
resource "cloudstack_service_offering" "example" {
name = "example-service-offering"
display_text = "Example Service Offering"
+ cpu_number = 2
+ memory = 4096
+}
+```
+
+### GPU Service Offering
+
+```hcl
+resource "cloudstack_service_offering" "gpu_offering" {
+ name = "gpu-a6000"
+ display_text = "GPU A6000 Instance"
+ cpu_number = 4
+ memory = 16384
+
+ service_offering_details = {
+ pciDevice = "Group of NVIDIA A6000 GPUs"
+ vgpuType = "A6000-8A"
+ }
}
```
@@ -69,6 +89,9 @@ The following arguments are supported:
* `storage_tags` - (Optional) Storage tags to associate with the service
offering.
+* `service_offering_details` - (Optional) A map of service offering details
for GPU configuration and other advanced settings. Common keys include
`pciDevice` and `vgpuType` for GPU offerings.
+ Changing this forces a new resource to be created.
+
## Attributes Reference
The following attributes are exported: