wait for asg to move to disabled state before making modifications to lb rule associated to an asg or autoscale vm profile
diff --git a/cloudstack/resource_cloudstack_autoscale_vm_profile.go b/cloudstack/resource_cloudstack_autoscale_vm_profile.go
index 5c2cf4c..0032b92 100644
--- a/cloudstack/resource_cloudstack_autoscale_vm_profile.go
+++ b/cloudstack/resource_cloudstack_autoscale_vm_profile.go
@@ -278,7 +278,9 @@
 	}
 
 	if p.Userdatadetails != "" {
-		d.Set("user_data_details", map[string]interface{}{})
+		if _, ok := d.GetOk("user_data_details"); !ok {
+			d.Set("user_data_details", map[string]interface{}{})
+		}
 	}
 
 	if p.Autoscaleuserid != "" {
@@ -308,85 +310,185 @@
 	return nil
 }
 
+// waitForVMGroupsState waits for the specified VM groups to reach the desired state
+func waitForVMGroupsState(cs *cloudstack.CloudStackClient, groupIDs []string, desiredState string) error {
+	maxRetries := 30 // 30 * 2 seconds = 60 seconds max wait
+	for i := 0; i < maxRetries; i++ {
+		allInDesiredState := true
+
+		for _, groupID := range groupIDs {
+			group, _, err := cs.AutoScale.GetAutoScaleVmGroupByID(groupID)
+			if err != nil {
+				return fmt.Errorf("Error checking state of VM group %s: %s", groupID, err)
+			}
+
+			groupInDesiredState := false
+			if desiredState == "disabled" {
+				groupInDesiredState = (group.State == "disabled")
+			} else if desiredState == "enabled" {
+				groupInDesiredState = (group.State == "enabled")
+			} else {
+				groupInDesiredState = (group.State == desiredState)
+			}
+
+			if !groupInDesiredState {
+				allInDesiredState = false
+				log.Printf("[DEBUG] VM group %s is in state '%s', waiting for '%s'", groupID, group.State, desiredState)
+				break
+			}
+		}
+
+		if allInDesiredState {
+			log.Printf("[INFO] All VM groups have reached desired state: %s", desiredState)
+			return nil
+		}
+
+		if i < maxRetries-1 {
+			log.Printf("[INFO] Waiting for VM groups to reach state '%s' (attempt %d/%d)", desiredState, i+1, maxRetries)
+			time.Sleep(2 * time.Second)
+		}
+	}
+
+	return fmt.Errorf("Timeout waiting for VM groups to reach state '%s' after %d seconds", desiredState, maxRetries*2)
+}
+
+func waitForVMGroupsToBeDisabled(cs *cloudstack.CloudStackClient, profileID string) error {
+	log.Printf("[DEBUG] Waiting for VM groups using profile %s to be disabled", profileID)
+	listParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
+	listParams.SetVmprofileid(profileID)
+
+	groups, err := cs.AutoScale.ListAutoScaleVmGroups(listParams)
+	if err != nil {
+		log.Printf("[ERROR] Failed to list VM groups for profile %s: %s", profileID, err)
+		return fmt.Errorf("Error listing autoscale VM groups: %s", err)
+	}
+
+	log.Printf("[DEBUG] Found %d VM groups using profile %s", len(groups.AutoScaleVmGroups), profileID)
+
+	var groupIDs []string
+	for _, group := range groups.AutoScaleVmGroups {
+		log.Printf("[DEBUG] VM group %s (%s) current state: %s", group.Name, group.Id, group.State)
+		groupIDs = append(groupIDs, group.Id)
+	}
+
+	if len(groupIDs) == 0 {
+		log.Printf("[DEBUG] No VM groups found using profile %s", profileID)
+		return nil
+	}
+
+	log.Printf("[INFO] Waiting for %d VM groups to be disabled for profile update", len(groupIDs))
+	if err := waitForVMGroupsState(cs, groupIDs, "disabled"); err != nil {
+		return fmt.Errorf("Autoscale VM groups must be disabled before updating profile: %s", err)
+	}
+
+	log.Printf("[DEBUG] All VM groups are now disabled for profile %s", profileID)
+	return nil
+}
+
 func resourceCloudStackAutoScaleVMProfileUpdate(d *schema.ResourceData, meta interface{}) error {
 	cs := meta.(*cloudstack.CloudStackClient)
-
-	p := cs.AutoScale.NewUpdateAutoScaleVmProfileParams(d.Id())
-
-	if d.HasChange("template") {
-		zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string))
-		if e != nil {
-			return e.Error()
+	log.Printf("[DEBUG] Profile update requested for ID: %s", d.Id())
+	for _, key := range []string{"template", "destroy_vm_grace_period", "counter_param_list", "user_data", "user_data_id", "user_data_details", "autoscale_user_id", "display", "metadata"} {
+		if d.HasChange(key) {
+			old, new := d.GetChange(key)
+			log.Printf("[DEBUG] Field '%s' changed from %v to %v", key, old, new)
 		}
-		templateid, e := retrieveTemplateID(cs, zoneid, d.Get("template").(string))
-		if e != nil {
-			return e.Error()
-		}
-		p.SetTemplateid(templateid)
 	}
 
-	if d.HasChange("destroy_vm_grace_period") {
-		if v, ok := d.GetOk("destroy_vm_grace_period"); ok {
-			duration, err := time.ParseDuration(v.(string))
-			if err != nil {
-				return err
+	// Check if we only have metadata changes (which don't require CloudStack API update)
+	onlyMetadataChanges := d.HasChange("metadata") &&
+		!d.HasChange("template") &&
+		!d.HasChange("destroy_vm_grace_period") &&
+		!d.HasChange("counter_param_list") &&
+		!d.HasChange("user_data") &&
+		!d.HasChange("user_data_id") &&
+		!d.HasChange("user_data_details") &&
+		!d.HasChange("autoscale_user_id") &&
+		!d.HasChange("display")
+
+	if !onlyMetadataChanges {
+		if err := waitForVMGroupsToBeDisabled(cs, d.Id()); err != nil {
+			return fmt.Errorf("Autoscale VM groups must be disabled before updating profile: %s", err)
+		}
+
+		p := cs.AutoScale.NewUpdateAutoScaleVmProfileParams(d.Id())
+
+		if d.HasChange("template") {
+			zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string))
+			if e != nil {
+				return e.Error()
 			}
-			p.SetExpungevmgraceperiod(int(duration.Seconds()))
-		}
-	}
-
-	if d.HasChange("counter_param_list") {
-		if v, ok := d.GetOk("counter_param_list"); ok {
-			nv := make(map[string]string)
-			for k, v := range v.(map[string]interface{}) {
-				nv[k] = v.(string)
+			templateid, e := retrieveTemplateID(cs, zoneid, d.Get("template").(string))
+			if e != nil {
+				return e.Error()
 			}
-			p.SetCounterparam(nv)
+			p.SetTemplateid(templateid)
 		}
-	}
 
-	if d.HasChange("user_data") {
-		if v, ok := d.GetOk("user_data"); ok {
-			p.SetUserdata(v.(string))
-		}
-	}
-
-	if d.HasChange("user_data_id") {
-		if v, ok := d.GetOk("user_data_id"); ok {
-			p.SetUserdataid(v.(string))
-		}
-	}
-
-	if d.HasChange("user_data_details") {
-		if v, ok := d.GetOk("user_data_details"); ok {
-			nv := make(map[string]string)
-			for k, v := range v.(map[string]interface{}) {
-				nv[k] = v.(string)
+		if d.HasChange("destroy_vm_grace_period") {
+			if v, ok := d.GetOk("destroy_vm_grace_period"); ok {
+				duration, err := time.ParseDuration(v.(string))
+				if err != nil {
+					return err
+				}
+				p.SetExpungevmgraceperiod(int(duration.Seconds()))
 			}
-			p.SetUserdatadetails(nv)
 		}
-	}
 
-	if d.HasChange("autoscale_user_id") {
-		if v, ok := d.GetOk("autoscale_user_id"); ok {
-			p.SetAutoscaleuserid(v.(string))
+		if d.HasChange("counter_param_list") {
+			if v, ok := d.GetOk("counter_param_list"); ok {
+				nv := make(map[string]string)
+				for k, v := range v.(map[string]interface{}) {
+					nv[k] = v.(string)
+				}
+				p.SetCounterparam(nv)
+			}
 		}
-	}
 
-	if d.HasChange("display") {
-		if v, ok := d.GetOk("display"); ok {
-			p.SetFordisplay(v.(bool))
+		if d.HasChange("user_data") {
+			if v, ok := d.GetOk("user_data"); ok {
+				p.SetUserdata(v.(string))
+			}
 		}
-	}
 
-	_, err := cs.AutoScale.UpdateAutoScaleVmProfile(p)
-	if err != nil {
-		return fmt.Errorf("Error updating AutoScaleVmProfile %s: %s", d.Id(), err)
+		if d.HasChange("user_data_id") {
+			if v, ok := d.GetOk("user_data_id"); ok {
+				p.SetUserdataid(v.(string))
+			}
+		}
+
+		if d.HasChange("user_data_details") {
+			if v, ok := d.GetOk("user_data_details"); ok {
+				nv := make(map[string]string)
+				for k, v := range v.(map[string]interface{}) {
+					nv[k] = v.(string)
+				}
+				p.SetUserdatadetails(nv)
+			}
+		}
+
+		if d.HasChange("autoscale_user_id") {
+			if v, ok := d.GetOk("autoscale_user_id"); ok {
+				p.SetAutoscaleuserid(v.(string))
+			}
+		}
+
+		if d.HasChange("display") {
+			if v, ok := d.GetOk("display"); ok {
+				p.SetFordisplay(v.(bool))
+			}
+		}
+
+		log.Printf("[DEBUG] Performing CloudStack API update for profile %s", d.Id())
+		_, updateErr := cs.AutoScale.UpdateAutoScaleVmProfile(p)
+		if updateErr != nil {
+			return fmt.Errorf("Error updating AutoScaleVmProfile %s: %s", d.Id(), updateErr)
+		}
 	}
 
 	if d.HasChange("metadata") {
-		if err := updateMetadata(cs, d, "AutoScaleVmProfile"); err != nil {
-			return fmt.Errorf("Error updating tags on AutoScaleVmProfile %s: %s", d.Id(), err)
+		if metadataErr := updateMetadata(cs, d, "AutoScaleVmProfile"); metadataErr != nil {
+			return fmt.Errorf("Error updating tags on AutoScaleVmProfile %s: %s", d.Id(), metadataErr)
 		}
 	}
 
diff --git a/cloudstack/resource_cloudstack_loadbalancer_rule.go b/cloudstack/resource_cloudstack_loadbalancer_rule.go
index 5c5de86..c31c861 100644
--- a/cloudstack/resource_cloudstack_loadbalancer_rule.go
+++ b/cloudstack/resource_cloudstack_loadbalancer_rule.go
@@ -25,6 +25,7 @@
 	"regexp"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/apache/cloudstack-go/v2/cloudstack"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -258,11 +259,73 @@
 	for _, i := range l.LoadBalancerRuleInstances {
 		mbs = append(mbs, i.Id)
 	}
+
+	asgCheckParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
+	asgCheckParams.SetLbruleid(d.Id())
+
+	asgGroups, err := cs.AutoScale.ListAutoScaleVmGroups(asgCheckParams)
+	if err != nil {
+		log.Printf("[WARN] Failed to check for autoscale VM groups during read: %s", err)
+	}
+
+	if len(asgGroups.AutoScaleVmGroups) > 0 {
+		log.Printf("[DEBUG] Load balancer rule %s is managed by %d autoscale VM group(s), current members: %v",
+			d.Id(), len(asgGroups.AutoScaleVmGroups), mbs)
+
+		if currentMemberIds, ok := d.GetOk("member_ids"); ok {
+			currentSet := currentMemberIds.(*schema.Set)
+			if currentSet.Len() == 0 && len(mbs) > 0 {
+				d.Set("member_ids", []string{})
+				return nil
+			}
+		}
+	}
+
 	d.Set("member_ids", mbs)
 
 	return nil
 }
 
+func waitForASGsToBeDisabled(cs *cloudstack.CloudStackClient, lbRuleID string) error {
+	log.Printf("[DEBUG] Waiting for autoscale VM groups using load balancer rule %s to be disabled", lbRuleID)
+
+	maxRetries := 60 // 60 * 2 seconds = 120 seconds max wait (longer for Terraform-driven changes)
+	for i := 0; i < maxRetries; i++ {
+		listParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
+		listParams.SetLbruleid(lbRuleID)
+
+		groups, err := cs.AutoScale.ListAutoScaleVmGroups(listParams)
+		if err != nil {
+			log.Printf("[WARN] Failed to list autoscale VM groups: %s", err)
+			time.Sleep(2 * time.Second)
+			continue
+		}
+
+		allDisabled := true
+		var enabledGroups []string
+
+		for _, group := range groups.AutoScaleVmGroups {
+			if group.State != "disabled" && group.State != "disable" {
+				allDisabled = false
+				enabledGroups = append(enabledGroups, fmt.Sprintf("%s(%s:%s)", group.Name, group.Id, group.State))
+			}
+		}
+
+		if allDisabled {
+			log.Printf("[INFO] All autoscale VM groups using load balancer rule %s are now disabled", lbRuleID)
+			return nil
+		}
+
+		if i < maxRetries-1 {
+			log.Printf("[DEBUG] Waiting for autoscale VM groups to be disabled (attempt %d/%d). Groups still enabled: %v",
+				i+1, maxRetries, enabledGroups)
+			time.Sleep(2 * time.Second)
+		}
+	}
+
+	return fmt.Errorf("Timeout waiting for autoscale VM groups to be disabled after %d seconds", maxRetries*2)
+}
+
 func resourceCloudStackLoadBalancerRuleUpdate(d *schema.ResourceData, meta interface{}) error {
 	cs := meta.(*cloudstack.CloudStackClient)
 
@@ -324,35 +387,126 @@
 	}
 
 	if d.HasChange("member_ids") {
-		o, n := d.GetChange("member_ids")
-		ombs, nmbs := o.(*schema.Set), n.(*schema.Set)
+		log.Printf("[DEBUG] Load balancer rule %s member_ids change detected", d.Id())
 
-		setToStringList := func(s *schema.Set) []string {
-			l := make([]string, s.Len())
-			for i, v := range s.List() {
-				l[i] = v.(string)
-			}
-			return l
+		asgCheckParams := cs.AutoScale.NewListAutoScaleVmGroupsParams()
+		asgCheckParams.SetLbruleid(d.Id())
+
+		asgGroups, err := cs.AutoScale.ListAutoScaleVmGroups(asgCheckParams)
+		if err != nil {
+			log.Printf("[WARN] Failed to check for autoscale VM groups: %s", err)
 		}
 
-		membersToAdd := setToStringList(nmbs.Difference(ombs))
-		membersToRemove := setToStringList(ombs.Difference(nmbs))
+		if len(asgGroups.AutoScaleVmGroups) > 0 {
+			log.Printf("[INFO] Load balancer rule %s is managed by %d autoscale VM group(s), handling member updates carefully",
+				d.Id(), len(asgGroups.AutoScaleVmGroups))
 
-		log.Printf("[DEBUG] Members to add: %v, remove: %v", membersToAdd, membersToRemove)
+			o, n := d.GetChange("member_ids")
+			ombs, nmbs := o.(*schema.Set), n.(*schema.Set)
 
-		if len(membersToAdd) > 0 {
-			p := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(d.Id())
-			p.SetVirtualmachineids(membersToAdd)
-			if _, err := cs.LoadBalancer.AssignToLoadBalancerRule(p); err != nil {
-				return err
+			setToStringList := func(s *schema.Set) []string {
+				l := make([]string, s.Len())
+				for i, v := range s.List() {
+					l[i] = v.(string)
+				}
+				return l
 			}
-		}
 
-		if len(membersToRemove) > 0 {
-			p := cs.LoadBalancer.NewRemoveFromLoadBalancerRuleParams(d.Id())
-			p.SetVirtualmachineids(membersToRemove)
-			if _, err := cs.LoadBalancer.RemoveFromLoadBalancerRule(p); err != nil {
-				return err
+			oldMembers := setToStringList(ombs)
+			newMembers := setToStringList(nmbs)
+
+			log.Printf("[DEBUG] Terraform state - old members: %v, new members: %v", oldMembers, newMembers)
+
+			p := cs.LoadBalancer.NewListLoadBalancerRuleInstancesParams(d.Id())
+			currentInstances, err := cs.LoadBalancer.ListLoadBalancerRuleInstances(p)
+			if err != nil {
+				return fmt.Errorf("Error listing current load balancer members: %s", err)
+			}
+
+			var currentMembers []string
+			for _, i := range currentInstances.LoadBalancerRuleInstances {
+				currentMembers = append(currentMembers, i.Id)
+			}
+
+			log.Printf("[DEBUG] CloudStack actual members: %v", currentMembers)
+
+			// If Terraform state is empty but CloudStack has members, it means autoscale is managing them
+			if len(oldMembers) == 0 && len(currentMembers) > 0 {
+				log.Printf("[INFO] Detected autoscale-managed members in load balancer. Skipping member updates to avoid conflicts.")
+				log.Printf("[INFO] Autoscale VM groups will manage the member lifecycle automatically.")
+
+				d.Set("member_ids", currentMembers)
+				return resourceCloudStackLoadBalancerRuleRead(d, meta)
+			}
+
+			if len(newMembers) > 0 {
+				log.Printf("[WARN] Explicit member_ids specified for autoscale-managed load balancer. This may conflict with autoscale operations.")
+
+				if err := waitForASGsToBeDisabled(cs, d.Id()); err != nil {
+					return fmt.Errorf("Autoscale VM groups must be disabled before modifying load balancer members: %s", err)
+				}
+
+				membersToAdd := setToStringList(nmbs.Difference(ombs))
+				membersToRemove := setToStringList(ombs.Difference(nmbs))
+
+				log.Printf("[DEBUG] Explicit member changes - to add: %v, to remove: %v", membersToAdd, membersToRemove)
+
+				if len(membersToRemove) > 0 {
+					log.Printf("[DEBUG] Removing %d explicit members from load balancer rule %s", len(membersToRemove), d.Id())
+					removeParams := cs.LoadBalancer.NewRemoveFromLoadBalancerRuleParams(d.Id())
+					removeParams.SetVirtualmachineids(membersToRemove)
+					if _, err := cs.LoadBalancer.RemoveFromLoadBalancerRule(removeParams); err != nil {
+						return fmt.Errorf("Error removing explicit members from load balancer rule %s: %s. Members: %v", d.Id(), err, membersToRemove)
+					}
+				}
+
+				if len(membersToAdd) > 0 {
+					log.Printf("[DEBUG] Adding %d explicit members to load balancer rule %s", len(membersToAdd), d.Id())
+					addParams := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(d.Id())
+					addParams.SetVirtualmachineids(membersToAdd)
+					if _, err := cs.LoadBalancer.AssignToLoadBalancerRule(addParams); err != nil {
+						return fmt.Errorf("Error adding explicit members to load balancer rule %s: %s. Members: %v", d.Id(), err, membersToAdd)
+					}
+				}
+			}
+		} else {
+			// No autoscale groups, proceed with normal member management
+			log.Printf("[DEBUG] No autoscale groups found, proceeding with normal member management")
+
+			o, n := d.GetChange("member_ids")
+			ombs, nmbs := o.(*schema.Set), n.(*schema.Set)
+
+			setToStringList := func(s *schema.Set) []string {
+				l := make([]string, s.Len())
+				for i, v := range s.List() {
+					l[i] = v.(string)
+				}
+				return l
+			}
+
+			membersToAdd := setToStringList(nmbs.Difference(ombs))
+			membersToRemove := setToStringList(ombs.Difference(nmbs))
+
+			log.Printf("[DEBUG] Members to add: %v, remove: %v", membersToAdd, membersToRemove)
+
+			if len(membersToRemove) > 0 {
+				log.Printf("[DEBUG] Removing %d members from load balancer rule %s", len(membersToRemove), d.Id())
+				p := cs.LoadBalancer.NewRemoveFromLoadBalancerRuleParams(d.Id())
+				p.SetVirtualmachineids(membersToRemove)
+				if _, err := cs.LoadBalancer.RemoveFromLoadBalancerRule(p); err != nil {
+					return fmt.Errorf("Error removing members from load balancer rule %s: %s. Members to remove: %v", d.Id(), err, membersToRemove)
+				}
+				log.Printf("[DEBUG] Successfully removed members from load balancer rule")
+			}
+
+			if len(membersToAdd) > 0 {
+				log.Printf("[DEBUG] Adding %d members to load balancer rule %s", len(membersToAdd), d.Id())
+				p := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(d.Id())
+				p.SetVirtualmachineids(membersToAdd)
+				if _, err := cs.LoadBalancer.AssignToLoadBalancerRule(p); err != nil {
+					return fmt.Errorf("Error adding members to load balancer rule %s: %s. Members to add: %v", d.Id(), err, membersToAdd)
+				}
+				log.Printf("[DEBUG] Successfully added members to load balancer rule")
 			}
 		}
 	}