Copilot commented on code in PR #252:
URL: 
https://github.com/apache/cloudstack-terraform-provider/pull/252#discussion_r3557384320


##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -233,141 +585,356 @@ func resourceCloudStackServiceOfferingCreate(d 
*schema.ResourceData, meta interf
                p.SetServiceofferingdetails(serviceOfferingDetails)
        }

Review Comment:
   GPU-specific attributes (gpu_card/gpu_type) are not merged into 
service_offering_details. As written, gpu_card is never sent to CloudStack, and 
gpu_type only sets vgpuprofileid (not vgpuType detail), which contradicts the 
resource schema/docs and can prevent GPU offerings from being 
created/configured as intended.



##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -50,157 +49,492 @@ func resourceCloudStackServiceOffering() *schema.Resource 
{
                                ForceNew:    true,
                        },
                        "cpu_speed": {
-                               Description: "Speed of CPU in Mhz",
+                               Description: "Speed of CPU in MHz",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "memory": {
+                               Description: "Amount of memory in MB",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
                        "host_tags": {
-                               Description: "The host tag for this service 
offering",
+                               Description: "The host tags for this service 
offering",
                                Type:        schema.TypeString,
                                Optional:    true,
                        },
-                       "limit_cpu_use": {
-                               Description: "Restrict the CPU usage to 
committed service offering",
+                       "storage_type": {
+                               Description: "The storage type of the service 
offering",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Default:     "shared",
+                       },

Review Comment:
   storage_type no longer validates allowed values. This allows invalid values 
into plans and defers failures to the CloudStack API.



##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -233,141 +585,356 @@ func resourceCloudStackServiceOfferingCreate(d 
*schema.ResourceData, meta interf
                p.SetServiceofferingdetails(serviceOfferingDetails)
        }
 
-       log.Printf("[DEBUG] Creating Service Offering %s", name)
-       s, err := cs.ServiceOffering.CreateServiceOffering(p)
+       if v, ok := d.GetOk("zone_id"); ok {
+               zones := make([]string, 0)
+               for _, z := range v.([]interface{}) {
+                       zones = append(zones, z.(string))
+               }
+               p.SetZoneid(zones)
+       }

Review Comment:
   domain_id is defined in the schema but never sent in Create. As a result, 
configured domain scoping is silently ignored.



##########
cloudstack/data_source_cloudstack_service_offering.go:
##########
@@ -46,6 +46,186 @@ func dataSourceCloudstackServiceOffering() *schema.Resource 
{
                                Type:     schema.TypeString,
                                Computed: true,
                        },
+                       "cpu_number": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "cpu_speed": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "memory": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "created": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "domain_id": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "domain": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "host_tags": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "is_customized": {
+                               Type:     schema.TypeBool,
+                               Computed: true,
+                       },
+                       "is_system": {
+                               Type:     schema.TypeBool,
+                               Computed: true,
+                       },
+                       "is_volatile": {
+                               Type:     schema.TypeBool,
+                               Computed: true,
+                       },
+                       "limit_cpu_use": {
+                               Type:     schema.TypeBool,
+                               Computed: true,
+                       },
+                       "network_rate": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "storage_type": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "system_vm_type": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "deployment_planner": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "offer_ha": {
+                               Type:     schema.TypeBool,
+                               Computed: true,
+                       },
+                       "tags": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "provisioning_type": {
+                               Type:     schema.TypeString,
+                               Computed: true,
+                       },
+                       "min_iops": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "max_iops": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "hypervisor_snapshot_reserve": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },
+                       "disk_iops": {
+                               Type:     schema.TypeInt,
+                               Computed: true,
+                       },

Review Comment:
   The data source schema defines a disk_iops attribute, but 
serviceOfferingDescriptionAttributes never sets it. This will always be 
unset/zero and is misleading for users.



##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -50,157 +49,492 @@ func resourceCloudStackServiceOffering() *schema.Resource 
{
                                ForceNew:    true,
                        },
                        "cpu_speed": {
-                               Description: "Speed of CPU in Mhz",
+                               Description: "Speed of CPU in MHz",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "memory": {
+                               Description: "Amount of memory in MB",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
                        "host_tags": {
-                               Description: "The host tag for this service 
offering",
+                               Description: "The host tags for this service 
offering",
                                Type:        schema.TypeString,
                                Optional:    true,
                        },
-                       "limit_cpu_use": {
-                               Description: "Restrict the CPU usage to 
committed service offering",
+                       "storage_type": {
+                               Description: "The storage type of the service 
offering",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Default:     "shared",
+                       },
+                       "service_offering_details": {
+                               Description: "Service offering details for 
custom configuration",
+                               Type:        schema.TypeMap,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem: &schema.Schema{
+                                       Type: schema.TypeString,
+                               },
+                       },
+                       "customized": {
+                               Description: "Whether service offering allows 
custom CPU/memory or not. If not specified, CloudStack automatically determines 
based on cpu_number and memory presence: creates customizable offering (true) 
when cpu_number/memory are omitted, or fixed offering (false) when they are 
provided.",
                                Type:        schema.TypeBool,
                                Optional:    true,
                                ForceNew:    true,
-                               Default:     false,
                        },
-                       "memory": {
-                               Description: "The total memory of the service 
offering in MB",
+                       "gpu_card": {
+                               Description: "GPU card name (e.g., 'Tesla P100 
Auto Created')",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "gpu_type": {
+                               Description: "GPU profile/type (e.g., 
'passthrough', 'GRID V100-8Q')",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "gpu_count": {
+                               Description: "Number of GPUs",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
+                       // Behavior settings
                        "offer_ha": {
-                               Description: "The HA for the service offering",
+                               Description: "Whether to offer HA to the VMs 
created with this offering",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Default:     false,
                        },
-                       "storage_type": {
-                               Description: "The storage type of the service 
offering. Values are local and shared",
-                               Type:        schema.TypeString,
+
+                       "dynamic_scaling_enabled": {
+                               Description: "Whether to enable dynamic 
scaling",
+                               Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Default:     "shared",
-                               ValidateFunc: func(val interface{}, key string) 
(warns []string, errs []error) {
-                                       v := val.(string)
-
-                                       if v == "local" || v == "shared" {
-                                               return
-                                       }
+                       },
 
-                                       errs = append(errs, fmt.Errorf("storage 
type should be either local or shared, got %s", v))
+                       // Disk configuration
+                       "root_disk_size": {
+                               Description: "Root disk size in GB",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
 
-                                       return
-                               },
+                       "provisioning_type": {
+                               Description: "Provisioning type: thin, sparse, 
or fat",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
                        },
-                       "customized": {
-                               Description: "Whether service offering allows 
custom CPU/memory or not",
+
+                       // Security
+                       "encrypt_root": {
+                               Description: "Whether to encrypt the root disk 
or not",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Computed:    true,
-                       },
+                       }, // Customized Offering Limits
                        "min_cpu_number": {
-                               Description: "Minimum number of CPU cores 
allowed",
+                               Description: "Minimum number of CPUs for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "max_cpu_number": {
-                               Description: "Maximum number of CPU cores 
allowed",
+                               Description: "Maximum number of CPUs for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "min_memory": {
-                               Description: "Minimum memory allowed (MB)",
+                               Description: "Minimum memory in MB for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "max_memory": {
-                               Description: "Maximum memory allowed (MB)",
+                               Description: "Maximum memory in MB for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
-                       "encrypt_root": {
-                               Description: "Encrypt the root disk for VMs 
using this service offering",
+
+                       // IOPS Limits
+                       "min_iops": {
+                               Description: "Minimum IOPS",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true,
+                       },
+
+                       "max_iops": {
+                               Description: "Maximum IOPS",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true,
+                       },
+
+                       // GPU Display
+                       "gpu_display": {
+                               Description: "Whether to display GPU in UI or 
not",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
                        },
-                       "storage_tags": {
-                               Description: "Storage tags to associate with 
the service offering",
+
+                       // High Priority Parameters
+                       "limit_cpu_use": {
+                               Description: "Restrict CPU usage to the service 
offering value",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "is_volatile": {
+                               Description: "True if the virtual machine needs 
to be volatile (root disk destroyed on stop)",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "customized_iops": {
+                               Description: "Whether compute offering iops is 
custom or not",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "tags": {
+                               Description: "Comma-separated list of tags for 
the service offering",
                                Type:        schema.TypeString,
                                Optional:    true,
+                               ForceNew:    true,
                        },
-                       "service_offering_details": {
-                               Description: "Service offering details for GPU 
configuration and other advanced settings",
+
+                       "domain_id": {
+                               Description: "The ID(s) of the domain(s) to 
which the service offering belongs",
+                               Type:        schema.TypeList,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem:        &schema.Schema{Type: 
schema.TypeString},
+                       },
+
+                       "zone_id": {
+                               Description: "The ID(s) of the zone(s) this 
service offering belongs to",
+                               Type:        schema.TypeList,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem:        &schema.Schema{Type: 
schema.TypeString},
+                       },
+
+                       // IOPS/Bandwidth parameters (Phase 2)
+                       // Note: CloudStack API does not support updating these 
after creation
+                       "disk_iops_read_rate": {
+                               Description: "IO requests read rate of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_write_rate": {
+                               Description: "IO requests write rate of the 
disk offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_read_rate_max": {
+                               Description: "IO requests read rate max of the 
disk offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_write_rate_max": {
+                               Description: "IO requests write rate max of the 
disk offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_read_rate_max_length": {
+                               Description: "Burst duration in seconds for 
read rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_write_rate_max_length": {
+                               Description: "Burst duration in seconds for 
write rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_read_rate": {
+                               Description: "Bytes read rate of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_write_rate": {
+                               Description: "Bytes write rate of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_read_rate_max": {
+                               Description: "Bytes read rate max of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_write_rate_max": {
+                               Description: "Bytes write rate max of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "bytes_read_rate_max_length": {
+                               Description: "Burst duration in seconds for 
bytes read rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "bytes_write_rate_max_length": {
+                               Description: "Burst duration in seconds for 
bytes write rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       }, // Hypervisor Parameters (Phase 3)
+                       "hypervisor_snapshot_reserve": {
+                               Description: "Hypervisor snapshot reserve space 
as a percent of a volume (for managed storage using Xen or VMware)",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                       },
+
+                       "cache_mode": {
+                               Description: "The cache mode to use for the 
disk offering. Valid values: none, writeback, writethrough",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               Computed:    true,
+                       },
+
+                       "deployment_planner": {
+                               Description: "Deployment planner heuristics to 
use for the service offering",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               Computed:    true,
+                       },
+
+                       "storage_policy": {
+                               Description: "Name of the storage policy (for 
VMware)",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               Computed:    true,
+                       },

Review Comment:
   cache_mode, deployment_planner, and storage_policy are set during Create but 
are not ForceNew and are not updated in Update. Also, the Read path comments 
that storage_policy is write-only, which conflicts with Computed=true in the 
schema and can lead to unstable plans/state.



##########
website/docs/r/service_offering.html.markdown:
##########
@@ -1,107 +1,406 @@
 ---
 layout: default
-title: "CloudStack: cloudstack_service_offering"
+page_title: "CloudStack: cloudstack_service_offering"
 sidebar_current: "docs-cloudstack-resource-service_offering"
 description: |-
-    Creates a Service Offering
+    Creates and manages a Service Offering in CloudStack
 ---
 
-# CloudStack: cloudstack_service_offering
+# cloudstack_service_offering
 
-A `cloudstack_service_offering` resource manages a service offering within 
CloudStack.
+Provides a CloudStack Service Offering resource. This resource can be used to 
create, modify, and delete service offerings that define the compute resources 
(CPU, memory, storage) available to virtual machines.
+
+## Understanding CloudStack Service Offering Types
+
+CloudStack supports **three types** of service offerings based on the 
`customized` parameter and how CPU/memory are configured:
+
+### 1. Fixed Offering (Fixed CPU and Memory)
+
+Users **cannot** change CPU or memory when deploying VMs. The values are fixed.
+
+**How to create:** Specify both `cpu_number` AND `memory` (do NOT set 
`customized`).
+
+```hcl
+resource "cloudstack_service_offering" "fixed" {
+  name         = "small-fixed"
+  display_text = "Small Fixed Instance - 2 CPU, 4GB RAM"
+  cpu_number   = 2
+  cpu_speed    = 2000
+  memory       = 4096
+  # customized is automatically set to false
+}
+```
+
+### 2. Custom Constrained Offering (User Choice with Limits)
+
+Users **can** choose CPU and memory **within** the min/max limits you define.
+
+**How to create:** Set `customized = true` AND specify min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "constrained" {
+  name           = "custom-constrained"
+  display_text   = "Custom Constrained - Choose between 2-8 CPU, 2-16GB RAM"
+  customized     = true
+  min_cpu_number = 2
+  max_cpu_number = 8
+  min_memory     = 2048  # 2 GB
+  max_memory     = 16384 # 16 GB
+}
+```
+
+### 3. Custom Unconstrained Offering (User Choice without Limits)
+
+Users **can** choose **any** CPU and memory values (no restrictions).
+
+**How to create:** Set `customized = true` WITHOUT min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "unconstrained" {
+  name         = "custom-unlimited"
+  display_text = "Custom Unlimited - Choose any CPU/RAM"
+  customized   = true
+  # No min/max limits - users have complete freedom
+}
+```
 
 ## Example Usage
 
-### Basic Service Offering
+### Basic Fixed Service Offering
 
 ```hcl
-resource "cloudstack_service_offering" "example" {
-    name = "example-service-offering"
-    display_text = "Example Service Offering"
-    cpu_number = 2
-    memory = 4096
+resource "cloudstack_service_offering" "basic" {
+  name         = "basic-offering"
+  display_text = "Basic 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"
-    }
+resource "cloudstack_service_offering" "gpu" {
+  name         = "gpu-a6000"
+  display_text = "GPU A6000 Instance"
+  cpu_number   = 8
+  memory       = 32768
+  
+  service_offering_details = {
+    pciDevice = "Group of NVIDIA A6000 GPUs"
+    vgpuType  = "A6000-8A"
+  }
+}
+```
+
+### GPU Service Offering with Direct GPU Parameters
+
+```hcl
+resource "cloudstack_service_offering" "tesla_p100_passthrough" {
+  name         = "tesla-p100-passthrough"
+  display_text = "Tesla P100 GPU - 2 vCPU, 1GB RAM (Passthrough Mode)"
+  
+  # Fixed CPU and Memory configuration
+  cpu_number   = 2
+  cpu_speed    = 1000
+  memory       = 1024  # 1 GB
+  
+  # Storage configuration
+  storage_type        = "shared"
+  provisioning_type   = "thin"
+  
+  # Performance and HA settings
+  offer_ha                = false
+  limit_cpu_use           = false
+  is_volatile             = false
+  dynamic_scaling_enabled = true
+  encrypt_root            = false
+  
+  # Cache mode
+  cache_mode = "none"
+  
+  # GPU Configuration - Direct API mapping
+  # gpu_card -> serviceofferingdetails["pciDevice"] -> resolves to gpucardid
+  # gpu_type -> SetVgpuprofileid() + serviceofferingdetails["vgpuType"] -> 
resolves to vgpuprofileid/vgpuprofilename
+  # gpu_count -> SetGpucount() -> number of GPUs
+  
+  gpu_card  = "Tesla P100 Auto Created"                      # GPU Card Name
+  gpu_type  = "8cb04cca-8395-44f8-9d1b-48eb08d48bed"         # vGPU Profile 
UUID
+  gpu_count = 1                                               # Number of GPUs
 }
 ```
 
+### High Performance with IOPS Limits
+
+```hcl
+resource "cloudstack_service_offering" "high_performance" {
+  name                = "high-performance"
+  display_text        = "High Performance Instance"
+  cpu_number          = 4
+  memory              = 8192
+  storage_type        = "shared"
+  
+  # IOPS configuration
+  bytes_read_rate     = 10485760  # 10 MB/s
+  bytes_write_rate    = 10485760  # 10 MB/s
+  iops_read_rate      = 1000
+  iops_write_rate     = 1000
+  
+  # Additional settings
+  offer_ha            = true
+  limit_cpu_use       = true
+  host_tags           = "high-performance"
+  storage_tags        = "ssd"
+}
+```
+
+### Dynamic Scaling Enabled
+
+```hcl
+resource "cloudstack_service_offering" "scalable" {
+  name                    = "scalable-offering"
+  display_text            = "Dynamically Scalable Instance"
+  cpu_number              = 4
+  memory                  = 8192
+  dynamic_scaling_enabled = true
+  disk_iops_min           = 500
+  disk_iops_max           = 2000
+}
+```
 
 ## Argument Reference
 
 The following arguments are supported:
 
-* `name` - (Required) Name of the service offering.
-    Changing this forces a new resource to be created.
+### Required Arguments
+
+* `name` - (Required) The name of the service offering. Changing this forces a 
new resource to be created.
+
+### Basic Configuration
+
+* `display_text` - (Optional) The display text of the service offering. If not 
provided, defaults to the name.
+
+### CPU and Memory Configuration
+
+* `cpu_number` - (Optional) The number of CPU cores. **Note:** When specified 
together with `memory`, creates a **Fixed Offering** (users cannot change 
CPU/memory). Changing this forces a new resource to be created.
+
+* `cpu_speed` - (Optional) The clock rate of the CPU cores in MHz. Changing 
this forces a new resource to be created.
+
+* `memory` - (Optional) The total memory for the service offering in MB. 
**Note:** When specified together with `cpu_number`, creates a **Fixed 
Offering** (users cannot change CPU/memory). Changing this forces a new 
resource to be created.
+
+### Customization Options (Choose Offering Type)
+
+* `customized` - (Optional) Controls whether users can choose CPU and memory 
when deploying VMs:
+  - **Not set** + `cpu_number` + `memory` specified = **Fixed Offering** (no 
user choice)
+  - **`true`** + min/max limits = **Custom Constrained** (user choice within 
limits)
+  - **`true`** + no limits = **Custom Unconstrained** (any user choice)
+  
+  Changing this forces a new resource to be created.
+
+* `customized_iops` - (Optional) Whether compute offering IOPS should be 
customizable. Changing this forces a new resource to be created.
+
+### Custom Constrained Limits
+
+Use these **only** when `customized = true` to set boundaries:
+
+* `min_cpu_number` - (Optional) Minimum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `max_cpu_number` - (Optional) Maximum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `min_memory` - (Optional) Minimum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+* `max_memory` - (Optional) Maximum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+### Storage Configuration
+
+* `storage_type` - (Optional) The storage type of the service offering. Valid 
values are `local` and `shared`. Changing this forces a new resource to be 
created.
+
+* `storage_tags` - (Optional) Comma-separated list of tags for matching 
storage pools. Changing this forces a new resource to be created.

Review Comment:
   The docs list a storage_tags argument, but the unified 
cloudstack_service_offering schema in this PR does not define storage_tags (it 
defines tags instead). This will mislead users and break copy/paste configs.



##########
website/docs/r/service_offering.html.markdown:
##########
@@ -1,107 +1,406 @@
 ---
 layout: default
-title: "CloudStack: cloudstack_service_offering"
+page_title: "CloudStack: cloudstack_service_offering"
 sidebar_current: "docs-cloudstack-resource-service_offering"
 description: |-
-    Creates a Service Offering
+    Creates and manages a Service Offering in CloudStack
 ---
 
-# CloudStack: cloudstack_service_offering
+# cloudstack_service_offering
 
-A `cloudstack_service_offering` resource manages a service offering within 
CloudStack.
+Provides a CloudStack Service Offering resource. This resource can be used to 
create, modify, and delete service offerings that define the compute resources 
(CPU, memory, storage) available to virtual machines.
+
+## Understanding CloudStack Service Offering Types
+
+CloudStack supports **three types** of service offerings based on the 
`customized` parameter and how CPU/memory are configured:
+
+### 1. Fixed Offering (Fixed CPU and Memory)
+
+Users **cannot** change CPU or memory when deploying VMs. The values are fixed.
+
+**How to create:** Specify both `cpu_number` AND `memory` (do NOT set 
`customized`).
+
+```hcl
+resource "cloudstack_service_offering" "fixed" {
+  name         = "small-fixed"
+  display_text = "Small Fixed Instance - 2 CPU, 4GB RAM"
+  cpu_number   = 2
+  cpu_speed    = 2000
+  memory       = 4096
+  # customized is automatically set to false
+}
+```
+
+### 2. Custom Constrained Offering (User Choice with Limits)
+
+Users **can** choose CPU and memory **within** the min/max limits you define.
+
+**How to create:** Set `customized = true` AND specify min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "constrained" {
+  name           = "custom-constrained"
+  display_text   = "Custom Constrained - Choose between 2-8 CPU, 2-16GB RAM"
+  customized     = true
+  min_cpu_number = 2
+  max_cpu_number = 8
+  min_memory     = 2048  # 2 GB
+  max_memory     = 16384 # 16 GB
+}
+```
+
+### 3. Custom Unconstrained Offering (User Choice without Limits)
+
+Users **can** choose **any** CPU and memory values (no restrictions).
+
+**How to create:** Set `customized = true` WITHOUT min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "unconstrained" {
+  name         = "custom-unlimited"
+  display_text = "Custom Unlimited - Choose any CPU/RAM"
+  customized   = true
+  # No min/max limits - users have complete freedom
+}
+```
 
 ## Example Usage
 
-### Basic Service Offering
+### Basic Fixed Service Offering
 
 ```hcl
-resource "cloudstack_service_offering" "example" {
-    name = "example-service-offering"
-    display_text = "Example Service Offering"
-    cpu_number = 2
-    memory = 4096
+resource "cloudstack_service_offering" "basic" {
+  name         = "basic-offering"
+  display_text = "Basic 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"
-    }
+resource "cloudstack_service_offering" "gpu" {
+  name         = "gpu-a6000"
+  display_text = "GPU A6000 Instance"
+  cpu_number   = 8
+  memory       = 32768
+  
+  service_offering_details = {
+    pciDevice = "Group of NVIDIA A6000 GPUs"
+    vgpuType  = "A6000-8A"
+  }
+}
+```
+
+### GPU Service Offering with Direct GPU Parameters
+
+```hcl
+resource "cloudstack_service_offering" "tesla_p100_passthrough" {
+  name         = "tesla-p100-passthrough"
+  display_text = "Tesla P100 GPU - 2 vCPU, 1GB RAM (Passthrough Mode)"
+  
+  # Fixed CPU and Memory configuration
+  cpu_number   = 2
+  cpu_speed    = 1000
+  memory       = 1024  # 1 GB
+  
+  # Storage configuration
+  storage_type        = "shared"
+  provisioning_type   = "thin"
+  
+  # Performance and HA settings
+  offer_ha                = false
+  limit_cpu_use           = false
+  is_volatile             = false
+  dynamic_scaling_enabled = true
+  encrypt_root            = false
+  
+  # Cache mode
+  cache_mode = "none"
+  
+  # GPU Configuration - Direct API mapping
+  # gpu_card -> serviceofferingdetails["pciDevice"] -> resolves to gpucardid
+  # gpu_type -> SetVgpuprofileid() + serviceofferingdetails["vgpuType"] -> 
resolves to vgpuprofileid/vgpuprofilename
+  # gpu_count -> SetGpucount() -> number of GPUs
+  
+  gpu_card  = "Tesla P100 Auto Created"                      # GPU Card Name
+  gpu_type  = "8cb04cca-8395-44f8-9d1b-48eb08d48bed"         # vGPU Profile 
UUID
+  gpu_count = 1                                               # Number of GPUs
 }
 ```
 
+### High Performance with IOPS Limits
+
+```hcl
+resource "cloudstack_service_offering" "high_performance" {
+  name                = "high-performance"
+  display_text        = "High Performance Instance"
+  cpu_number          = 4
+  memory              = 8192
+  storage_type        = "shared"
+  
+  # IOPS configuration
+  bytes_read_rate     = 10485760  # 10 MB/s
+  bytes_write_rate    = 10485760  # 10 MB/s
+  iops_read_rate      = 1000
+  iops_write_rate     = 1000
+  
+  # Additional settings
+  offer_ha            = true
+  limit_cpu_use       = true
+  host_tags           = "high-performance"
+  storage_tags        = "ssd"
+}
+```
+
+### Dynamic Scaling Enabled
+
+```hcl
+resource "cloudstack_service_offering" "scalable" {
+  name                    = "scalable-offering"
+  display_text            = "Dynamically Scalable Instance"
+  cpu_number              = 4
+  memory                  = 8192
+  dynamic_scaling_enabled = true
+  disk_iops_min           = 500
+  disk_iops_max           = 2000
+}
+```
 
 ## Argument Reference
 
 The following arguments are supported:
 
-* `name` - (Required) Name of the service offering.
-    Changing this forces a new resource to be created.
+### Required Arguments
+
+* `name` - (Required) The name of the service offering. Changing this forces a 
new resource to be created.
+
+### Basic Configuration
+
+* `display_text` - (Optional) The display text of the service offering. If not 
provided, defaults to the name.
+
+### CPU and Memory Configuration
+
+* `cpu_number` - (Optional) The number of CPU cores. **Note:** When specified 
together with `memory`, creates a **Fixed Offering** (users cannot change 
CPU/memory). Changing this forces a new resource to be created.
+
+* `cpu_speed` - (Optional) The clock rate of the CPU cores in MHz. Changing 
this forces a new resource to be created.
+
+* `memory` - (Optional) The total memory for the service offering in MB. 
**Note:** When specified together with `cpu_number`, creates a **Fixed 
Offering** (users cannot change CPU/memory). Changing this forces a new 
resource to be created.
+
+### Customization Options (Choose Offering Type)
+
+* `customized` - (Optional) Controls whether users can choose CPU and memory 
when deploying VMs:
+  - **Not set** + `cpu_number` + `memory` specified = **Fixed Offering** (no 
user choice)
+  - **`true`** + min/max limits = **Custom Constrained** (user choice within 
limits)
+  - **`true`** + no limits = **Custom Unconstrained** (any user choice)
+  
+  Changing this forces a new resource to be created.
+
+* `customized_iops` - (Optional) Whether compute offering IOPS should be 
customizable. Changing this forces a new resource to be created.
+
+### Custom Constrained Limits
+
+Use these **only** when `customized = true` to set boundaries:
+
+* `min_cpu_number` - (Optional) Minimum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `max_cpu_number` - (Optional) Maximum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `min_memory` - (Optional) Minimum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+* `max_memory` - (Optional) Maximum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+### Storage Configuration
+
+* `storage_type` - (Optional) The storage type of the service offering. Valid 
values are `local` and `shared`. Changing this forces a new resource to be 
created.
+
+* `storage_tags` - (Optional) Comma-separated list of tags for matching 
storage pools. Changing this forces a new resource to be created.
 
-* `display_text` - (Optional) The display text of the service offering.
+* `host_tags` - (Optional) Comma-separated list of tags for matching hosts. 
Changing this forces a new resource to be created.
 
-* `cpu_number` - (Optional) The number of CPU cores.
-    Changing this forces a new resource to be created.
+* `root_disk_size` - (Optional) The root disk size in GB. Changing this forces 
a new resource to be created.
 
-* `cpu_speed` - (Optional) The speed of the CPU in Mhz.
-    Changing this forces a new resource to be created.
+* `encrypt_root` - (Optional) Whether to encrypt the root disk. Changing this 
forces a new resource to be created.
 
-* `memory` - (Optional) Memory reserved by the VM in MB.
-    Changing this forces a new resource to be created.
+### GPU Configuration
 
-* `host_tags` - (Optional) The host tags for the service offering.
+* `gpu_card` - (Optional) The GPU card name for GPU-enabled service offerings. 
This maps to `serviceofferingdetails["pciDevice"]` and CloudStack automatically 
resolves it to `gpucardid`. Example: `"Tesla P100 Auto Created"`. Changing this 
forces a new resource to be created.
 
-* `limit_cpu_use` - (Optional) Restrict the CPU usage to committed service 
offering.
-    Changing this forces a new resource to be created.
+* `gpu_type` - (Optional) The vGPU profile UUID or type for GPU-enabled 
service offerings. This parameter serves dual purposes:
+  - Sets the vGPU profile ID via `SetVgpuprofileid()` API parameter
+  - Populates `serviceofferingdetails["vgpuType"]`
+  - CloudStack uses this to determine both `vgpuprofileid` and 
`vgpuprofilename`
+  
+  Example: `"8cb04cca-8395-44f8-9d1b-48eb08d48bed"` for passthrough mode. 
Changing this forces a new resource to be created.
 
-* `offer_ha` - (Optional) The HA for the service offering.
-    Changing this forces a new resource to be created.
+* `gpu_count` - (Optional) The number of GPUs to allocate for this service 
offering. Maps directly to `SetGpucount()` API parameter. Default is `1` if not 
specified. Changing this forces a new resource to be created.
 
-* `storage_type` - (Optional) The storage type of the service offering. Values 
are `local` and `shared`.
-    Changing this forces a new resource to be created.
+~> **Note:** For GPU offerings, ensure your CloudStack hosts are properly 
configured with GPU passthrough and that the GPU card names and vGPU profile 
UUIDs match your physical GPU configuration.
 
-* `customized` - (Optional) Whether the service offering allows custom CPU and 
memory values. Set to `true` to enable users to specify CPU/memory within the 
min/max constraints for constrained offerings and any value for unconstrained 
offerings.
-    Changing this forces a new resource to be created.
+### IOPS and Bandwidth Limits
 
-* `min_cpu_number` - (Optional) Minimum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+~> **Note:** All IOPS and bandwidth parameters are immutable after creation. 
Any changes will force recreation of the service offering.
 
-* `max_cpu_number` - (Optional) Maximum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate` - (Optional) Bytes read rate in bytes per second. Changing 
this forces a new resource to be created.
 
-* `min_memory` - (Optional) Minimum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max` - (Optional) Burst bytes read rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `max_memory` - (Optional) Maximum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max_length` - (Optional) Length of the burst bytes read 
rate in seconds. Changing this forces a new resource to be created.
 
-* `encrypt_root` - (Optional) Whether to encrypt the root disk for VMs using 
this service offering.
-    Changing this forces a new resource to be created.
+* `bytes_write_rate` - (Optional) Bytes write rate in bytes per second. 
Changing this forces a new resource to be created.
 
-* `storage_tags` - (Optional) Storage tags to associate with the service 
offering.
+* `bytes_write_rate_max` - (Optional) Burst bytes write rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `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.
+* `bytes_write_rate_max_length` - (Optional) Length of the burst bytes write 
rate in seconds. Changing this forces a new resource to be created.
+
+* `iops_read_rate` - (Optional) IO requests read rate in IOPS. Changing this 
forces a new resource to be created.
+
+* `iops_read_rate_max` - (Optional) Burst IO requests read rate in IOPS. 
Changing this forces a new resource to be created.
+
+* `iops_read_rate_max_length` - (Optional) Length of the burst IO requests 
read rate in seconds. Changing this forces a new resource to be created.
+
+* `iops_write_rate` - (Optional) IO requests write rate in IOPS. Changing this 
forces a new resource to be created.
+
+* `iops_write_rate_max` - (Optional) Burst IO requests write rate in IOPS. 
Changing this forces a new resource to be created.
+
+* `iops_write_rate_max_length` - (Optional) Length of the burst IO requests 
write rate in seconds. Changing this forces a new resource to be created.

Review Comment:
   The IOPS/Bandwidth argument list documents iops_read_rate/iops_write_rate 
and related max fields, but the implemented schema uses 
disk_iops_read_rate/disk_iops_write_rate (and disk_iops_*_max/_max_length). The 
documented names won't work.



##########
cloudstack/resource_cloudstack_service_offering_test.go:
##########
@@ -84,31 +170,59 @@ func testAccCheckCloudStackServiceOfferingExists(n string, 
so *cloudstack.Servic
        }
 }
 
-func TestAccCloudStackServiceOffering_customized(t *testing.T) {
+func testAccCheckCloudStackServiceOfferingDestroy(s *terraform.State) error {
+       cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
+
+       for _, rs := range s.RootModule().Resources {
+               if rs.Type != testServiceOfferingResourceName {
+                       continue
+               }
+
+               if rs.Primary.ID == "" {
+                       continue
+               }
+
+               resp, _, err := 
cs.ServiceOffering.GetServiceOfferingByID(rs.Primary.ID)
+               if err != nil {
+                       // CloudStack returns 431 error code when the resource 
doesn't exist
+                       // Just return nil in this case as the resource is gone
+                       return nil
+               }

Review Comment:
   The destroy check treats any error from GetServiceOfferingByID as success, 
which can mask real API/permission/transport failures and produce 
false-positive test passes. It should only ignore the specific CloudStack 'not 
found' error (not every error).



##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -233,141 +585,356 @@ func resourceCloudStackServiceOfferingCreate(d 
*schema.ResourceData, meta interf
                p.SetServiceofferingdetails(serviceOfferingDetails)
        }
 
-       log.Printf("[DEBUG] Creating Service Offering %s", name)
-       s, err := cs.ServiceOffering.CreateServiceOffering(p)
+       if v, ok := d.GetOk("zone_id"); ok {
+               zones := make([]string, 0)
+               for _, z := range v.([]interface{}) {
+                       zones = append(zones, z.(string))
+               }
+               p.SetZoneid(zones)
+       }
+
+       if v, ok := d.GetOk("disk_iops_read_rate"); ok {
+               p.SetIopsreadrate(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_iops_write_rate"); ok {
+               p.SetIopswriterate(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_iops_read_rate_max"); ok {
+               p.SetIopsreadratemax(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_iops_write_rate_max"); ok {
+               p.SetIopswriteratemax(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_iops_read_rate_max_length"); ok {
+               p.SetIopsreadratemaxlength(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_iops_write_rate_max_length"); ok {
+               p.SetIopswriteratemaxlength(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_bytes_read_rate"); ok {
+               p.SetBytesreadrate(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_bytes_write_rate"); ok {
+               p.SetByteswriterate(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_bytes_read_rate_max"); ok {
+               p.SetBytesreadratemax(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("disk_bytes_write_rate_max"); ok {
+               p.SetByteswriteratemax(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("bytes_read_rate_max_length"); ok {
+               p.SetBytesreadratemaxlength(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("bytes_write_rate_max_length"); ok {
+               p.SetByteswriteratemaxlength(int64(v.(int)))
+       }
+
+       if v, ok := d.GetOk("hypervisor_snapshot_reserve"); ok {
+               p.SetHypervisorsnapshotreserve(v.(int))
+       }
+
+       if v, ok := d.GetOk("cache_mode"); ok {
+               p.SetCachemode(v.(string))
+       }
+
+       if v, ok := d.GetOk("deployment_planner"); ok {
+               p.SetDeploymentplanner(v.(string))
+       }
+
+       if v, ok := d.GetOk("storage_policy"); ok {
+               p.SetStoragepolicy(v.(string))
+       }
 
+       if v, ok := d.GetOk("network_rate"); ok {
+               p.SetNetworkrate(v.(int))
+       }
+
+       if v, ok := d.GetOk("purge_resources"); ok {
+               p.SetPurgeresources(v.(bool))
+       }
+
+       if v, ok := d.GetOk("system_vm_type"); ok {
+               p.SetSystemvmtype(v.(string))
+       }
+
+       if v, ok := d.GetOk("disk_offering_id"); ok {
+               p.SetDiskofferingid(v.(string))
+       }
+
+       if v, ok := d.GetOk("disk_offering_strictness"); ok {
+               p.SetDiskofferingstrictness(v.(bool))
+       }
+
+       if v, ok := d.GetOk("external_details"); ok {
+               extDetails := make(map[string]string)
+               for key, value := range v.(map[string]interface{}) {
+                       extDetails[key] = value.(string)
+               }
+               p.SetExternaldetails(extDetails)
+       }
+
+       if v, ok := d.GetOk("is_system"); ok {
+               p.SetIssystem(v.(bool))
+       }
+
+       if v, ok := d.GetOk("lease_duration"); ok {
+               p.SetLeaseduration(v.(int))
+       }
+
+       if v, ok := d.GetOk("lease_expiry_action"); ok {
+               p.SetLeaseexpiryaction(v.(string))
+       }
+
+       if v, ok := d.GetOk("service_offering_details"); ok {
+               details := make(map[string]string)
+               for key, value := range v.(map[string]interface{}) {
+                       details[key] = value.(string)
+               }
+               p.SetServiceofferingdetails(details)
+       }

Review Comment:
   service_offering_details is set a second time later in Create. This 
duplicates logic and can override the earlier merged details (including 
gpu_card/gpu_type-derived keys), causing GPU configuration to be dropped when 
service_offering_details is also provided.



##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -50,157 +49,492 @@ func resourceCloudStackServiceOffering() *schema.Resource 
{
                                ForceNew:    true,
                        },
                        "cpu_speed": {
-                               Description: "Speed of CPU in Mhz",
+                               Description: "Speed of CPU in MHz",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "memory": {
+                               Description: "Amount of memory in MB",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
                        "host_tags": {
-                               Description: "The host tag for this service 
offering",
+                               Description: "The host tags for this service 
offering",
                                Type:        schema.TypeString,
                                Optional:    true,
                        },
-                       "limit_cpu_use": {
-                               Description: "Restrict the CPU usage to 
committed service offering",
+                       "storage_type": {
+                               Description: "The storage type of the service 
offering",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Default:     "shared",
+                       },
+                       "service_offering_details": {
+                               Description: "Service offering details for 
custom configuration",
+                               Type:        schema.TypeMap,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem: &schema.Schema{
+                                       Type: schema.TypeString,
+                               },
+                       },
+                       "customized": {
+                               Description: "Whether service offering allows 
custom CPU/memory or not. If not specified, CloudStack automatically determines 
based on cpu_number and memory presence: creates customizable offering (true) 
when cpu_number/memory are omitted, or fixed offering (false) when they are 
provided.",
                                Type:        schema.TypeBool,
                                Optional:    true,
                                ForceNew:    true,
-                               Default:     false,
                        },
-                       "memory": {
-                               Description: "The total memory of the service 
offering in MB",
+                       "gpu_card": {
+                               Description: "GPU card name (e.g., 'Tesla P100 
Auto Created')",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "gpu_type": {
+                               Description: "GPU profile/type (e.g., 
'passthrough', 'GRID V100-8Q')",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "gpu_count": {
+                               Description: "Number of GPUs",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
+                       // Behavior settings
                        "offer_ha": {
-                               Description: "The HA for the service offering",
+                               Description: "Whether to offer HA to the VMs 
created with this offering",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Default:     false,
                        },
-                       "storage_type": {
-                               Description: "The storage type of the service 
offering. Values are local and shared",
-                               Type:        schema.TypeString,
+
+                       "dynamic_scaling_enabled": {
+                               Description: "Whether to enable dynamic 
scaling",
+                               Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Default:     "shared",
-                               ValidateFunc: func(val interface{}, key string) 
(warns []string, errs []error) {
-                                       v := val.(string)
-
-                                       if v == "local" || v == "shared" {
-                                               return
-                                       }
+                       },
 
-                                       errs = append(errs, fmt.Errorf("storage 
type should be either local or shared, got %s", v))
+                       // Disk configuration
+                       "root_disk_size": {
+                               Description: "Root disk size in GB",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
 
-                                       return
-                               },
+                       "provisioning_type": {
+                               Description: "Provisioning type: thin, sparse, 
or fat",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
                        },
-                       "customized": {
-                               Description: "Whether service offering allows 
custom CPU/memory or not",
+
+                       // Security
+                       "encrypt_root": {
+                               Description: "Whether to encrypt the root disk 
or not",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Computed:    true,
-                       },
+                       }, // Customized Offering Limits
                        "min_cpu_number": {
-                               Description: "Minimum number of CPU cores 
allowed",
+                               Description: "Minimum number of CPUs for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "max_cpu_number": {
-                               Description: "Maximum number of CPU cores 
allowed",
+                               Description: "Maximum number of CPUs for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "min_memory": {
-                               Description: "Minimum memory allowed (MB)",
+                               Description: "Minimum memory in MB for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "max_memory": {
-                               Description: "Maximum memory allowed (MB)",
+                               Description: "Maximum memory in MB for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
-                       "encrypt_root": {
-                               Description: "Encrypt the root disk for VMs 
using this service offering",
+
+                       // IOPS Limits
+                       "min_iops": {
+                               Description: "Minimum IOPS",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true,
+                       },
+
+                       "max_iops": {
+                               Description: "Maximum IOPS",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true,
+                       },
+
+                       // GPU Display
+                       "gpu_display": {
+                               Description: "Whether to display GPU in UI or 
not",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
                        },
-                       "storage_tags": {
-                               Description: "Storage tags to associate with 
the service offering",
+
+                       // High Priority Parameters
+                       "limit_cpu_use": {
+                               Description: "Restrict CPU usage to the service 
offering value",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "is_volatile": {
+                               Description: "True if the virtual machine needs 
to be volatile (root disk destroyed on stop)",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "customized_iops": {
+                               Description: "Whether compute offering iops is 
custom or not",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "tags": {
+                               Description: "Comma-separated list of tags for 
the service offering",
                                Type:        schema.TypeString,
                                Optional:    true,
+                               ForceNew:    true,
                        },
-                       "service_offering_details": {
-                               Description: "Service offering details for GPU 
configuration and other advanced settings",
+
+                       "domain_id": {
+                               Description: "The ID(s) of the domain(s) to 
which the service offering belongs",
+                               Type:        schema.TypeList,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem:        &schema.Schema{Type: 
schema.TypeString},
+                       },
+
+                       "zone_id": {
+                               Description: "The ID(s) of the zone(s) this 
service offering belongs to",
+                               Type:        schema.TypeList,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem:        &schema.Schema{Type: 
schema.TypeString},
+                       },
+
+                       // IOPS/Bandwidth parameters (Phase 2)
+                       // Note: CloudStack API does not support updating these 
after creation
+                       "disk_iops_read_rate": {
+                               Description: "IO requests read rate of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_write_rate": {
+                               Description: "IO requests write rate of the 
disk offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_read_rate_max": {
+                               Description: "IO requests read rate max of the 
disk offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_write_rate_max": {
+                               Description: "IO requests write rate max of the 
disk offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_read_rate_max_length": {
+                               Description: "Burst duration in seconds for 
read rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_iops_write_rate_max_length": {
+                               Description: "Burst duration in seconds for 
write rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_read_rate": {
+                               Description: "Bytes read rate of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_write_rate": {
+                               Description: "Bytes write rate of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_read_rate_max": {
+                               Description: "Bytes read rate max of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "disk_bytes_write_rate_max": {
+                               Description: "Bytes write rate max of the disk 
offering",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "bytes_read_rate_max_length": {
+                               Description: "Burst duration in seconds for 
bytes read rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       },
+
+                       "bytes_write_rate_max_length": {
+                               Description: "Burst duration in seconds for 
bytes write rate max",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true, // Cannot be updated after 
creation
+                       }, // Hypervisor Parameters (Phase 3)
+                       "hypervisor_snapshot_reserve": {
+                               Description: "Hypervisor snapshot reserve space 
as a percent of a volume (for managed storage using Xen or VMware)",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                       },

Review Comment:
   hypervisor_snapshot_reserve is set during Create but the schema doesn't 
ForceNew and Update doesn't handle it. Changing this value will produce a 
perpetual diff (or a no-op Update) instead of correctly forcing recreation.



##########
cloudstack/resource_cloudstack_service_offering.go:
##########
@@ -50,157 +49,492 @@ func resourceCloudStackServiceOffering() *schema.Resource 
{
                                ForceNew:    true,
                        },
                        "cpu_speed": {
-                               Description: "Speed of CPU in Mhz",
+                               Description: "Speed of CPU in MHz",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "memory": {
+                               Description: "Amount of memory in MB",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
                        "host_tags": {
-                               Description: "The host tag for this service 
offering",
+                               Description: "The host tags for this service 
offering",
                                Type:        schema.TypeString,
                                Optional:    true,
                        },
-                       "limit_cpu_use": {
-                               Description: "Restrict the CPU usage to 
committed service offering",
+                       "storage_type": {
+                               Description: "The storage type of the service 
offering",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Default:     "shared",
+                       },
+                       "service_offering_details": {
+                               Description: "Service offering details for 
custom configuration",
+                               Type:        schema.TypeMap,
+                               Optional:    true,
+                               ForceNew:    true,
+                               Elem: &schema.Schema{
+                                       Type: schema.TypeString,
+                               },
+                       },
+                       "customized": {
+                               Description: "Whether service offering allows 
custom CPU/memory or not. If not specified, CloudStack automatically determines 
based on cpu_number and memory presence: creates customizable offering (true) 
when cpu_number/memory are omitted, or fixed offering (false) when they are 
provided.",
                                Type:        schema.TypeBool,
                                Optional:    true,
                                ForceNew:    true,
-                               Default:     false,
                        },
-                       "memory": {
-                               Description: "The total memory of the service 
offering in MB",
+                       "gpu_card": {
+                               Description: "GPU card name (e.g., 'Tesla P100 
Auto Created')",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "gpu_type": {
+                               Description: "GPU profile/type (e.g., 
'passthrough', 'GRID V100-8Q')",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
+                       "gpu_count": {
+                               Description: "Number of GPUs",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
+                       // Behavior settings
                        "offer_ha": {
-                               Description: "The HA for the service offering",
+                               Description: "Whether to offer HA to the VMs 
created with this offering",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Default:     false,
                        },
-                       "storage_type": {
-                               Description: "The storage type of the service 
offering. Values are local and shared",
-                               Type:        schema.TypeString,
+
+                       "dynamic_scaling_enabled": {
+                               Description: "Whether to enable dynamic 
scaling",
+                               Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Default:     "shared",
-                               ValidateFunc: func(val interface{}, key string) 
(warns []string, errs []error) {
-                                       v := val.(string)
-
-                                       if v == "local" || v == "shared" {
-                                               return
-                                       }
+                       },
 
-                                       errs = append(errs, fmt.Errorf("storage 
type should be either local or shared, got %s", v))
+                       // Disk configuration
+                       "root_disk_size": {
+                               Description: "Root disk size in GB",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               ForceNew:    true,
+                       },
 
-                                       return
-                               },
+                       "provisioning_type": {
+                               Description: "Provisioning type: thin, sparse, 
or fat",
+                               Type:        schema.TypeString,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
                        },
-                       "customized": {
-                               Description: "Whether service offering allows 
custom CPU/memory or not",
+
+                       // Security
+                       "encrypt_root": {
+                               Description: "Whether to encrypt the root disk 
or not",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
-                               Computed:    true,
-                       },
+                       }, // Customized Offering Limits
                        "min_cpu_number": {
-                               Description: "Minimum number of CPU cores 
allowed",
+                               Description: "Minimum number of CPUs for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "max_cpu_number": {
-                               Description: "Maximum number of CPU cores 
allowed",
+                               Description: "Maximum number of CPUs for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "min_memory": {
-                               Description: "Minimum memory allowed (MB)",
+                               Description: "Minimum memory in MB for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
+
                        "max_memory": {
-                               Description: "Maximum memory allowed (MB)",
+                               Description: "Maximum memory in MB for 
customized offerings",
                                Type:        schema.TypeInt,
                                Optional:    true,
                                ForceNew:    true,
                        },
-                       "encrypt_root": {
-                               Description: "Encrypt the root disk for VMs 
using this service offering",
+
+                       // IOPS Limits
+                       "min_iops": {
+                               Description: "Minimum IOPS",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true,
+                       },
+
+                       "max_iops": {
+                               Description: "Maximum IOPS",
+                               Type:        schema.TypeInt,
+                               Optional:    true,
+                               Computed:    true,
+                               ForceNew:    true,
+                       },
+
+                       // GPU Display
+                       "gpu_display": {
+                               Description: "Whether to display GPU in UI or 
not",
                                Type:        schema.TypeBool,
                                Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
                                ForceNew:    true,
                        },
-                       "storage_tags": {
-                               Description: "Storage tags to associate with 
the service offering",
+
+                       // High Priority Parameters
+                       "limit_cpu_use": {
+                               Description: "Restrict CPU usage to the service 
offering value",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "is_volatile": {
+                               Description: "True if the virtual machine needs 
to be volatile (root disk destroyed on stop)",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "customized_iops": {
+                               Description: "Whether compute offering iops is 
custom or not",
+                               Type:        schema.TypeBool,
+                               Optional:    true,
+                               Computed:    true, // CloudStack returns 
default value
+                               ForceNew:    true,
+                       },
+
+                       "tags": {
+                               Description: "Comma-separated list of tags for 
the service offering",
                                Type:        schema.TypeString,
                                Optional:    true,
+                               ForceNew:    true,
                        },

Review Comment:
   This PR replaces the previous storage_tags field with tags, but the 
description still reads like generic service offering tags. In this provider, 
tags appears to be used for storage pool matching (CloudStack storagetags), 
which is also what the data source populates. The schema description should be 
updated to prevent confusing/incorrect usage.



##########
website/docs/r/service_offering.html.markdown:
##########
@@ -1,107 +1,406 @@
 ---
 layout: default
-title: "CloudStack: cloudstack_service_offering"
+page_title: "CloudStack: cloudstack_service_offering"
 sidebar_current: "docs-cloudstack-resource-service_offering"
 description: |-
-    Creates a Service Offering
+    Creates and manages a Service Offering in CloudStack
 ---
 
-# CloudStack: cloudstack_service_offering
+# cloudstack_service_offering
 
-A `cloudstack_service_offering` resource manages a service offering within 
CloudStack.
+Provides a CloudStack Service Offering resource. This resource can be used to 
create, modify, and delete service offerings that define the compute resources 
(CPU, memory, storage) available to virtual machines.
+
+## Understanding CloudStack Service Offering Types
+
+CloudStack supports **three types** of service offerings based on the 
`customized` parameter and how CPU/memory are configured:
+
+### 1. Fixed Offering (Fixed CPU and Memory)
+
+Users **cannot** change CPU or memory when deploying VMs. The values are fixed.
+
+**How to create:** Specify both `cpu_number` AND `memory` (do NOT set 
`customized`).
+
+```hcl
+resource "cloudstack_service_offering" "fixed" {
+  name         = "small-fixed"
+  display_text = "Small Fixed Instance - 2 CPU, 4GB RAM"
+  cpu_number   = 2
+  cpu_speed    = 2000
+  memory       = 4096
+  # customized is automatically set to false
+}
+```
+
+### 2. Custom Constrained Offering (User Choice with Limits)
+
+Users **can** choose CPU and memory **within** the min/max limits you define.
+
+**How to create:** Set `customized = true` AND specify min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "constrained" {
+  name           = "custom-constrained"
+  display_text   = "Custom Constrained - Choose between 2-8 CPU, 2-16GB RAM"
+  customized     = true
+  min_cpu_number = 2
+  max_cpu_number = 8
+  min_memory     = 2048  # 2 GB
+  max_memory     = 16384 # 16 GB
+}
+```
+
+### 3. Custom Unconstrained Offering (User Choice without Limits)
+
+Users **can** choose **any** CPU and memory values (no restrictions).
+
+**How to create:** Set `customized = true` WITHOUT min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "unconstrained" {
+  name         = "custom-unlimited"
+  display_text = "Custom Unlimited - Choose any CPU/RAM"
+  customized   = true
+  # No min/max limits - users have complete freedom
+}
+```
 
 ## Example Usage
 
-### Basic Service Offering
+### Basic Fixed Service Offering
 
 ```hcl
-resource "cloudstack_service_offering" "example" {
-    name = "example-service-offering"
-    display_text = "Example Service Offering"
-    cpu_number = 2
-    memory = 4096
+resource "cloudstack_service_offering" "basic" {
+  name         = "basic-offering"
+  display_text = "Basic 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"
-    }
+resource "cloudstack_service_offering" "gpu" {
+  name         = "gpu-a6000"
+  display_text = "GPU A6000 Instance"
+  cpu_number   = 8
+  memory       = 32768
+  
+  service_offering_details = {
+    pciDevice = "Group of NVIDIA A6000 GPUs"
+    vgpuType  = "A6000-8A"
+  }
+}
+```
+
+### GPU Service Offering with Direct GPU Parameters
+
+```hcl
+resource "cloudstack_service_offering" "tesla_p100_passthrough" {
+  name         = "tesla-p100-passthrough"
+  display_text = "Tesla P100 GPU - 2 vCPU, 1GB RAM (Passthrough Mode)"
+  
+  # Fixed CPU and Memory configuration
+  cpu_number   = 2
+  cpu_speed    = 1000
+  memory       = 1024  # 1 GB
+  
+  # Storage configuration
+  storage_type        = "shared"
+  provisioning_type   = "thin"
+  
+  # Performance and HA settings
+  offer_ha                = false
+  limit_cpu_use           = false
+  is_volatile             = false
+  dynamic_scaling_enabled = true
+  encrypt_root            = false
+  
+  # Cache mode
+  cache_mode = "none"
+  
+  # GPU Configuration - Direct API mapping
+  # gpu_card -> serviceofferingdetails["pciDevice"] -> resolves to gpucardid
+  # gpu_type -> SetVgpuprofileid() + serviceofferingdetails["vgpuType"] -> 
resolves to vgpuprofileid/vgpuprofilename
+  # gpu_count -> SetGpucount() -> number of GPUs
+  
+  gpu_card  = "Tesla P100 Auto Created"                      # GPU Card Name
+  gpu_type  = "8cb04cca-8395-44f8-9d1b-48eb08d48bed"         # vGPU Profile 
UUID
+  gpu_count = 1                                               # Number of GPUs
 }
 ```
 
+### High Performance with IOPS Limits
+
+```hcl
+resource "cloudstack_service_offering" "high_performance" {
+  name                = "high-performance"
+  display_text        = "High Performance Instance"
+  cpu_number          = 4
+  memory              = 8192
+  storage_type        = "shared"
+  
+  # IOPS configuration
+  bytes_read_rate     = 10485760  # 10 MB/s
+  bytes_write_rate    = 10485760  # 10 MB/s
+  iops_read_rate      = 1000
+  iops_write_rate     = 1000
+  
+  # Additional settings
+  offer_ha            = true
+  limit_cpu_use       = true
+  host_tags           = "high-performance"
+  storage_tags        = "ssd"
+}
+```
+
+### Dynamic Scaling Enabled
+
+```hcl
+resource "cloudstack_service_offering" "scalable" {
+  name                    = "scalable-offering"
+  display_text            = "Dynamically Scalable Instance"
+  cpu_number              = 4
+  memory                  = 8192
+  dynamic_scaling_enabled = true
+  disk_iops_min           = 500
+  disk_iops_max           = 2000
+}
+```
 
 ## Argument Reference
 
 The following arguments are supported:
 
-* `name` - (Required) Name of the service offering.
-    Changing this forces a new resource to be created.
+### Required Arguments
+
+* `name` - (Required) The name of the service offering. Changing this forces a 
new resource to be created.
+
+### Basic Configuration
+
+* `display_text` - (Optional) The display text of the service offering. If not 
provided, defaults to the name.
+
+### CPU and Memory Configuration
+
+* `cpu_number` - (Optional) The number of CPU cores. **Note:** When specified 
together with `memory`, creates a **Fixed Offering** (users cannot change 
CPU/memory). Changing this forces a new resource to be created.
+
+* `cpu_speed` - (Optional) The clock rate of the CPU cores in MHz. Changing 
this forces a new resource to be created.
+
+* `memory` - (Optional) The total memory for the service offering in MB. 
**Note:** When specified together with `cpu_number`, creates a **Fixed 
Offering** (users cannot change CPU/memory). Changing this forces a new 
resource to be created.
+
+### Customization Options (Choose Offering Type)
+
+* `customized` - (Optional) Controls whether users can choose CPU and memory 
when deploying VMs:
+  - **Not set** + `cpu_number` + `memory` specified = **Fixed Offering** (no 
user choice)
+  - **`true`** + min/max limits = **Custom Constrained** (user choice within 
limits)
+  - **`true`** + no limits = **Custom Unconstrained** (any user choice)
+  
+  Changing this forces a new resource to be created.
+
+* `customized_iops` - (Optional) Whether compute offering IOPS should be 
customizable. Changing this forces a new resource to be created.
+
+### Custom Constrained Limits
+
+Use these **only** when `customized = true` to set boundaries:
+
+* `min_cpu_number` - (Optional) Minimum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `max_cpu_number` - (Optional) Maximum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `min_memory` - (Optional) Minimum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+* `max_memory` - (Optional) Maximum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+### Storage Configuration
+
+* `storage_type` - (Optional) The storage type of the service offering. Valid 
values are `local` and `shared`. Changing this forces a new resource to be 
created.
+
+* `storage_tags` - (Optional) Comma-separated list of tags for matching 
storage pools. Changing this forces a new resource to be created.
 
-* `display_text` - (Optional) The display text of the service offering.
+* `host_tags` - (Optional) Comma-separated list of tags for matching hosts. 
Changing this forces a new resource to be created.
 
-* `cpu_number` - (Optional) The number of CPU cores.
-    Changing this forces a new resource to be created.
+* `root_disk_size` - (Optional) The root disk size in GB. Changing this forces 
a new resource to be created.
 
-* `cpu_speed` - (Optional) The speed of the CPU in Mhz.
-    Changing this forces a new resource to be created.
+* `encrypt_root` - (Optional) Whether to encrypt the root disk. Changing this 
forces a new resource to be created.
 
-* `memory` - (Optional) Memory reserved by the VM in MB.
-    Changing this forces a new resource to be created.
+### GPU Configuration
 
-* `host_tags` - (Optional) The host tags for the service offering.
+* `gpu_card` - (Optional) The GPU card name for GPU-enabled service offerings. 
This maps to `serviceofferingdetails["pciDevice"]` and CloudStack automatically 
resolves it to `gpucardid`. Example: `"Tesla P100 Auto Created"`. Changing this 
forces a new resource to be created.
 
-* `limit_cpu_use` - (Optional) Restrict the CPU usage to committed service 
offering.
-    Changing this forces a new resource to be created.
+* `gpu_type` - (Optional) The vGPU profile UUID or type for GPU-enabled 
service offerings. This parameter serves dual purposes:
+  - Sets the vGPU profile ID via `SetVgpuprofileid()` API parameter
+  - Populates `serviceofferingdetails["vgpuType"]`
+  - CloudStack uses this to determine both `vgpuprofileid` and 
`vgpuprofilename`
+  
+  Example: `"8cb04cca-8395-44f8-9d1b-48eb08d48bed"` for passthrough mode. 
Changing this forces a new resource to be created.
 
-* `offer_ha` - (Optional) The HA for the service offering.
-    Changing this forces a new resource to be created.
+* `gpu_count` - (Optional) The number of GPUs to allocate for this service 
offering. Maps directly to `SetGpucount()` API parameter. Default is `1` if not 
specified. Changing this forces a new resource to be created.
 
-* `storage_type` - (Optional) The storage type of the service offering. Values 
are `local` and `shared`.
-    Changing this forces a new resource to be created.
+~> **Note:** For GPU offerings, ensure your CloudStack hosts are properly 
configured with GPU passthrough and that the GPU card names and vGPU profile 
UUIDs match your physical GPU configuration.
 
-* `customized` - (Optional) Whether the service offering allows custom CPU and 
memory values. Set to `true` to enable users to specify CPU/memory within the 
min/max constraints for constrained offerings and any value for unconstrained 
offerings.
-    Changing this forces a new resource to be created.
+### IOPS and Bandwidth Limits
 
-* `min_cpu_number` - (Optional) Minimum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+~> **Note:** All IOPS and bandwidth parameters are immutable after creation. 
Any changes will force recreation of the service offering.
 
-* `max_cpu_number` - (Optional) Maximum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate` - (Optional) Bytes read rate in bytes per second. Changing 
this forces a new resource to be created.
 
-* `min_memory` - (Optional) Minimum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max` - (Optional) Burst bytes read rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `max_memory` - (Optional) Maximum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max_length` - (Optional) Length of the burst bytes read 
rate in seconds. Changing this forces a new resource to be created.

Review Comment:
   The IOPS/Bandwidth argument list documents bytes_read_rate/bytes_write_rate 
and their max variants, but the implemented schema uses 
disk_bytes_read_rate/disk_bytes_write_rate (and disk_bytes_*_max) along with 
bytes_*_max_length. The current names won't work.



##########
website/docs/r/service_offering.html.markdown:
##########
@@ -1,107 +1,406 @@
 ---
 layout: default
-title: "CloudStack: cloudstack_service_offering"
+page_title: "CloudStack: cloudstack_service_offering"
 sidebar_current: "docs-cloudstack-resource-service_offering"
 description: |-
-    Creates a Service Offering
+    Creates and manages a Service Offering in CloudStack
 ---
 
-# CloudStack: cloudstack_service_offering
+# cloudstack_service_offering
 
-A `cloudstack_service_offering` resource manages a service offering within 
CloudStack.
+Provides a CloudStack Service Offering resource. This resource can be used to 
create, modify, and delete service offerings that define the compute resources 
(CPU, memory, storage) available to virtual machines.
+
+## Understanding CloudStack Service Offering Types
+
+CloudStack supports **three types** of service offerings based on the 
`customized` parameter and how CPU/memory are configured:
+
+### 1. Fixed Offering (Fixed CPU and Memory)
+
+Users **cannot** change CPU or memory when deploying VMs. The values are fixed.
+
+**How to create:** Specify both `cpu_number` AND `memory` (do NOT set 
`customized`).
+
+```hcl
+resource "cloudstack_service_offering" "fixed" {
+  name         = "small-fixed"
+  display_text = "Small Fixed Instance - 2 CPU, 4GB RAM"
+  cpu_number   = 2
+  cpu_speed    = 2000
+  memory       = 4096
+  # customized is automatically set to false
+}
+```
+
+### 2. Custom Constrained Offering (User Choice with Limits)
+
+Users **can** choose CPU and memory **within** the min/max limits you define.
+
+**How to create:** Set `customized = true` AND specify min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "constrained" {
+  name           = "custom-constrained"
+  display_text   = "Custom Constrained - Choose between 2-8 CPU, 2-16GB RAM"
+  customized     = true
+  min_cpu_number = 2
+  max_cpu_number = 8
+  min_memory     = 2048  # 2 GB
+  max_memory     = 16384 # 16 GB
+}
+```
+
+### 3. Custom Unconstrained Offering (User Choice without Limits)
+
+Users **can** choose **any** CPU and memory values (no restrictions).
+
+**How to create:** Set `customized = true` WITHOUT min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "unconstrained" {
+  name         = "custom-unlimited"
+  display_text = "Custom Unlimited - Choose any CPU/RAM"
+  customized   = true
+  # No min/max limits - users have complete freedom
+}
+```
 
 ## Example Usage
 
-### Basic Service Offering
+### Basic Fixed Service Offering
 
 ```hcl
-resource "cloudstack_service_offering" "example" {
-    name = "example-service-offering"
-    display_text = "Example Service Offering"
-    cpu_number = 2
-    memory = 4096
+resource "cloudstack_service_offering" "basic" {
+  name         = "basic-offering"
+  display_text = "Basic 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"
-    }
+resource "cloudstack_service_offering" "gpu" {
+  name         = "gpu-a6000"
+  display_text = "GPU A6000 Instance"
+  cpu_number   = 8
+  memory       = 32768
+  
+  service_offering_details = {
+    pciDevice = "Group of NVIDIA A6000 GPUs"
+    vgpuType  = "A6000-8A"
+  }
+}
+```
+
+### GPU Service Offering with Direct GPU Parameters
+
+```hcl
+resource "cloudstack_service_offering" "tesla_p100_passthrough" {
+  name         = "tesla-p100-passthrough"
+  display_text = "Tesla P100 GPU - 2 vCPU, 1GB RAM (Passthrough Mode)"
+  
+  # Fixed CPU and Memory configuration
+  cpu_number   = 2
+  cpu_speed    = 1000
+  memory       = 1024  # 1 GB
+  
+  # Storage configuration
+  storage_type        = "shared"
+  provisioning_type   = "thin"
+  
+  # Performance and HA settings
+  offer_ha                = false
+  limit_cpu_use           = false
+  is_volatile             = false
+  dynamic_scaling_enabled = true
+  encrypt_root            = false
+  
+  # Cache mode
+  cache_mode = "none"
+  
+  # GPU Configuration - Direct API mapping
+  # gpu_card -> serviceofferingdetails["pciDevice"] -> resolves to gpucardid
+  # gpu_type -> SetVgpuprofileid() + serviceofferingdetails["vgpuType"] -> 
resolves to vgpuprofileid/vgpuprofilename
+  # gpu_count -> SetGpucount() -> number of GPUs
+  
+  gpu_card  = "Tesla P100 Auto Created"                      # GPU Card Name
+  gpu_type  = "8cb04cca-8395-44f8-9d1b-48eb08d48bed"         # vGPU Profile 
UUID
+  gpu_count = 1                                               # Number of GPUs
 }
 ```
 
+### High Performance with IOPS Limits
+
+```hcl
+resource "cloudstack_service_offering" "high_performance" {
+  name                = "high-performance"
+  display_text        = "High Performance Instance"
+  cpu_number          = 4
+  memory              = 8192
+  storage_type        = "shared"
+  
+  # IOPS configuration
+  bytes_read_rate     = 10485760  # 10 MB/s
+  bytes_write_rate    = 10485760  # 10 MB/s
+  iops_read_rate      = 1000
+  iops_write_rate     = 1000
+  
+  # Additional settings
+  offer_ha            = true
+  limit_cpu_use       = true
+  host_tags           = "high-performance"
+  storage_tags        = "ssd"
+}

Review Comment:
   The High Performance example uses argument names 
(bytes_read_rate/iops_read_rate/storage_tags) that do not exist in the resource 
schema implemented in this PR. The resource uses disk_bytes_* and disk_iops_* 
names, and the storage-pool tag argument is tags (not storage_tags).



##########
website/docs/r/service_offering.html.markdown:
##########
@@ -1,107 +1,406 @@
 ---
 layout: default
-title: "CloudStack: cloudstack_service_offering"
+page_title: "CloudStack: cloudstack_service_offering"
 sidebar_current: "docs-cloudstack-resource-service_offering"
 description: |-
-    Creates a Service Offering
+    Creates and manages a Service Offering in CloudStack
 ---
 
-# CloudStack: cloudstack_service_offering
+# cloudstack_service_offering
 
-A `cloudstack_service_offering` resource manages a service offering within 
CloudStack.
+Provides a CloudStack Service Offering resource. This resource can be used to 
create, modify, and delete service offerings that define the compute resources 
(CPU, memory, storage) available to virtual machines.
+
+## Understanding CloudStack Service Offering Types
+
+CloudStack supports **three types** of service offerings based on the 
`customized` parameter and how CPU/memory are configured:
+
+### 1. Fixed Offering (Fixed CPU and Memory)
+
+Users **cannot** change CPU or memory when deploying VMs. The values are fixed.
+
+**How to create:** Specify both `cpu_number` AND `memory` (do NOT set 
`customized`).
+
+```hcl
+resource "cloudstack_service_offering" "fixed" {
+  name         = "small-fixed"
+  display_text = "Small Fixed Instance - 2 CPU, 4GB RAM"
+  cpu_number   = 2
+  cpu_speed    = 2000
+  memory       = 4096
+  # customized is automatically set to false
+}
+```
+
+### 2. Custom Constrained Offering (User Choice with Limits)
+
+Users **can** choose CPU and memory **within** the min/max limits you define.
+
+**How to create:** Set `customized = true` AND specify min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "constrained" {
+  name           = "custom-constrained"
+  display_text   = "Custom Constrained - Choose between 2-8 CPU, 2-16GB RAM"
+  customized     = true
+  min_cpu_number = 2
+  max_cpu_number = 8
+  min_memory     = 2048  # 2 GB
+  max_memory     = 16384 # 16 GB
+}
+```
+
+### 3. Custom Unconstrained Offering (User Choice without Limits)
+
+Users **can** choose **any** CPU and memory values (no restrictions).
+
+**How to create:** Set `customized = true` WITHOUT min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "unconstrained" {
+  name         = "custom-unlimited"
+  display_text = "Custom Unlimited - Choose any CPU/RAM"
+  customized   = true
+  # No min/max limits - users have complete freedom
+}
+```
 
 ## Example Usage
 
-### Basic Service Offering
+### Basic Fixed Service Offering
 
 ```hcl
-resource "cloudstack_service_offering" "example" {
-    name = "example-service-offering"
-    display_text = "Example Service Offering"
-    cpu_number = 2
-    memory = 4096
+resource "cloudstack_service_offering" "basic" {
+  name         = "basic-offering"
+  display_text = "Basic 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"
-    }
+resource "cloudstack_service_offering" "gpu" {
+  name         = "gpu-a6000"
+  display_text = "GPU A6000 Instance"
+  cpu_number   = 8
+  memory       = 32768
+  
+  service_offering_details = {
+    pciDevice = "Group of NVIDIA A6000 GPUs"
+    vgpuType  = "A6000-8A"
+  }
+}
+```
+
+### GPU Service Offering with Direct GPU Parameters
+
+```hcl
+resource "cloudstack_service_offering" "tesla_p100_passthrough" {
+  name         = "tesla-p100-passthrough"
+  display_text = "Tesla P100 GPU - 2 vCPU, 1GB RAM (Passthrough Mode)"
+  
+  # Fixed CPU and Memory configuration
+  cpu_number   = 2
+  cpu_speed    = 1000
+  memory       = 1024  # 1 GB
+  
+  # Storage configuration
+  storage_type        = "shared"
+  provisioning_type   = "thin"
+  
+  # Performance and HA settings
+  offer_ha                = false
+  limit_cpu_use           = false
+  is_volatile             = false
+  dynamic_scaling_enabled = true
+  encrypt_root            = false
+  
+  # Cache mode
+  cache_mode = "none"
+  
+  # GPU Configuration - Direct API mapping
+  # gpu_card -> serviceofferingdetails["pciDevice"] -> resolves to gpucardid
+  # gpu_type -> SetVgpuprofileid() + serviceofferingdetails["vgpuType"] -> 
resolves to vgpuprofileid/vgpuprofilename
+  # gpu_count -> SetGpucount() -> number of GPUs
+  
+  gpu_card  = "Tesla P100 Auto Created"                      # GPU Card Name
+  gpu_type  = "8cb04cca-8395-44f8-9d1b-48eb08d48bed"         # vGPU Profile 
UUID
+  gpu_count = 1                                               # Number of GPUs
 }
 ```
 
+### High Performance with IOPS Limits
+
+```hcl
+resource "cloudstack_service_offering" "high_performance" {
+  name                = "high-performance"
+  display_text        = "High Performance Instance"
+  cpu_number          = 4
+  memory              = 8192
+  storage_type        = "shared"
+  
+  # IOPS configuration
+  bytes_read_rate     = 10485760  # 10 MB/s
+  bytes_write_rate    = 10485760  # 10 MB/s
+  iops_read_rate      = 1000
+  iops_write_rate     = 1000
+  
+  # Additional settings
+  offer_ha            = true
+  limit_cpu_use       = true
+  host_tags           = "high-performance"
+  storage_tags        = "ssd"
+}
+```
+
+### Dynamic Scaling Enabled
+
+```hcl
+resource "cloudstack_service_offering" "scalable" {
+  name                    = "scalable-offering"
+  display_text            = "Dynamically Scalable Instance"
+  cpu_number              = 4
+  memory                  = 8192
+  dynamic_scaling_enabled = true
+  disk_iops_min           = 500
+  disk_iops_max           = 2000
+}
+```
 
 ## Argument Reference
 
 The following arguments are supported:
 
-* `name` - (Required) Name of the service offering.
-    Changing this forces a new resource to be created.
+### Required Arguments
+
+* `name` - (Required) The name of the service offering. Changing this forces a 
new resource to be created.
+
+### Basic Configuration
+
+* `display_text` - (Optional) The display text of the service offering. If not 
provided, defaults to the name.
+
+### CPU and Memory Configuration
+
+* `cpu_number` - (Optional) The number of CPU cores. **Note:** When specified 
together with `memory`, creates a **Fixed Offering** (users cannot change 
CPU/memory). Changing this forces a new resource to be created.
+
+* `cpu_speed` - (Optional) The clock rate of the CPU cores in MHz. Changing 
this forces a new resource to be created.
+
+* `memory` - (Optional) The total memory for the service offering in MB. 
**Note:** When specified together with `cpu_number`, creates a **Fixed 
Offering** (users cannot change CPU/memory). Changing this forces a new 
resource to be created.
+
+### Customization Options (Choose Offering Type)
+
+* `customized` - (Optional) Controls whether users can choose CPU and memory 
when deploying VMs:
+  - **Not set** + `cpu_number` + `memory` specified = **Fixed Offering** (no 
user choice)
+  - **`true`** + min/max limits = **Custom Constrained** (user choice within 
limits)
+  - **`true`** + no limits = **Custom Unconstrained** (any user choice)
+  
+  Changing this forces a new resource to be created.
+
+* `customized_iops` - (Optional) Whether compute offering IOPS should be 
customizable. Changing this forces a new resource to be created.
+
+### Custom Constrained Limits
+
+Use these **only** when `customized = true` to set boundaries:
+
+* `min_cpu_number` - (Optional) Minimum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `max_cpu_number` - (Optional) Maximum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `min_memory` - (Optional) Minimum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+* `max_memory` - (Optional) Maximum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+### Storage Configuration
+
+* `storage_type` - (Optional) The storage type of the service offering. Valid 
values are `local` and `shared`. Changing this forces a new resource to be 
created.
+
+* `storage_tags` - (Optional) Comma-separated list of tags for matching 
storage pools. Changing this forces a new resource to be created.
 
-* `display_text` - (Optional) The display text of the service offering.
+* `host_tags` - (Optional) Comma-separated list of tags for matching hosts. 
Changing this forces a new resource to be created.
 
-* `cpu_number` - (Optional) The number of CPU cores.
-    Changing this forces a new resource to be created.
+* `root_disk_size` - (Optional) The root disk size in GB. Changing this forces 
a new resource to be created.
 
-* `cpu_speed` - (Optional) The speed of the CPU in Mhz.
-    Changing this forces a new resource to be created.
+* `encrypt_root` - (Optional) Whether to encrypt the root disk. Changing this 
forces a new resource to be created.
 
-* `memory` - (Optional) Memory reserved by the VM in MB.
-    Changing this forces a new resource to be created.
+### GPU Configuration
 
-* `host_tags` - (Optional) The host tags for the service offering.
+* `gpu_card` - (Optional) The GPU card name for GPU-enabled service offerings. 
This maps to `serviceofferingdetails["pciDevice"]` and CloudStack automatically 
resolves it to `gpucardid`. Example: `"Tesla P100 Auto Created"`. Changing this 
forces a new resource to be created.
 
-* `limit_cpu_use` - (Optional) Restrict the CPU usage to committed service 
offering.
-    Changing this forces a new resource to be created.
+* `gpu_type` - (Optional) The vGPU profile UUID or type for GPU-enabled 
service offerings. This parameter serves dual purposes:
+  - Sets the vGPU profile ID via `SetVgpuprofileid()` API parameter
+  - Populates `serviceofferingdetails["vgpuType"]`
+  - CloudStack uses this to determine both `vgpuprofileid` and 
`vgpuprofilename`
+  
+  Example: `"8cb04cca-8395-44f8-9d1b-48eb08d48bed"` for passthrough mode. 
Changing this forces a new resource to be created.
 
-* `offer_ha` - (Optional) The HA for the service offering.
-    Changing this forces a new resource to be created.
+* `gpu_count` - (Optional) The number of GPUs to allocate for this service 
offering. Maps directly to `SetGpucount()` API parameter. Default is `1` if not 
specified. Changing this forces a new resource to be created.
 
-* `storage_type` - (Optional) The storage type of the service offering. Values 
are `local` and `shared`.
-    Changing this forces a new resource to be created.
+~> **Note:** For GPU offerings, ensure your CloudStack hosts are properly 
configured with GPU passthrough and that the GPU card names and vGPU profile 
UUIDs match your physical GPU configuration.
 
-* `customized` - (Optional) Whether the service offering allows custom CPU and 
memory values. Set to `true` to enable users to specify CPU/memory within the 
min/max constraints for constrained offerings and any value for unconstrained 
offerings.
-    Changing this forces a new resource to be created.
+### IOPS and Bandwidth Limits
 
-* `min_cpu_number` - (Optional) Minimum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+~> **Note:** All IOPS and bandwidth parameters are immutable after creation. 
Any changes will force recreation of the service offering.
 
-* `max_cpu_number` - (Optional) Maximum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate` - (Optional) Bytes read rate in bytes per second. Changing 
this forces a new resource to be created.
 
-* `min_memory` - (Optional) Minimum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max` - (Optional) Burst bytes read rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `max_memory` - (Optional) Maximum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max_length` - (Optional) Length of the burst bytes read 
rate in seconds. Changing this forces a new resource to be created.
 
-* `encrypt_root` - (Optional) Whether to encrypt the root disk for VMs using 
this service offering.
-    Changing this forces a new resource to be created.
+* `bytes_write_rate` - (Optional) Bytes write rate in bytes per second. 
Changing this forces a new resource to be created.
 
-* `storage_tags` - (Optional) Storage tags to associate with the service 
offering.
+* `bytes_write_rate_max` - (Optional) Burst bytes write rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `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.
+* `bytes_write_rate_max_length` - (Optional) Length of the burst bytes write 
rate in seconds. Changing this forces a new resource to be created.
+
+* `iops_read_rate` - (Optional) IO requests read rate in IOPS. Changing this 
forces a new resource to be created.
+
+* `iops_read_rate_max` - (Optional) Burst IO requests read rate in IOPS. 
Changing this forces a new resource to be created.
+
+* `iops_read_rate_max_length` - (Optional) Length of the burst IO requests 
read rate in seconds. Changing this forces a new resource to be created.
+
+* `iops_write_rate` - (Optional) IO requests write rate in IOPS. Changing this 
forces a new resource to be created.
+
+* `iops_write_rate_max` - (Optional) Burst IO requests write rate in IOPS. 
Changing this forces a new resource to be created.
+
+* `iops_write_rate_max_length` - (Optional) Length of the burst IO requests 
write rate in seconds. Changing this forces a new resource to be created.
+
+### Dynamic Scaling and IOPS
+
+* `disk_iops_min` - (Optional) Minimum IOPS for the disk. Changing this forces 
a new resource to be created.
+
+* `disk_iops_max` - (Optional) Maximum IOPS for the disk. Changing this forces 
a new resource to be created.
+

Review Comment:
   The docs refer to disk_iops_min/disk_iops_max, but the implemented schema 
uses min_iops/max_iops. The documented names won't work.



##########
website/docs/r/service_offering.html.markdown:
##########
@@ -1,107 +1,406 @@
 ---
 layout: default
-title: "CloudStack: cloudstack_service_offering"
+page_title: "CloudStack: cloudstack_service_offering"
 sidebar_current: "docs-cloudstack-resource-service_offering"
 description: |-
-    Creates a Service Offering
+    Creates and manages a Service Offering in CloudStack
 ---
 
-# CloudStack: cloudstack_service_offering
+# cloudstack_service_offering
 
-A `cloudstack_service_offering` resource manages a service offering within 
CloudStack.
+Provides a CloudStack Service Offering resource. This resource can be used to 
create, modify, and delete service offerings that define the compute resources 
(CPU, memory, storage) available to virtual machines.
+
+## Understanding CloudStack Service Offering Types
+
+CloudStack supports **three types** of service offerings based on the 
`customized` parameter and how CPU/memory are configured:
+
+### 1. Fixed Offering (Fixed CPU and Memory)
+
+Users **cannot** change CPU or memory when deploying VMs. The values are fixed.
+
+**How to create:** Specify both `cpu_number` AND `memory` (do NOT set 
`customized`).
+
+```hcl
+resource "cloudstack_service_offering" "fixed" {
+  name         = "small-fixed"
+  display_text = "Small Fixed Instance - 2 CPU, 4GB RAM"
+  cpu_number   = 2
+  cpu_speed    = 2000
+  memory       = 4096
+  # customized is automatically set to false
+}
+```
+
+### 2. Custom Constrained Offering (User Choice with Limits)
+
+Users **can** choose CPU and memory **within** the min/max limits you define.
+
+**How to create:** Set `customized = true` AND specify min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "constrained" {
+  name           = "custom-constrained"
+  display_text   = "Custom Constrained - Choose between 2-8 CPU, 2-16GB RAM"
+  customized     = true
+  min_cpu_number = 2
+  max_cpu_number = 8
+  min_memory     = 2048  # 2 GB
+  max_memory     = 16384 # 16 GB
+}
+```
+
+### 3. Custom Unconstrained Offering (User Choice without Limits)
+
+Users **can** choose **any** CPU and memory values (no restrictions).
+
+**How to create:** Set `customized = true` WITHOUT min/max constraints.
+
+```hcl
+resource "cloudstack_service_offering" "unconstrained" {
+  name         = "custom-unlimited"
+  display_text = "Custom Unlimited - Choose any CPU/RAM"
+  customized   = true
+  # No min/max limits - users have complete freedom
+}
+```
 
 ## Example Usage
 
-### Basic Service Offering
+### Basic Fixed Service Offering
 
 ```hcl
-resource "cloudstack_service_offering" "example" {
-    name = "example-service-offering"
-    display_text = "Example Service Offering"
-    cpu_number = 2
-    memory = 4096
+resource "cloudstack_service_offering" "basic" {
+  name         = "basic-offering"
+  display_text = "Basic 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"
-    }
+resource "cloudstack_service_offering" "gpu" {
+  name         = "gpu-a6000"
+  display_text = "GPU A6000 Instance"
+  cpu_number   = 8
+  memory       = 32768
+  
+  service_offering_details = {
+    pciDevice = "Group of NVIDIA A6000 GPUs"
+    vgpuType  = "A6000-8A"
+  }
+}
+```
+
+### GPU Service Offering with Direct GPU Parameters
+
+```hcl
+resource "cloudstack_service_offering" "tesla_p100_passthrough" {
+  name         = "tesla-p100-passthrough"
+  display_text = "Tesla P100 GPU - 2 vCPU, 1GB RAM (Passthrough Mode)"
+  
+  # Fixed CPU and Memory configuration
+  cpu_number   = 2
+  cpu_speed    = 1000
+  memory       = 1024  # 1 GB
+  
+  # Storage configuration
+  storage_type        = "shared"
+  provisioning_type   = "thin"
+  
+  # Performance and HA settings
+  offer_ha                = false
+  limit_cpu_use           = false
+  is_volatile             = false
+  dynamic_scaling_enabled = true
+  encrypt_root            = false
+  
+  # Cache mode
+  cache_mode = "none"
+  
+  # GPU Configuration - Direct API mapping
+  # gpu_card -> serviceofferingdetails["pciDevice"] -> resolves to gpucardid
+  # gpu_type -> SetVgpuprofileid() + serviceofferingdetails["vgpuType"] -> 
resolves to vgpuprofileid/vgpuprofilename
+  # gpu_count -> SetGpucount() -> number of GPUs
+  
+  gpu_card  = "Tesla P100 Auto Created"                      # GPU Card Name
+  gpu_type  = "8cb04cca-8395-44f8-9d1b-48eb08d48bed"         # vGPU Profile 
UUID
+  gpu_count = 1                                               # Number of GPUs
 }
 ```
 
+### High Performance with IOPS Limits
+
+```hcl
+resource "cloudstack_service_offering" "high_performance" {
+  name                = "high-performance"
+  display_text        = "High Performance Instance"
+  cpu_number          = 4
+  memory              = 8192
+  storage_type        = "shared"
+  
+  # IOPS configuration
+  bytes_read_rate     = 10485760  # 10 MB/s
+  bytes_write_rate    = 10485760  # 10 MB/s
+  iops_read_rate      = 1000
+  iops_write_rate     = 1000
+  
+  # Additional settings
+  offer_ha            = true
+  limit_cpu_use       = true
+  host_tags           = "high-performance"
+  storage_tags        = "ssd"
+}
+```
+
+### Dynamic Scaling Enabled
+
+```hcl
+resource "cloudstack_service_offering" "scalable" {
+  name                    = "scalable-offering"
+  display_text            = "Dynamically Scalable Instance"
+  cpu_number              = 4
+  memory                  = 8192
+  dynamic_scaling_enabled = true
+  disk_iops_min           = 500
+  disk_iops_max           = 2000
+}
+```
 
 ## Argument Reference
 
 The following arguments are supported:
 
-* `name` - (Required) Name of the service offering.
-    Changing this forces a new resource to be created.
+### Required Arguments
+
+* `name` - (Required) The name of the service offering. Changing this forces a 
new resource to be created.
+
+### Basic Configuration
+
+* `display_text` - (Optional) The display text of the service offering. If not 
provided, defaults to the name.
+
+### CPU and Memory Configuration
+
+* `cpu_number` - (Optional) The number of CPU cores. **Note:** When specified 
together with `memory`, creates a **Fixed Offering** (users cannot change 
CPU/memory). Changing this forces a new resource to be created.
+
+* `cpu_speed` - (Optional) The clock rate of the CPU cores in MHz. Changing 
this forces a new resource to be created.
+
+* `memory` - (Optional) The total memory for the service offering in MB. 
**Note:** When specified together with `cpu_number`, creates a **Fixed 
Offering** (users cannot change CPU/memory). Changing this forces a new 
resource to be created.
+
+### Customization Options (Choose Offering Type)
+
+* `customized` - (Optional) Controls whether users can choose CPU and memory 
when deploying VMs:
+  - **Not set** + `cpu_number` + `memory` specified = **Fixed Offering** (no 
user choice)
+  - **`true`** + min/max limits = **Custom Constrained** (user choice within 
limits)
+  - **`true`** + no limits = **Custom Unconstrained** (any user choice)
+  
+  Changing this forces a new resource to be created.
+
+* `customized_iops` - (Optional) Whether compute offering IOPS should be 
customizable. Changing this forces a new resource to be created.
+
+### Custom Constrained Limits
+
+Use these **only** when `customized = true` to set boundaries:
+
+* `min_cpu_number` - (Optional) Minimum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `max_cpu_number` - (Optional) Maximum number of CPU cores users can select. 
Changing this forces a new resource to be created.
+
+* `min_memory` - (Optional) Minimum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+* `max_memory` - (Optional) Maximum memory in MB users can select. Changing 
this forces a new resource to be created.
+
+### Storage Configuration
+
+* `storage_type` - (Optional) The storage type of the service offering. Valid 
values are `local` and `shared`. Changing this forces a new resource to be 
created.
+
+* `storage_tags` - (Optional) Comma-separated list of tags for matching 
storage pools. Changing this forces a new resource to be created.
 
-* `display_text` - (Optional) The display text of the service offering.
+* `host_tags` - (Optional) Comma-separated list of tags for matching hosts. 
Changing this forces a new resource to be created.
 
-* `cpu_number` - (Optional) The number of CPU cores.
-    Changing this forces a new resource to be created.
+* `root_disk_size` - (Optional) The root disk size in GB. Changing this forces 
a new resource to be created.
 
-* `cpu_speed` - (Optional) The speed of the CPU in Mhz.
-    Changing this forces a new resource to be created.
+* `encrypt_root` - (Optional) Whether to encrypt the root disk. Changing this 
forces a new resource to be created.
 
-* `memory` - (Optional) Memory reserved by the VM in MB.
-    Changing this forces a new resource to be created.
+### GPU Configuration
 
-* `host_tags` - (Optional) The host tags for the service offering.
+* `gpu_card` - (Optional) The GPU card name for GPU-enabled service offerings. 
This maps to `serviceofferingdetails["pciDevice"]` and CloudStack automatically 
resolves it to `gpucardid`. Example: `"Tesla P100 Auto Created"`. Changing this 
forces a new resource to be created.
 
-* `limit_cpu_use` - (Optional) Restrict the CPU usage to committed service 
offering.
-    Changing this forces a new resource to be created.
+* `gpu_type` - (Optional) The vGPU profile UUID or type for GPU-enabled 
service offerings. This parameter serves dual purposes:
+  - Sets the vGPU profile ID via `SetVgpuprofileid()` API parameter
+  - Populates `serviceofferingdetails["vgpuType"]`
+  - CloudStack uses this to determine both `vgpuprofileid` and 
`vgpuprofilename`
+  
+  Example: `"8cb04cca-8395-44f8-9d1b-48eb08d48bed"` for passthrough mode. 
Changing this forces a new resource to be created.
 
-* `offer_ha` - (Optional) The HA for the service offering.
-    Changing this forces a new resource to be created.
+* `gpu_count` - (Optional) The number of GPUs to allocate for this service 
offering. Maps directly to `SetGpucount()` API parameter. Default is `1` if not 
specified. Changing this forces a new resource to be created.
 
-* `storage_type` - (Optional) The storage type of the service offering. Values 
are `local` and `shared`.
-    Changing this forces a new resource to be created.
+~> **Note:** For GPU offerings, ensure your CloudStack hosts are properly 
configured with GPU passthrough and that the GPU card names and vGPU profile 
UUIDs match your physical GPU configuration.
 
-* `customized` - (Optional) Whether the service offering allows custom CPU and 
memory values. Set to `true` to enable users to specify CPU/memory within the 
min/max constraints for constrained offerings and any value for unconstrained 
offerings.
-    Changing this forces a new resource to be created.
+### IOPS and Bandwidth Limits
 
-* `min_cpu_number` - (Optional) Minimum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+~> **Note:** All IOPS and bandwidth parameters are immutable after creation. 
Any changes will force recreation of the service offering.
 
-* `max_cpu_number` - (Optional) Maximum number of CPU cores allowed for 
customized offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate` - (Optional) Bytes read rate in bytes per second. Changing 
this forces a new resource to be created.
 
-* `min_memory` - (Optional) Minimum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max` - (Optional) Burst bytes read rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `max_memory` - (Optional) Maximum memory (in MB) allowed for customized 
offerings.
-    Changing this forces a new resource to be created.
+* `bytes_read_rate_max_length` - (Optional) Length of the burst bytes read 
rate in seconds. Changing this forces a new resource to be created.
 
-* `encrypt_root` - (Optional) Whether to encrypt the root disk for VMs using 
this service offering.
-    Changing this forces a new resource to be created.
+* `bytes_write_rate` - (Optional) Bytes write rate in bytes per second. 
Changing this forces a new resource to be created.
 
-* `storage_tags` - (Optional) Storage tags to associate with the service 
offering.
+* `bytes_write_rate_max` - (Optional) Burst bytes write rate in bytes per 
second. Changing this forces a new resource to be created.
 
-* `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.
+* `bytes_write_rate_max_length` - (Optional) Length of the burst bytes write 
rate in seconds. Changing this forces a new resource to be created.
+
+* `iops_read_rate` - (Optional) IO requests read rate in IOPS. Changing this 
forces a new resource to be created.
+
+* `iops_read_rate_max` - (Optional) Burst IO requests read rate in IOPS. 
Changing this forces a new resource to be created.
+
+* `iops_read_rate_max_length` - (Optional) Length of the burst IO requests 
read rate in seconds. Changing this forces a new resource to be created.
+
+* `iops_write_rate` - (Optional) IO requests write rate in IOPS. Changing this 
forces a new resource to be created.
+
+* `iops_write_rate_max` - (Optional) Burst IO requests write rate in IOPS. 
Changing this forces a new resource to be created.
+
+* `iops_write_rate_max_length` - (Optional) Length of the burst IO requests 
write rate in seconds. Changing this forces a new resource to be created.
+
+### Dynamic Scaling and IOPS
+
+* `disk_iops_min` - (Optional) Minimum IOPS for the disk. Changing this forces 
a new resource to be created.
+
+* `disk_iops_max` - (Optional) Maximum IOPS for the disk. Changing this forces 
a new resource to be created.
+
+* `hypervisor_snapshot_reserve` - (Optional) Hypervisor snapshot reserve space 
as a percent of a volume (for managed storage using Xen or VMware). Changing 
this forces a new resource to be created.
+
+### High Availability and Performance
+
+* `offer_ha` - (Optional) Whether HA (High Availability) is enabled for the 
service offering. Changing this forces a new resource to be created.
+
+* `limit_cpu_use` - (Optional) Restrict the CPU usage to the committed service 
offering percentage. Changing this forces a new resource to be created.
+
+* `dynamic_scaling_enabled` - (Optional) Enable dynamic scaling of VM CPU and 
memory. Changing this forces a new resource to be created.
+
+### Cache and Deployment
+
+* `cache_mode` - (Optional) The cache mode to use. Valid values: `none`, 
`writeback`, `writethrough`. Changing this forces a new resource to be created.
+
+* `deployment_planner` - (Optional) The deployment planner heuristics used to 
deploy VMs. Changing this forces a new resource to be created.
+
+### System VM Configuration
+
+* `is_system` - (Optional) Whether the offering is for system VMs. Changing 
this forces a new resource to be created.
+
+* `system_vm_type` - (Optional) The system VM type. Required when `is_system` 
is true. Valid values: `domainrouter`, `consoleproxy`, `secondarystoragevm`. 
Changing this forces a new resource to be created.
+
+### Zone and Domain
+
+* `zone_id` - (Optional) The ID of the zone for which the service offering is 
available. Changing this forces a new resource to be created.
+
+* `domain_id` - (Optional) The ID of the domain for which the service offering 
is available. Changing this forces a new resource to be created.
+
+### Provisioning
+
+* `provisioning_type` - (Optional) Provisioning type used to create volumes. 
Valid values: `thin`, `sparse`, `fat`. Changing this forces a new resource to 
be created.
+
+* `is_volatile` - (Optional) If true, the VM's original root disk is destroyed 
and recreated on every reboot. Changing this forces a new resource to be 
created.
+
+### Advanced Settings
+
+* `service_offering_details` - (Optional) A map of service offering details 
for GPU configuration and other advanced settings. Common keys include:
+  - `pciDevice` - PCI device for GPU passthrough
+  - `vgpuType` - vGPU type for GPU offerings
+  
+  ~> **Note:** CloudStack may add system keys (like `External:key`, 
`purge.db.entities`) to this map. Terraform automatically filters these out to 
prevent state drift.
+  
+  Changing this forces a new resource to be created.
 
 ## Attributes Reference
 
-The following attributes are exported:
+In addition to all arguments above, the following attributes are exported:
 
 * `id` - The ID of the service offering.
+* `created` - The date when the service offering was created.
 

Review Comment:
   The docs claim a created attribute is exported by the resource, but the 
resource schema/Read implementation in this PR does not set a created field. 
This will cause confusion for users.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to