ECS resources can be created based on your needs. You can create custom resources during peak hours based on your needs and release these resources during off-peak hours. This topic describes how to use SDK for Python to release an ECS instance.

Background information

After an ECS instance is released, the physical resources used by the instance will be recycled, such as disks and snapshots. All related data will be deleted and can never be recovered. If you want to retain the data, we recommend that you create snapshots of the disks before you release the ECS instance. The snapshots can be used to create a new ECS instance.

This topic provides the sample code to show how to release an ECS instance and also the explanation of the sample code. For more information, see the following topics:

Sample code

The sample code is as follows.

Note Exercise caution when you release an ECS instance.
#  coding=utf-8
rr# if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs'
# if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs'
# make sure the sdk version is 2.1.2, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DeleteInstanceRequest import DeleteInstanceRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.ModifyInstanceAutoReleaseTimeRequest import \
    ModifyInstanceAutoReleaseTimeRequest
from aliyunsdkecs.request.v20140526.StopInstanceRequest import StopInstanceRequest

# configuration the log output formatter, if you want to save the output to file,
# append ",filename='ecs_invoke.log'" after datefmt.

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S')
clt = client.AcsClient('<accessKeyId>', '<accessSecret>', '<region-Id>')


def stop_instance(instance_id, force_stop=False):
    '''
    stop one ecs instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force_stop: if force stop is true, it will force stop the server and not ensure the data
    write to disk correctly.
    :return:
    '''
    request = StopInstanceRequest()
    request.set_InstanceId(instance_id)
    request.set_ForceStop(force_stop)
    logging.info("Stop %s command submit successfully.", instance_id)
    _send_request(request)


def describe_instance_detail(instance_id):
    '''
    describe instance detail
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :return:
    '''
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get('Instances').get('Instance')
        if len(instance_list) > 0:
            return instance_list[0]


def check_auto_release_time_ready(instance_id):
    detail = describe_instance_detail(instance_id=instance_id)
    if detail is not None:
        release_time = detail.get('AutoReleaseTime')
        return release_time


def release_instance(instance_id, force=False):
    '''
    delete instance according instance id, only support after pay instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force:
    if force is false, you need to make the ecs instance stopped, you can
    execute the delete action.
    If force is true, you can delete the instance even the instance is running.
    :return:
    '''
    request = DeleteInstanceRequest();
    request.set_InstanceId(instance_id)
    request.set_Force(force)
    _send_request(request)


def set_instance_auto_release_time(instance_id, time_to_release=None):
    '''
    setting instance auto delete time
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param time_to_release: if the property is setting, such as '2017-01-30T00:00:00Z'
    it means setting the instance to be release at that time.
    if the property is None, it means cancel the auto delete time.
    :return:
    '''
    request = ModifyInstanceAutoReleaseTimeRequest()
    request.set_InstanceId(instance_id)
    if time_to_release is not None:
        request.set_AutoReleaseTime(time_to_release)
    _send_request(request)
    release_time = check_auto_release_time_ready(instance_id)
    logging.info("Check instance %s auto release time setting is %s. ", instance_id, release_time)


def _send_request(request):
    '''
    send open api request
    :param request:
    :return:
    '''
    request.set_accept_format('json')
    try:
        response_str = clt.do_action(request)
        logging.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        logging.error(e)


if __name__ == '__main__':
    logging.info("Release ecs instance by Aliyun OpenApi!")
    stop_instance('i-bp1aet7s13lfpjop****')
    # set_instance_auto_release_time('i-bp1187lghfcy8nnz****', '2020-04-17T06:00:00Z')
    # set_instance_auto_release_time('i-bp1aet7s13lfpjop****')
    # release_instance('i-bp1aet7s13lfpjop****')
    # release_instance('i-bp1aet7s13lfpjop****', True)

Stop an ECS instance

Before you release an ECS instance, make sure that the ECS instance is in the Stopped state. After the ECS instance is stopped, you can restart the ECS instance based on your needs.

The command used to stop the ECS instance is easy to use. You can use the same command to stop pay-as-you-go and subscription instances. When the ForceStop parameter is set to true, the ECS instance is stopped but its data is not necessarily written to the disk, which is similar to a power failure. Therefore, if you want to release an ECS instance, set ForceStop to true.

def stop_instance(instance_id, force_stop=False):
    '''
    stop one ecs instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force_stop: if force stop is true, it will force stop the server and not ensure the data
    write to disk correctly.
    :return:
    '''
    request = StopInstanceRequest()
    request.set_InstanceId(instance_id)
    request.set_ForceStop(force_stop)
    logging.info("Stop %s command submit successfully.", instance_id)
    _send_request(request)

Release an ECS instance

If you release an ECS instance that is not in the Stopped state, the following error may occur:
{"RequestId":"3C6DEAB4-7207-411F-9A31-6ADE54C268BE","HostId":"ecs-cn-hangzhou.aliyuncs.com","Code":"IncorrectInstanceStatus","Message":"The current status of the resource does not support this operation."}
If an ECS instance is in the Stopped state, you can release it. The following parameters are used to release an ECS instance:
  • InstanceId: the ID of the instance.
  • force: specifies whether to forcibly release the instance. If this parameter is set to true, the instance is released forcibly even when the instance is not in the Stopped state. Exercise caution when you set this parameter. Release by mistake may affect your business.
The following content is a request to release an ECS instance:
def release_instance(instance_id, force=False):
    '''
    delete instance according instance id, only support after pay instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force:
    if force is false, you need to make the ecs instance stopped, you can
    execute the delete action.
    If force is true, you can delete the instance even the instance is running.
    :return:
    '''
    request = DeleteInstanceRequest();
    request.set_InstanceId(instance_id)
    request.set_Force(force)
    _send_request(request)
The following response is returned if the ECS instance is released:
{"RequestId":"689E5813-D150-4664-AF6F-2A27BB4986A3"}

Set the automatic release time for an ECS instance

You can set the automatic release time for an ECS instance to simplify instance management. When the release time is reached, Alibaba Cloud automatically releases the ECS instance without the need for manual intervention.

Note Specify the automatic release time in the ISO 8601 standard in the yyyy-MM-ddTHH:mm:ssZ format. The time must be in UTC. If the value of the seconds place is not 00, the time will automatically be set to the start of the specified minute. The automatic release time ranges from 30 minutes later than the current time to three years later than the current time.
def set_instance_auto_release_time(instance_id, time_to_release = None):
    '''
    setting instance auto delete time
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param time_to_release: if the property is setting, such as '2017-01-30T00:00:00Z'
    it means setting the instance to be release at that time.
    if the property is None, it means cancel the auto delete time.
    :return:
    '''
    request = ModifyInstanceAutoReleaseTimeRequest()
    request.set_InstanceId(instance_id)
    if time_to_release is not None:
        request.set_AutoReleaseTime(time_to_release)
    _send_request(request)

Run set_instance_auto_release_time('i-1111', '2017-01-30T00:00:00Z') to set the automatic release time.

After the time is set, you can call DescribeInstances to query the automatic release time:

def describe_instance_detail(instance_id):
    '''
    describe instance detail
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :return:
    '''
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get('Instances').get('Instance')
        if len(instance_list) > 0:
            return instance_list[0]
def check_auto_release_time_ready(instance_id):
    detail = describe_instance_detail(instance_id=instance_id)
    if detail is not None:
        release_time = detail.get('AutoReleaseTime')
        return release_time

Cancel the automatic release

If you want to cancel the automatic release due to your business changes, run the following command to set the automatic release time to null:

set_instance_auto_release_time('i-1111')