func resourceAliCloudKvstoreInstanceUpdate()

in alicloud/resource_alicloud_kvstore_instance.go [790:1694]


func resourceAliCloudKvstoreInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*connectivity.AliyunClient)
	r_kvstoreService := R_kvstoreService{client}
	var response map[string]interface{}
	var err error
	d.Partial(true)

	if d.HasChange("tags") {
		if err := r_kvstoreService.SetResourceTags(d, "INSTANCE"); err != nil {
			return WrapError(err)
		}
		d.SetPartial("tags")
	}

	if d.HasChange("config") {
		request := r_kvstore.CreateModifyInstanceConfigRequest()
		request.InstanceId = d.Id()
		respJson, err := convertMaptoJsonString(d.Get("config").(map[string]interface{}))
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, "alicloud_kvstore_instance", request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		request.Config = respJson
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceConfig(request)
		})
		addDebug(request.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("config")
	}

	if d.HasChange("vpc_auth_mode") && d.Get("vswitch_id") != "" {
		request := r_kvstore.CreateModifyInstanceVpcAuthModeRequest()
		request.InstanceId = d.Id()
		request.VpcAuthMode = d.Get("vpc_auth_mode").(string)
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceVpcAuthMode(request)
		})
		addDebug(request.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("vpc_auth_mode")
	}
	if d.HasChange("security_group_id") {
		request := r_kvstore.CreateModifySecurityGroupConfigurationRequest()
		request.DBInstanceId = d.Id()
		request.SecurityGroupId = d.Get("security_group_id").(string)
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifySecurityGroupConfiguration(request)
		})
		addDebug(request.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("security_group_id")
	}

	update := false
	transformInstanceChargeTypeReq := map[string]interface{}{
		"AutoPay":    true,
		"InstanceId": d.Id(),
	}

	if !d.IsNewResource() && d.HasChange("payment_type") {
		update = true

		if v, ok := d.GetOk("payment_type"); ok {
			transformInstanceChargeTypeReq["ChargeType"] = v
		}
	}

	if !d.IsNewResource() && d.HasChange("instance_charge_type") {
		update = true

		if v, ok := d.GetOk("instance_charge_type"); ok {
			transformInstanceChargeTypeReq["ChargeType"] = v
		}
	}

	if v, ok := d.GetOk("period"); ok {
		transformInstanceChargeTypeReq["Period"] = v
	}

	if v, ok := d.GetOkExists("auto_renew"); ok {
		transformInstanceChargeTypeReq["AutoRenew"] = convertBoolToString(v.(bool))
	}

	if v, ok := d.GetOkExists("auto_renew_period"); ok {
		transformInstanceChargeTypeReq["AutoRenewPeriod"] = v
	}

	if update {
		action := "TransformInstanceChargeType"
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, transformInstanceChargeTypeReq, false)
			if err != nil {
				if NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, transformInstanceChargeTypeReq)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}

		instanceStatusConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "InstanceStatus"))
		if _, err := instanceStatusConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		stateConf := BuildStateConf([]string{}, []string{"true"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "IsOrderCompleted"))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		d.SetPartial("payment_type")
		d.SetPartial("instance_charge_type")
	}

	update = false
	request := r_kvstore.CreateModifyInstanceAutoRenewalAttributeRequest()
	request.DBInstanceId = d.Id()
	if !d.IsNewResource() && d.HasChange("auto_renew") {
		update = true
	}
	request.AutoRenew = convertBoolToString(d.Get("auto_renew").(bool))
	if !d.IsNewResource() && d.HasChange("auto_renew_period") {
		update = true
	}
	request.Duration = convertIntergerToString(d.Get("auto_renew_period").(int))

	if update {
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceAutoRenewalAttribute(request)
		})
		addDebug(request.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		d.SetPartial("auto_renew")
		d.SetPartial("auto_renew_period")
	}
	update = false
	modifyInstanceMaintainTimeReq := r_kvstore.CreateModifyInstanceMaintainTimeRequest()
	modifyInstanceMaintainTimeReq.InstanceId = d.Id()
	if d.HasChange("maintain_end_time") {
		update = true
	}
	modifyInstanceMaintainTimeReq.MaintainEndTime = d.Get("maintain_end_time").(string)
	if d.HasChange("maintain_start_time") {
		update = true
	}
	modifyInstanceMaintainTimeReq.MaintainStartTime = d.Get("maintain_start_time").(string)
	if update {
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceMaintainTime(modifyInstanceMaintainTimeReq)
		})
		addDebug(modifyInstanceMaintainTimeReq.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifyInstanceMaintainTimeReq.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		d.SetPartial("maintain_end_time")
		d.SetPartial("maintain_start_time")
	}
	if d.HasChange("ssl_enable") {
		request := r_kvstore.CreateModifyInstanceSSLRequest()
		request.InstanceId = d.Id()
		request.SSLEnabled = d.Get("ssl_enable").(string)
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceSSL(request)
		})
		addDebug(request.GetActionName(), raw)
		if err != nil && !IsExpectedErrors(err, []string{"SSLDisableStateExistsFault"}) {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 5*time.Minute, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("ssl_enable")
	}
	if !d.IsNewResource() && d.HasChange("resource_group_id") {
		request := r_kvstore.CreateModifyResourceGroupRequest()
		request.InstanceId = d.Id()
		request.RegionId = client.RegionId
		request.ResourceGroupId = d.Get("resource_group_id").(string)
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyResourceGroup(request)
		})
		addDebug(request.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("resource_group_id")
	}

	update = false
	migrateToOtherZoneReq := map[string]interface{}{
		"DBInstanceId": d.Id(),
	}

	if !d.IsNewResource() && d.HasChange("zone_id") {
		update = true

		if v, ok := d.GetOk("zone_id"); ok {
			migrateToOtherZoneReq["ZoneId"] = v
		}
	}

	if !d.IsNewResource() && d.HasChange("vswitch_id") {
		update = true
	}
	if v, ok := d.GetOk("vswitch_id"); ok {
		migrateToOtherZoneReq["VSwitchId"] = v
	}

	if !d.IsNewResource() && d.HasChange("secondary_zone_id") {
		update = true
	}
	if v, ok := d.GetOk("secondary_zone_id"); ok {
		migrateToOtherZoneReq["SecondaryZoneId"] = v
	}

	if v, ok := d.GetOkExists("read_only_count"); ok {
		migrateToOtherZoneReq["ReadOnlyCount"] = v
	}

	if v, ok := d.GetOkExists("slave_read_only_count"); ok {
		migrateToOtherZoneReq["SlaveReadOnlyCount"] = v
	}

	if !d.IsNewResource() && d.HasChange("availability_zone") {
		update = true

		if v, ok := d.GetOk("availability_zone"); ok {
			migrateToOtherZoneReq["ZoneId"] = v
		}
	}

	if v, ok := d.GetOk("effective_time"); ok {
		migrateToOtherZoneReq["EffectiveTime"] = v
	}

	if update {
		action := "MigrateToOtherZone"
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, migrateToOtherZoneReq, true)
			if err != nil {
				if NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, migrateToOtherZoneReq)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}

		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 300*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		d.SetPartial("vswitch_id")
		d.SetPartial("zone_id")
		d.SetPartial("availability_zone")
		d.SetPartial("secondary_zone_id")
	}

	update = false
	modifyBackupPolicyReq := r_kvstore.CreateModifyBackupPolicyRequest()
	modifyBackupPolicyReq.InstanceId = d.Id()
	if d.HasChange("backup_period") {
		update = true
	}
	modifyBackupPolicyReq.PreferredBackupPeriod = convertListToCommaSeparate(d.Get("backup_period").(*schema.Set).List())
	if d.HasChange("backup_time") {
		update = true
	}
	modifyBackupPolicyReq.PreferredBackupTime = d.Get("backup_time").(string)
	if update {
		if _, ok := d.GetOk("enable_backup_log"); ok {
			modifyBackupPolicyReq.EnableBackupLog = requests.NewInteger(d.Get("enable_backup_log").(int))
		}
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyBackupPolicy(modifyBackupPolicyReq)
		})
		addDebug(modifyBackupPolicyReq.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifyBackupPolicyReq.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("backup_period")
		d.SetPartial("backup_time")
	}
	update = false
	modifyInstanceAttributeReq := r_kvstore.CreateModifyInstanceAttributeRequest()
	modifyInstanceAttributeReq.InstanceId = d.Id()

	if !d.IsNewResource() && (d.HasChange("db_instance_name") || d.HasChange("instance_name")) {
		update = true
	}
	if v, ok := d.GetOk("db_instance_name"); ok {
		modifyInstanceAttributeReq.InstanceName = v.(string)
	} else if v, ok := d.GetOk("instance_name"); ok {
		modifyInstanceAttributeReq.InstanceName = v.(string)
	}

	if d.HasChange("instance_release_protection") {
		update = true
		modifyInstanceAttributeReq.InstanceReleaseProtection = requests.NewBoolean(d.Get("instance_release_protection").(bool))
	}
	if !d.IsNewResource() && (d.HasChange("password") || d.HasChange("kms_encrypted_password")) {
		update = true
		password := d.Get("password").(string)
		kmsPassword := d.Get("kms_encrypted_password").(string)

		if password == "" && kmsPassword == "" {
			return WrapError(Error("One of the 'password' and 'kms_encrypted_password' should be set."))
		}

		if password != "" {
			modifyInstanceAttributeReq.NewPassword = password
		} else {
			kmsService := KmsService{meta.(*connectivity.AliyunClient)}
			decryptResp, err := kmsService.Decrypt(kmsPassword, d.Get("kms_encryption_context").(map[string]interface{}))
			if err != nil {
				return WrapError(err)
			}
			modifyInstanceAttributeReq.NewPassword = decryptResp
		}
	}
	if update {
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceAttribute(modifyInstanceAttributeReq)
		})
		addDebug(modifyInstanceAttributeReq.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifyInstanceAttributeReq.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("instance_name")
		d.SetPartial("db_instance_name")
		d.SetPartial("instance_release_protection")
		d.SetPartial("kms_encrypted_password")
		d.SetPartial("kms_encryption_context")
		d.SetPartial("password")
	}
	update = false
	modifyDBInstanceConnectionStringReq := r_kvstore.CreateModifyDBInstanceConnectionStringRequest()
	modifyDBInstanceConnectionStringReq.DBInstanceId = d.Id()
	if d.HasChange("private_connection_prefix") {
		update = true
		modifyDBInstanceConnectionStringReq.NewConnectionString = d.Get("private_connection_prefix").(string)
	}
	if d.HasChange("private_connection_port") {
		update = true
		modifyDBInstanceConnectionStringReq.Port = d.Get("private_connection_port").(string)
	}
	modifyDBInstanceConnectionStringReq.IPType = "Private"
	if update {
		object, err := r_kvstoreService.DescribeKvstoreInstance(d.Id())
		modifyDBInstanceConnectionStringReq.CurrentConnectionString = fmt.Sprint(object["ConnectionDomain"])
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyDBInstanceConnectionString(modifyDBInstanceConnectionStringReq)
		})
		addDebug(modifyDBInstanceConnectionStringReq.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifyDBInstanceConnectionStringReq.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("private_connection_prefix")
		d.SetPartial("private_connection_port")
	}
	update = false
	modifySecurityIpsReq := r_kvstore.CreateModifySecurityIpsRequest()
	modifySecurityIpsReq.InstanceId = d.Id()
	modifySecurityIpsReq.ModifyMode = "Cover"

	if d.HasChange("security_ips") {
		update = true
	}
	modifySecurityIpsReq.SecurityIps = convertListToCommaSeparate(d.Get("security_ips").(*schema.Set).List())

	if d.HasChange("security_ip_group_attribute") {
		update = true
	}
	if v, ok := d.GetOk("security_ip_group_attribute"); ok {
		modifySecurityIpsReq.SecurityIpGroupAttribute = v.(string)
	}

	if d.HasChange("security_ip_group_name") {
		update = true
	}
	if v, ok := d.GetOk("security_ip_group_name"); ok {
		modifySecurityIpsReq.SecurityIpGroupName = v.(string)
	}

	if update {
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifySecurityIps(modifySecurityIpsReq)
		})
		addDebug(modifySecurityIpsReq.GetActionName(), raw)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifySecurityIpsReq.GetActionName(), AlibabaCloudSdkGoERROR)
		}

		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 1*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		d.SetPartial("security_ips")
		d.SetPartial("security_ip_group_attribute")
		d.SetPartial("security_ip_group_name")
	}

	update = false
	modifyInstanceSpecReq := map[string]interface{}{
		"RegionId":   client.RegionId,
		"AutoPay":    true,
		"InstanceId": d.Id(),
	}
	if !d.IsNewResource() && d.HasChange("instance_class") {
		update = true
	}
	if v, ok := d.GetOk("instance_class"); ok {
		modifyInstanceSpecReq["InstanceClass"] = v
	}

	// read_only_count and slave_read_only_count may be changed after other attributes changed, like secondary_zone_id
	// and ReadOnlyCount and SlaveReadOnlyCount can not be changed together
	if !d.IsNewResource() && d.HasChange("read_only_count") {
		update = true

		if v, ok := d.GetOkExists("read_only_count"); ok {
			modifyInstanceSpecReq["ReadOnlyCount"] = v
		}
	}

	if v, ok := d.GetOk("effective_time"); ok {
		modifyInstanceSpecReq["EffectiveTime"] = v
	}

	if v, ok := d.GetOk("business_info"); ok {
		modifyInstanceSpecReq["BusinessInfo"] = v
	}

	if v, ok := d.GetOk("coupon_no"); ok {
		modifyInstanceSpecReq["CouponNo"] = v
	}

	if v, ok := d.GetOkExists("force_upgrade"); ok {
		modifyInstanceSpecReq["ForceUpgrade"] = v
	}

	if v, ok := d.GetOk("order_type"); ok {
		modifyInstanceSpecReq["OrderType"] = v
	}

	if update {
		action := "ModifyInstanceSpec"
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, modifyInstanceSpecReq, false)
			if err != nil {
				if IsExpectedErrors(err, []string{"MissingRedisUsedmemoryUnsupportPerfItem", "Task.Conflict"}) || NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, modifyInstanceSpecReq)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}

		instanceStatusConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "InstanceStatus"))
		if _, err := instanceStatusConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		stateConf := BuildStateConf([]string{}, []string{"true"}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "IsOrderCompleted"))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		if fmt.Sprint(modifyInstanceSpecReq["EffectiveTime"]) != "MaintainTime" && d.HasChange("instance_class") {
			stateConf := BuildStateConf([]string{}, []string{modifyInstanceSpecReq["InstanceClass"].(string)}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "RealInstanceClass"))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}
	}

	// read_only_count and slave_read_only_count may be changed after other attributes changed, like secondary_zone_id
	// and ReadOnlyCount and SlaveReadOnlyCount can not be changed together
	if !d.IsNewResource() && d.HasChange("slave_read_only_count") {
		update = true

		if v, ok := d.GetOkExists("slave_read_only_count"); ok {
			modifyInstanceSpecReq["SlaveReadOnlyCount"] = v
		}

		delete(modifyInstanceSpecReq, "ReadOnlyCount")

		action := "ModifyInstanceSpec"

		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, modifyInstanceSpecReq, false)
			if err != nil {
				if IsExpectedErrors(err, []string{"MissingRedisUsedmemoryUnsupportPerfItem", "Task.Conflict"}) || NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, modifyInstanceSpecReq)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}

		instanceStatusConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "InstanceStatus"))
		if _, err := instanceStatusConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		stateConf := BuildStateConf([]string{}, []string{"true"}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "IsOrderCompleted"))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
	}

	update = false
	modifyInstanceMajorVersionReq := r_kvstore.CreateModifyInstanceMajorVersionRequest()
	modifyInstanceMajorVersionReq.InstanceId = d.Id()
	if !d.IsNewResource() && d.HasChange("engine_version") {
		update = true
	}

	modifyInstanceMajorVersionReq.MajorVersion = d.Get("engine_version").(string)
	if v, ok := d.GetOk("effective_time"); ok {
		modifyInstanceMajorVersionReq.EffectiveTime = v.(string)
	}
	if update {
		raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
			return r_kvstoreClient.ModifyInstanceMajorVersion(modifyInstanceMajorVersionReq)
		})
		addDebug(modifyInstanceMajorVersionReq.GetActionName(), raw)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifyInstanceMajorVersionReq.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 300*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("engine_version")
	}
	if d.HasChange("parameters") {
		request := r_kvstore.CreateModifyInstanceConfigRequest()
		request.InstanceId = d.Id()
		config := make(map[string]interface{})
		documented := d.Get("parameters").(*schema.Set).List()
		if len(documented) > 0 {
			for _, i := range documented {
				key := i.(map[string]interface{})["name"].(string)
				value := i.(map[string]interface{})["value"]
				config[key] = value
			}
			cfg, _ := convertMaptoJsonString(config)
			request.Config = cfg

			raw, err := client.WithRKvstoreClient(func(r_kvstoreClient *r_kvstore.Client) (interface{}, error) {
				return r_kvstoreClient.ModifyInstanceConfig(request)
			})
			addDebug(request.GetActionName(), raw)
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
			}
			stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}

		d.SetPartial("parameters")
	}
	if d.HasChange("enable_public") {
		prefix := d.Get("connection_string_prefix").(string)
		port := fmt.Sprintf("%s", d.Get("port"))
		target := d.Get("enable_public").(bool)

		if target {
			request := r_kvstore.CreateAllocateInstancePublicConnectionRequest()
			request.InstanceId = d.Id()
			request.ConnectionStringPrefix = prefix
			request.Port = port

			raw, err := client.WithRKvstoreClient(func(client *r_kvstore.Client) (interface{}, error) {
				return client.AllocateInstancePublicConnection(request)
			})
			addDebug(request.GetActionName(), raw)
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
			}
			stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}
		if !target && d.Get("connection_string") != "" {
			request := r_kvstore.CreateReleaseInstancePublicConnectionRequest()
			request.InstanceId = d.Id()
			request.CurrentConnectionString = d.Get("connection_string").(string)

			raw, err := client.WithRKvstoreClient(func(client *r_kvstore.Client) (interface{}, error) {
				return client.ReleaseInstancePublicConnection(request)
			})
			addDebug(request.GetActionName(), raw)
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
			}
			stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 120*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}
		d.SetPartial("enable_public")
	}
	update = false
	modifyInstanceTDERequest := map[string]interface{}{
		"InstanceId": d.Id(),
	}
	if d.HasChange("tde_status") {
		update = true
		if v, ok := d.GetOk("tde_status"); ok {
			modifyInstanceTDERequest["TDEStatus"] = v
		}
	}
	if d.HasChange("encryption_name") {
		update = true
		if v, ok := d.GetOk("encryption_name"); ok {
			modifyInstanceTDERequest["EncryptionName"] = v
		}
	}
	if d.HasChange("encryption_key") {
		update = true
		if v, ok := d.GetOk("encryption_key"); ok {
			modifyInstanceTDERequest["EncryptionKey"] = v
		}
	}
	if d.HasChange("role_arn") {
		update = true
		if v, ok := d.GetOk("role_arn"); ok {
			modifyInstanceTDERequest["RoleArn"] = v
		}
	}
	if update {
		action := "ModifyInstanceTDE"
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err := resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, modifyInstanceTDERequest, false)
			if err != nil {
				if NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, request)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}
		stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}
		d.SetPartial("tde_status")
		d.SetPartial("encryption_name")
		d.SetPartial("encryption_key")
		d.SetPartial("role_arn")
	}

	if !d.IsNewResource() && d.HasChange("shard_count") {
		if instanceClass, ok := d.GetOk("instance_class"); ok {
			if !isCloudDiskSpec(fmt.Sprint(instanceClass)) {
				return WrapErrorf(err, "The instance_class(%s) is not cloud disk specification, if you want to modify the shard_count, you can do this by modifying instance_class.", instanceClass)
			}
		}

		oldEntry, newEntry := d.GetChange("shard_count")
		oldEntryValue := oldEntry.(int)
		newEntryValue := newEntry.(int)
		removed := oldEntryValue - newEntryValue
		added := newEntryValue - oldEntryValue

		if removed > 0 {
			action := "DeleteShardingNode"
			request := make(map[string]interface{})
			request["InstanceId"] = d.Id()
			request["ShardCount"] = removed
			wait := incrementalWait(3*time.Second, 5*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError {
				response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, request, false)

				if err != nil {
					if NeedRetry(err) {
						wait()
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				addDebug(action, response, request)
				return nil
			})
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
			}

			instanceStatusConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "InstanceStatus"))
			if _, err := instanceStatusConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}

			stateConf := BuildStateConf([]string{}, []string{"true"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "IsOrderCompleted"))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}

			d.SetPartial("shard_count")
		}

		if added > 0 {
			action := "AddShardingNode"
			request := make(map[string]interface{})
			request["InstanceId"] = d.Id()
			request["ClientToken"] = buildClientToken(action)
			request["ShardCount"] = added
			wait := incrementalWait(3*time.Second, 5*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError {
				response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, request, true)
				request["ClientToken"] = buildClientToken(action)
				if err != nil {
					if NeedRetry(err) {
						wait()
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				return nil
			})
			addDebug(action, response, request)

			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
			}

			instanceStatusConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "InstanceStatus"))
			if _, err := instanceStatusConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}

			stateConf := BuildStateConf([]string{}, []string{"true"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "IsOrderCompleted"))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}

			d.SetPartial("shard_count")
		}

	}

	update = false
	modifyDBInstanceAutoUpgradeReq := map[string]interface{}{
		"DBInstanceId": d.Id(),
	}

	if d.HasChange("is_auto_upgrade_open") {
		update = true
	}
	if v, ok := d.GetOk("is_auto_upgrade_open"); ok {
		modifyDBInstanceAutoUpgradeReq["Value"] = v
	}

	if update {
		action := "ModifyDBInstanceAutoUpgrade"
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, modifyDBInstanceAutoUpgradeReq, false)
			if err != nil {
				if NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, modifyDBInstanceAutoUpgradeReq)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}

		d.SetPartial("is_auto_upgrade_open")
	}

	update = false
	modifyInstanceBandwidthReq := map[string]interface{}{
		"InstanceId": d.Id(),
	}

	if d.HasChange("bandwidth") {
		update = true

		if v, ok := d.GetOkExists("bandwidth"); ok {
			modifyInstanceBandwidthReq["TargetIntranetBandwidth"] = v
		}
	}

	if update {
		action := "ModifyInstanceBandwidth"
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("R-kvstore", "2015-01-01", action, nil, modifyInstanceBandwidthReq, false)
			if err != nil {
				if NeedRetry(err) {
					wait()
					return resource.RetryableError(err)
				}
				return resource.NonRetryableError(err)
			}
			return nil
		})
		addDebug(action, response, modifyInstanceBandwidthReq)

		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}

		instanceStatusConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "InstanceStatus"))
		if _, err := instanceStatusConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		stateConf := BuildStateConf([]string{}, []string{"true"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, r_kvstoreService.KvstoreInstanceAttributeRefreshFunc(d.Id(), "IsOrderCompleted"))
		if _, err := stateConf.WaitForState(); err != nil {
			return WrapErrorf(err, IdMsg, d.Id())
		}

		d.SetPartial("bandwidth")
	}

	d.Partial(false)

	return resourceAliCloudKvstoreInstanceRead(d, meta)
}