func resourceAliCloudInstanceUpdate()

in alicloud/resource_alicloud_instance.go [1466:2178]


func resourceAliCloudInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*connectivity.AliyunClient)
	ecsService := EcsService{client}
	var err error
	d.Partial(true)

	if !d.IsNewResource() {
		if err := setTags(client, TagResourceInstance, d); err != nil {
			return WrapError(err)
		} else {
			d.SetPartial("tags")
		}
	}

	if !d.IsNewResource() && d.HasChange("resource_group_id") {
		action := "JoinResourceGroup"
		request := map[string]interface{}{
			"ResourceType":    "instance",
			"ResourceId":      d.Id(),
			"RegionId":        client.RegionId,
			"ResourceGroupId": d.Get("resource_group_id"),
		}
		response, err := client.RpcPost("Ecs", "2014-05-26", action, nil, request, false)
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
		}
		addDebug(action, response, request)
		d.SetPartial("resource_group_id")
	}

	if err := setVolumeTags(client, TagResourceDisk, d); err != nil {
		return WrapError(err)
	} else {
		d.SetPartial("volume_tags")
	}

	if !d.IsNewResource() && !d.HasChange("vpc_id") && d.HasChange("security_groups") {
		if !d.IsNewResource() || d.Get("vswitch_id").(string) == "" {
			o, n := d.GetChange("security_groups")
			os := o.(*schema.Set)
			ns := n.(*schema.Set)

			rl := expandStringList(os.Difference(ns).List())
			al := expandStringList(ns.Difference(os).List())

			if len(rl) > 0 {
				err := ecsService.LeaveSecurityGroups(d.Id(), rl)
				if err != nil {
					return WrapError(err)
				}
			}

			if len(al) > 0 {
				err := ecsService.JoinSecurityGroups(d.Id(), al)
				if err != nil {
					return WrapError(err)
				}
			}

			d.SetPartial("security_groups")
		}
	}

	if !d.IsNewResource() && (d.HasChange("system_disk_size") || d.HasChange("system_disk_auto_snapshot_policy_id") || d.HasChange("system_disk_name") || d.HasChange("system_disk_description") || d.HasChange("system_disk_performance_level")) {
		disk, err := ecsService.DescribeEcsSystemDisk(d.Id())
		if err != nil {
			return WrapError(err)
		}

		if d.HasChange("system_disk_performance_level") {
			action := "ModifyDiskSpec"
			var response map[string]interface{}
			request := map[string]interface{}{
				"RegionId": client.RegionId,
			}
			request["DiskId"] = disk["DiskId"].(string)
			if d.HasChange("system_disk_performance_level") {
				request["PerformanceLevel"] = d.Get("system_disk_performance_level")
			}
			wait := incrementalWait(3*time.Second, 3*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, false)
				if err != nil {
					if IsExpectedErrors(err, []string{"ServiceUnavailable", "Throttling.ConcurrentLimitExceeded"}) || 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{"Available", "In_use"}, d.Timeout(schema.TimeoutUpdate), 10*time.Second, ecsService.EcsDiskStateRefreshFunc(disk["DiskId"].(string), []string{}))
			if _, err := stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}

		if d.HasChange("system_disk_size") {
			instance, errDesc := ecsService.DescribeInstance(d.Id())
			if errDesc != nil {
				return WrapError(errDesc)
			}

			request := ecs.CreateResizeDiskRequest()
			request.NewSize = requests.NewInteger(d.Get("system_disk_size").(int))
			if instance.Status == string(Stopped) {
				request.Type = "offline"
			} else {
				request.Type = "online"
			}
			request.DiskId = disk["DiskId"].(string)
			raw, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
				return ecsClient.ResizeDisk(request)
			})
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
			}
			addDebug(request.GetActionName(), raw, request.RpcRequest, request)
			d.SetPartial("system_disk_size")
		}

		if d.HasChange("system_disk_auto_snapshot_policy_id") {
			action := "ApplyAutoSnapshotPolicy"
			var response map[string]interface{}
			request := map[string]interface{}{
				"RegionId": client.RegionId,
			}
			request["autoSnapshotPolicyId"] = d.Get("system_disk_auto_snapshot_policy_id")
			request["diskIds"] = convertListToJsonString([]interface{}{disk["DiskId"]})
			wait := incrementalWait(3*time.Second, 3*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, 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)
			}
			d.SetPartial("system_disk_auto_snapshot_policy_id")
		}

		if d.HasChange("system_disk_name") || d.HasChange("system_disk_description") {
			var response map[string]interface{}
			modifyDiskAttributeReq := map[string]interface{}{
				"DiskId": disk["DiskId"],
			}
			modifyDiskAttributeReq["DiskName"] = d.Get("system_disk_name")
			modifyDiskAttributeReq["Description"] = d.Get("system_disk_description")
			action := "ModifyDiskAttribute"
			wait := incrementalWait(3*time.Second, 3*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, modifyDiskAttributeReq, false)
				if err != nil {
					if NeedRetry(err) {
						wait()
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				addDebug(action, response, modifyDiskAttributeReq)
				return nil
			})
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
			}
			d.SetPartial("system_disk_name")
			d.SetPartial("system_disk_description")
		}
	}

	run := false
	imageUpdate, err := modifyInstanceImage(d, meta, run)
	if err != nil {
		return WrapError(err)
	}

	vpcUpdate, err := modifyVpcAttribute(d, meta, run)
	if err != nil {
		return WrapError(err)
	}

	passwordUpdate, err := modifyInstanceAttribute(d, meta)
	if err != nil {
		return WrapError(err)
	}

	if !d.IsNewResource() && d.HasChange("auto_release_time") {
		request := ecs.CreateModifyInstanceAutoReleaseTimeRequest()
		request.InstanceId = d.Id()
		request.RegionId = client.RegionId
		request.AutoReleaseTime = d.Get("auto_release_time").(string)
		_, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
			return ecsClient.ModifyInstanceAutoReleaseTime(request)
		})
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		d.SetPartial("auto_release_time")
	}

	typeUpdate, err := modifyInstanceType(d, meta, run)
	if err != nil {
		return WrapError(err)
	}

	if err := modifyInstanceChargeType(d, meta, false); err != nil {
		return WrapError(err)
	}

	target, targetExist := d.GetOk("status")
	statusUpdate := d.HasChange("status")
	if d.IsNewResource() && targetExist && target.(string) == string(Running) {
		statusUpdate = false
	}
	if imageUpdate || vpcUpdate || passwordUpdate || typeUpdate || statusUpdate {
		run = true
		instance, errDesc := ecsService.DescribeInstance(d.Id())
		if errDesc != nil {
			return WrapError(errDesc)
		}
		if statusUpdate && targetExist && target == string(Stopped) || instance.Status == string(Running) {
			stopRequest := ecs.CreateStopInstanceRequest()
			stopRequest.RegionId = client.RegionId
			stopRequest.InstanceId = d.Id()
			stopRequest.ForceStop = requests.NewBoolean(false)
			if v, ok := d.GetOk("stopped_mode"); ok {
				stopRequest.StoppedMode = v.(string)
			}
			err := resource.Retry(5*time.Minute, func() *resource.RetryError {
				raw, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
					return ecsClient.StopInstance(stopRequest)
				})
				if err != nil {
					if IsExpectedErrors(err, []string{"IncorrectInstanceStatus"}) {
						time.Sleep(time.Second)
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				addDebug(stopRequest.GetActionName(), raw)
				return nil
			})
			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), stopRequest.GetActionName(), AlibabaCloudSdkGoERROR)
			}
			stateConf := BuildStateConf([]string{"Pending", "Running", "Stopping"}, []string{"Stopped"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, ecsService.InstanceStateRefreshFunc(d.Id(), []string{}))

			if _, err = stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}
		if _, err := modifyInstanceImage(d, meta, run); err != nil {
			return WrapError(err)
		}

		if _, err := modifyVpcAttribute(d, meta, run); err != nil {
			return WrapError(err)
		}

		if _, err := modifyInstanceType(d, meta, run); err != nil {
			return WrapError(err)
		}

		if targetExist && target == string(Running) {
			startRequest := ecs.CreateStartInstanceRequest()
			startRequest.InstanceId = d.Id()

			err := resource.Retry(5*time.Minute, func() *resource.RetryError {
				raw, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
					return ecsClient.StartInstance(startRequest)
				})
				if err != nil {
					if IsExpectedErrors(err, []string{"IncorrectInstanceStatus"}) {
						time.Sleep(time.Second)
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				addDebug(startRequest.GetActionName(), raw)
				return nil
			})

			if err != nil {
				return WrapErrorf(err, DefaultErrorMsg, d.Id(), startRequest.GetActionName(), AlibabaCloudSdkGoERROR)
			}
			// Start instance sometimes costs more than 8 minutes when os type is centos.
			stateConf := &resource.StateChangeConf{
				Pending:    []string{"Pending", "Starting", "Stopped"},
				Target:     []string{"Running"},
				Refresh:    ecsService.InstanceStateRefreshFunc(d.Id(), []string{}),
				Timeout:    d.Timeout(schema.TimeoutUpdate),
				Delay:      5 * time.Second,
				MinTimeout: 3 * time.Second,
			}

			if _, err = stateConf.WaitForState(); err != nil {
				return WrapErrorf(err, IdMsg, d.Id())
			}
		}
		if d.HasChange("status") {
			d.SetPartial("status")
		}
	}

	if err := modifyInstanceNetworkSpec(d, meta); err != nil {
		return WrapError(err)
	}

	if d.HasChange("force_delete") {
		d.SetPartial("force_delete")
	}

	// Only PrePaid instance can support modifying renewal attribute
	if !d.IsNewResource() && d.Get("instance_charge_type").(string) == string(PrePaid) &&
		(d.HasChange("renewal_status") || d.HasChange("auto_renew_period")) {
		status := d.Get("renewal_status").(string)
		request := ecs.CreateModifyInstanceAutoRenewAttributeRequest()
		request.InstanceId = d.Id()
		request.RenewalStatus = status

		if status == string(RenewAutoRenewal) {
			request.PeriodUnit = d.Get("period_unit").(string)
			request.Duration = requests.NewInteger(d.Get("auto_renew_period").(int))
		}

		raw, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
			return ecsClient.ModifyInstanceAutoRenewAttribute(request)
		})
		if err != nil {
			return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
		}
		addDebug(request.GetActionName(), raw, request.RpcRequest, request)
		d.SetPartial("renewal_status")
		d.SetPartial("auto_renew_period")
	}

	if d.HasChange("secondary_private_ips") {
		var response map[string]interface{}
		instance, err := ecsService.DescribeInstance(d.Id())
		if err != nil {
			return WrapError(err)
		}
		networkInterfaceId := ""
		for _, obj := range instance.NetworkInterfaces.NetworkInterface {
			if obj.Type == "Primary" {
				networkInterfaceId = obj.NetworkInterfaceId
				break
			}
		}
		oraw, nraw := d.GetChange("secondary_private_ips")
		remove := oraw.(*schema.Set).Difference(nraw.(*schema.Set)).List()
		create := nraw.(*schema.Set).Difference(oraw.(*schema.Set)).List()
		if len(remove) > 0 {
			action := "UnassignPrivateIpAddresses"
			request := map[string]interface{}{
				"RegionId":           client.RegionId,
				"NetworkInterfaceId": networkInterfaceId,
				"ClientToken":        buildClientToken(action),
			}

			for index, val := range remove {
				request[fmt.Sprintf("PrivateIpAddress.%d", index+1)] = val
			}

			wait := incrementalWait(3*time.Second, 3*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, false)
				if err != nil {
					if NeedRetry(err) || IsExpectedErrors(err, []string{"OperationConflict", "Operation.Conflict"}) {
						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)
			}
			addDebug(action, response, request)
			d.SetPartial("secondary_private_ips")
		}
		if len(create) > 0 {
			action := "AssignPrivateIpAddresses"
			request := map[string]interface{}{
				"RegionId":           client.RegionId,
				"NetworkInterfaceId": networkInterfaceId,
				"ClientToken":        buildClientToken(action),
			}
			for index, val := range create {
				request[fmt.Sprintf("PrivateIpAddress.%d", index+1)] = val
			}
			wait := incrementalWait(3*time.Second, 3*time.Second)
			err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, false)
				if err != nil {
					if NeedRetry(err) || IsExpectedErrors(err, []string{"OperationConflict", "Operation.Conflict"}) {
						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)
			}
			d.SetPartial("secondary_private_ips")
		}

	}

	if d.HasChange("secondary_private_ip_address_count") {
		var response map[string]interface{}
		instance, err := ecsService.DescribeInstance(d.Id())
		if err != nil {
			return WrapError(err)
		}
		// query for the Primary NetworkInterfaceId
		networkInterfaceId := ""
		for _, obj := range instance.NetworkInterfaces.NetworkInterface {
			if obj.Type == "Primary" {
				networkInterfaceId = obj.NetworkInterfaceId
				break
			}
		}
		privateIpList := expandStringList(d.Get("secondary_private_ips").(*schema.Set).List())
		oldIpsCount, newIpsCount := d.GetChange("secondary_private_ip_address_count")
		if oldIpsCount != nil && newIpsCount != nil && newIpsCount != len(privateIpList) {
			diff := newIpsCount.(int) - oldIpsCount.(int)
			if diff > 0 {
				action := "AssignPrivateIpAddresses"
				request := map[string]interface{}{
					"RegionId":                       client.RegionId,
					"NetworkInterfaceId":             networkInterfaceId,
					"ClientToken":                    buildClientToken(action),
					"SecondaryPrivateIpAddressCount": diff,
				}
				wait := incrementalWait(3*time.Second, 3*time.Second)
				err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
					response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, false)
					if err != nil {
						if NeedRetry(err) || IsExpectedErrors(err, []string{"OperationConflict"}) {
							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)
				}
				d.SetPartial("secondary_private_ip_address_count")
			}
			if diff < 0 {
				diff *= -1
				action := "UnassignPrivateIpAddresses"
				request := map[string]interface{}{
					"RegionId":           client.RegionId,
					"NetworkInterfaceId": networkInterfaceId,
					"ClientToken":        buildClientToken(action),
				}
				for index, val := range privateIpList[:diff] {
					request[fmt.Sprintf("PrivateIpAddress.%d", index+1)] = val
				}
				wait := incrementalWait(3*time.Second, 3*time.Second)
				err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
					response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, false)
					if err != nil {
						if NeedRetry(err) || IsExpectedErrors(err, []string{"OperationConflict"}) {
							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)
				}
				addDebug(action, response, request)
				d.SetPartial("secondary_private_ip_address_count")
			}
		}
	}

	if !d.IsNewResource() && d.HasChange("deployment_set_id") {
		action := "ModifyInstanceDeployment"
		var response map[string]interface{}
		request := map[string]interface{}{
			"RegionId":    client.RegionId,
			"InstanceId":  d.Id(),
			"ClientToken": buildClientToken(action),
		}
		if v, ok := d.GetOk("deployment_set_id"); ok {
			request["DeploymentSetId"] = v
		}
		if v := d.Get("deployment_set_id"); len(v.(string)) == 0 {
			oldDeploymentSetId, _ := d.GetChange("deployment_set_id")
			request["DeploymentSetId"] = oldDeploymentSetId
			request["RemoveFromDeploymentSet"] = true
		}
		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
			response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, 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)
		}
		d.SetPartial("deployment_set_id")
	}

	if d.HasChange("maintenance_time") || d.HasChange("maintenance_action") || d.HasChange("maintenance_notify") {
		var response map[string]interface{}
		action := "ModifyInstanceMaintenanceAttributes"
		request := map[string]interface{}{
			"RegionId":   client.RegionId,
			"InstanceId": []string{d.Id()},
		}

		maintenanceWindowsMaps := make([]map[string]interface{}, 0)
		for _, maintenanceWindows := range d.Get("maintenance_time").(*schema.Set).List() {
			maintenanceWindowsMap := make(map[string]interface{})
			maintenanceWindowsArg := maintenanceWindows.(map[string]interface{})

			if v, ok := maintenanceWindowsArg["start_time"].(string); ok && v != "" {
				maintenanceWindowsMap["StartTime"] = v
			}
			if v, ok := maintenanceWindowsArg["end_time"].(string); ok && v != "" {
				maintenanceWindowsMap["EndTime"] = v
			}

			maintenanceWindowsMaps = append(maintenanceWindowsMaps, maintenanceWindowsMap)
		}
		request["MaintenanceWindow"] = maintenanceWindowsMaps

		if v, ok := d.GetOk("maintenance_action"); ok {
			request["ActionOnMaintenance"] = v
		}
		if v, ok := d.GetOkExists("maintenance_notify"); ok {
			request["NotifyOnMaintenance"] = v
		}

		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError {
			response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, 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)
		}

		d.SetPartial("maintenance_time")
		d.SetPartial("maintenance_action")
		d.SetPartial("maintenance_notify")
	}

	if d.HasChange("http_endpoint") || d.HasChange("http_tokens") {
		var response map[string]interface{}
		action := "ModifyInstanceMetadataOptions"
		request := map[string]interface{}{
			"RegionId":   client.RegionId,
			"InstanceId": d.Id(),
		}

		if v, ok := d.GetOk("http_endpoint"); ok {
			request["HttpEndpoint"] = v
		} else {
			request["HttpEndpoint"] = "enabled"
		}
		if v, ok := d.GetOk("http_tokens"); ok {
			request["HttpTokens"] = v
		}

		wait := incrementalWait(3*time.Second, 3*time.Second)
		err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
			response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, 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)
		}

		d.SetPartial("http_endpoint")
		d.SetPartial("http_tokens")
	}

	if !d.IsNewResource() && d.HasChange("ipv6_addresses") {
		var response map[string]interface{}
		instance, err := ecsService.DescribeInstance(d.Id())
		if err != nil {
			return WrapError(err)
		}

		networkInterfaceId := ""
		for _, obj := range instance.NetworkInterfaces.NetworkInterface {
			if obj.Type == "Primary" {
				networkInterfaceId = obj.NetworkInterfaceId
				break
			}
		}

		oldIpv6Addresses, newIpv6Addresses := d.GetChange("ipv6_addresses")
		removed := oldIpv6Addresses.(*schema.Set).Difference(newIpv6Addresses.(*schema.Set)).List()
		added := newIpv6Addresses.(*schema.Set).Difference(oldIpv6Addresses.(*schema.Set)).List()

		if len(removed) > 0 {
			action := "UnassignIpv6Addresses"

			unassignIpv6AddressesReq := map[string]interface{}{
				"RegionId":           client.RegionId,
				"ClientToken":        buildClientToken("UnassignIpv6Addresses"),
				"NetworkInterfaceId": networkInterfaceId,
				"Ipv6Address":        removed,
			}

			wait := incrementalWait(3*time.Second, 5*time.Second)
			err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, unassignIpv6AddressesReq, true)
				if err != nil {
					if NeedRetry(err) {
						wait()
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				return nil
			})
			addDebug(action, response, unassignIpv6AddressesReq)

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

		if len(added) > 0 {
			action := "AssignIpv6Addresses"

			assignIpv6AddressesReq := map[string]interface{}{
				"RegionId":           client.RegionId,
				"ClientToken":        buildClientToken("AssignIpv6Addresses"),
				"NetworkInterfaceId": networkInterfaceId,
				"Ipv6Address":        added,
			}

			wait := incrementalWait(3*time.Second, 5*time.Second)
			err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
				response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, assignIpv6AddressesReq, true)
				if err != nil {
					if NeedRetry(err) {
						wait()
						return resource.RetryableError(err)
					}
					return resource.NonRetryableError(err)
				}
				return nil
			})
			addDebug(action, response, assignIpv6AddressesReq)

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

		d.SetPartial("ipv6_addresses")
	}

	d.Partial(false)

	return resourceAliCloudInstanceRead(d, meta)
}