All Products
Search
Document Center

Elastic Compute Service:Renew an ECS instance

Last Updated:Mar 21, 2024

You can renew an Elastic Compute Service (ECS) instance in the ECS console or on the instance buy page. You can also call API operations provided by Alibaba Cloud to renew an ECS instance and query the expiration time of the instance.

Background information

The lifecycle is important for subscription ECS instances. If you fail to renew an ECS instance before the instance expires, the instance may be locked or even released. This affects service continuity. You can use API operations to query the expiration time of instances and renew instances at the earliest opportunity.

This topic describes how to renew an ECS instance. This topic provides the sample code and the explanation of the sample code. For more information, see the following sections in this topic:

Sample code

#  coding=utf-8
# 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 4.4.3, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging
import os
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DescribeInstanceAutoRenewAttributeRequest import \
    DescribeInstanceAutoRenewAttributeRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.ModifyInstanceAutoRenewAttributeRequest import \
    ModifyInstanceAutoRenewAttributeRequest
from aliyunsdkecs.request.v20140526.RenewInstanceRequest import RenewInstanceRequest

# Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are configured in the code runtime environment. 
# If the project code is leaked, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. The following sample code shows how to use environment variables to obtain an AccessKey pair and use the AccessKey pair to call API operations. We recommend that you use Security Token Service (STS) tokens, which provide higher security.
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(os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'], os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'], '<region-Id>')

INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING = '2017-01-22T00:00Z'
INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING = '2017-01-28T00:00Z'
def renew_job(page_size=100, page_number=1, check_need_renew=True, security_group_id=None):
    response = describe_need_renew_instance(page_size=page_size, page_number=page_number, check_need_renew=check_need_renew, security_group_id=security_group_id)
    response_list = response.get('Instances').get('Instance')
    logging.info("%s instances need to renew", str(response.get('TotalCount')))
    if response_list > 0:
        instance_ids = ''
        for item in response_list:
            instance_id = item.get('InstanceId')
            instance_ids += instance_id + ','
            renew_instance(instance_id=instance_id)
        logging.info("%s execute renew action ready", instance_ids)

def describe_need_renew_instance(page_size=100, page_number=1, instance_id=None, check_need_renew=True, security_group_id=None):
    request = DescribeInstancesRequest()
    if check_need_renew is True:
        request.set_Filter3Key("ExpiredStartTime")
        request.set_Filter3Value(INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING)
        request.set_Filter4Key("ExpiredEndTime")
        request.set_Filter4Value(INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING)
    if instance_id is not None:
        request.set_InstanceIds(json.dumps([instance_id]))
    if security_group_id:
        request.set_SecurityGroupId(security_group_id)
    request.set_PageNumber(page_number)
    request.set_PageSize(page_size)
    return _send_request(request)

def describe_instance_auto_renew_setting(instance_ids, expected_auto_renew=True):
    describe_request = DescribeInstanceAutoRenewAttributeRequest()
    describe_request.set_InstanceId(instance_ids)
    response_detail = _send_request(request=describe_request)
    failed_instance_ids = ''
    if response_detail is not None:
        attributes = response_detail.get('InstanceRenewAttributes').get('InstanceRenewAttribute')
        if attributes:
            for item in attributes:
                auto_renew_status = item.get('AutoRenewEnabled')
                if auto_renew_status != expected_auto_renew:
                    failed_instance_ids += item.get('InstanceId') + ','
    if len(failed_instance_ids) > 0:
        logging.error("instance %s auto renew not match expect %s.", failed_instance_ids,
                      expected_auto_renew)

def setting_instance_auto_renew(instance_ids, auto_renew=True):
    logging.info('execute enable auto renew ' + instance_ids)
    request = ModifyInstanceAutoRenewAttributeRequest();
    request.set_Duration(1);
    request.set_AutoRenew(auto_renew);
    request.set_InstanceId(instance_ids)
    _send_request(request)
    describe_instance_auto_renew_setting(instance_ids, auto_renew)

def check_instance_need_renew(instance_id):
    response = describe_need_renew_instance(instance_id=instance_id)
    if response is not None:
        return response.get('TotalCount') == 1
    return False

def renew_instance(instance_id, period='1'):
    need_renew = check_instance_need_renew(instance_id)
    if need_renew:
        _renew_instance_action(instance_id, period)
        # describe_need_renew_instance(instance_id=instance_id, check_need_renew=False)

def _renew_instance_action(instance_id, period='1'):
    request = RenewInstanceRequest()
    request.set_Period(period)
    request.set_InstanceId(instance_id)
    response = _send_request(request)
    logging.info('renew %s ready, output is %s ', instance_id, response)

def _send_request(request):
    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("Renew ECS Instance by OpenApi!")
    # Query instances that expire within a specified time range. 
    describe_need_renew_instance()
    # Renew the instances. Renewal fees are automatically deducted from your account. 
    # renew_instance('i-bp1aet7s13lfpjop****')
    # Query the auto-renewal status of the instances. 
    # describe_instance_auto_renew_setting('i-bp1aet7s13lfpjop****,i-bp13uh1twnfv7vp8****')
    # Configure auto-renewal for the instances. 
    # setting_instance_auto_renew('i-bp1aet7s13lfpjop****,i-bp13uh1twnfv7vp8****')

Query instances that expire within a specified time range

You can call the DescribeInstances operation to query instances that expire within the time range specified by ExpiredStartTime and ExpiredEndTime. The start time and end time follow the ISO 8601 standard in the yyyy-MM-ddThh:mmZ format and must be in UTC. If you want to filter instances by security group, specify the IDs of the security groups.

INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING = '2017-01-22T00:00Z'
INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING = '2017-01-28T00:00Z'

def renew_job(page_size=100, page_number=1, check_need_renew=True, security_group_id=None):
    response = describe_need_renew_instance(page_size=page_size, page_number=page_number, check_need_renew=check_need_renew, security_group_id=security_group_id)
    response_list = response.get('Instances').get('Instance')
    logging.info("%s instances need to renew", str(response.get('TotalCount')))
    if response_list > 0:
        instance_ids = ''
        for item in response_list:
            instance_id = item.get('InstanceId')
            instance_ids += instance_id + ','
            renew_instance(instance_id=instance_id)
        logging.info("%s execute renew action ready", instance_ids)

Renew an ECS instance

You can renew only subscription ECS instances. Make sure that your account supports balance payments or credit payments. After you call the relevant API operation to renew an ECS instance, the renewal fee is deducted from your account and an order is created. Make sure that your account has sufficient funds to support automatic deduction of fees.

def _renew_instance_action(instance_id, period='1'):
    request = RenewInstanceRequest()
    request.set_Period(period)
    request.set_InstanceId(instance_id)
    response = _send_request(request)
    logging.info('renew %s ready, output is %s ', instance_id, response)

When an instance is renewed, the renewal fee is automatically deducted from your account. After the renewal is complete, you can query the expiration time of the instance based on InstanceId. The expiration time may be updated in 10 seconds because the API operation is called asynchronously.

Enable auto-renewal for ECS instances

Alibaba Cloud provides auto-renewal for subscription ECS instances to help you reduce maintenance costs. The renewal fee is automatically deducted from your account at 08:00:00 on the ninth day before an instance expires. If the first deduction attempt fails, Alibaba Cloud attempts to deduct the fee on the following days until the fee is deducted. If the payment is not complete after nine days, the instance is locked. Make sure that your account has sufficient balance or credit.

  • Query auto-renewal settings

    You can call API operations to query and configure auto-renewal. The API operations support only subscription ECS instances. If you call the API operations on a pay-as-you-go instance, an error is returned. You can query the auto-renewal status of up to 100 subscription ECS instances at a time. Separate the instance IDs with commas (,).

    The input parameters of the DescribeInstanceAutoRenewAttribute operation include InstanceId.

    InstanceId: the IDs of instances. You can specify up to 100 subscription instance IDs at a time. Separate the instance IDs with commas (,).

    def describe_instance_auto_renew_setting(instance_ids, expected_auto_renew=True):
        describe_request = DescribeInstanceAutoRenewAttributeRequest()
        describe_request.set_InstanceId(instance_ids)
        response_detail = _send_request(request=describe_request)
        failed_instance_ids = ''
        if response_detail is not None:
            attributes = response_detail.get('InstanceRenewAttributes').get('InstanceRenewAttribute')
            if attributes:
                for item in attributes:
                    auto_renew_status = item.get('AutoRenewEnabled')
                    if auto_renew_status != expected_auto_renew:
                        failed_instance_ids += item.get('InstanceId') + ','
    
    describe_instance_auto_renew_setting('i-bp1aet7s13lfpjop****,i-bp13uh1twnfv7vp8****')

    Sample response:

    {"InstanceRenewAttributes":{"InstanceRenewAttribute":[{"Duration":0,"InstanceId":"i-1111","AutoRenewEnabled":false},{"Duration":0,"InstanceId":"i-2222","AutoRenewEnabled":false}]},"RequestId":"71FBB7A5-C793-4A0D-B17E-D6Bxxxxxxxxx"}

    If auto-renewal is configured, the value true is returned for AutoRenewEnabled. Otherwise, the value false is returned.

  • Enable and disable auto-renewal for ECS instances

    Configure the following input parameters to enable auto-renewal:

    • InstanceId: the IDs of instances. You can specify up to 100 subscription instance IDs at a time. Separate the instance IDs with commas (,).

    • Duration: the duration of ECS instances. Valid values: 1, 2, 3, 6, and 12. Unit: month.

    • AutoRenew: specifies whether to enable auto-renewal. Valid values: true and false. Set the value to true to enable auto-renewal. Set the value to false to disable auto-renewal.

    def setting_instance_auto_renew(instance_ids, auto_renew = True):
        logging.info('execute enable auto renew ' + instance_ids)
        request = ModifyInstanceAutoRenewAttributeRequest();
        request.set_Duration(1);
        request.set_AutoRenew(auto_renew);
        request.set_InstanceId(instance_ids)
        _send_request(request)

    If the operation is successful, the following response is returned:

    {"RequestId":"7DAC9984-AAB4-43EF-8FC7-7D7xxxxxxxxx"}

    After auto-renewal is enabled, you can query the auto-renewal status again. The system returns the auto-renewal duration and status in the following code:

    {"InstanceRenewAttributes":{"InstanceRenewAttribute":[{"Duration":1,"InstanceId":"i-1111","AutoRenewEnabled":true},{"Duration":1,"InstanceId":"i-2222","AutoRenewEnabled":true}]},"RequestId":"7F4D14B0-D0D2-48C7-B310-B1DF713D4331"}