This topic describes how to use Alibaba Cloud Elastic Compute Service (ECS) SDK for Python to call the DescribeResourcesModification operation to query available resources that can be used to change the configurations of an ECS instance. In this topic, Python 2.7 is used.

Prerequisites

The AccessKey pair and the ID of the region where the resources reside are obtained. For more information, see Regions and zones and Create an AccessKey pair.

Background information

You can call the ModifyInstanceSpec or ModifyPrepayInstanceSpec operation to change the configurations of an ECS instance. Before you call an API operation to change the configurations of an ECS instance, you can call the DescribeResourcesModification operation to query the following resources:
  • Resources that can be used to upgrade the configurations of the ECS instance
  • Resources that can be used to upgrade the system disk
When you call the DescribeResourcesModification operation, you can set the MigrateAcrossZone parameter to true to query available resources that can be used to change the configurations of an ECS instance across generations. The private IP address of an ECS instance of the classic network type changes if you change the configurations of the instance across generations. If you are using a retired instance type, exercise caution when you upgrade a non-I/O-optimized instance to an I/O-optimized instance. The following table describes the results that may occur based on the network type and instance family if the configurations of an ECS instance are changed.
Item Configuration change of a Generation-I non-I/O-optimized instance across instance types in the classic network Configuration change of a Generation-I non-I/O-optimized instance across instance types in a VPC Configuration change of an instance of other generations in the classic network Configuration change of an instance of other generations in a VPC
Private IP address Changed Unchanged Changed Unchanged
Disk device name (only in Linux) Basic disk (cloud) Changed to xvd* such as xvda and xvdb Unchanged
Ultra disk (cloud_efficiency) Changed to vd* such as vda and vdb
Software authorization code Changed

Install ECS SDK for Python

The following example shows how to install ECS SDK for Python in Linux:

  • For root users, run the following command:
    pip install aliyun-python-sdk-ecs
  • For non-root users, run the following command:
    sudo pip install aliyun-python-sdk-ecs
Note Make sure that you are using ECS SDK for Python 4.6.3 or later. To download the latest version of ECS SDK for Python, go to GitHub Repo Alibaba Cloud.

Sample scenarios

#  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.6.3, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging

from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DescribeResourcesModificationRequest import DescribeResourcesModificationRequest

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')

# Your AccessKey ID. 
ak_id = "YOUR_ACCESS_KEY_ID"

# Your AccessKey secret. 
ak_secret = "YOUR_ACCESS_SECRET"

# The ID of the region where your resource resides. 
region_id = "cn-hangzhou"

# Your resource ID, such as an instance ID. 
resource_id = "i-bp1187lghfcy8nnz****"

# The target resource type. Valid values: InstanceType and SystemDisk. 
destination_instance_type ='InstanceType'
destination_system_disk ='SystemDisk'

# The operation that you want to perform to change configurations. Valid values: Upgrade, Downgrade, RenewDowngrade, and RenewModify. 
operation_type = 'Upgrade'

# The new instance type. You can call the DescribeInstanceTypes operation to query the most recent list of instance types. When the DestinationResource parameter is set to SystemDisk, you must specify the InstanceType parameter. 
instance_type = "ecs.g6.large"

"""
Exercise caution when you set the MigrateAcrossZone parameter. MigrateAcrossZone (Boolean) specifies whether the configurations of an ECS instance can be changed across generations. Default value: False. 
If the MigrateAcrossZone parameter is set to True, take note of the following items when you upgrade the configurations of the ECS instance based on the response:
Instances of the classic network type:
1. For Generation-I instances, when you upgrade non-I/O-optimized instances to I/O-optimized instances, the private IP addresses, disk device names, and software authorization codes of the instances are changed. For Linux instances, basic disks (cloud) are identified by the prefix xvd such as xvda and xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified by the prefix vd such as vda and vdb. 
2. For instances of other generations, the private IP addresses of the instances are changed when you change the configurations of the instances across generations. 
Instances of the VPC type: For Generation-I instances, when non-I/O-optimized instances are upgraded to I/O-optimized instances, the disk device names and software authorization codes of the instances are changed. For Linux instances, basic disks (cloud) are identified by the prefix xvd such as xvda and xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified by the prefix vd such as vda and vdb. 
"""
migrate_across_zone = False

clt = client.AcsClient(ak_id, ak_secret, region_id)

# Query the resources that can be used to upgrade instance types. 
def describe_resource_instance_type():
    request = build_request()
    request.set_DestinationResource(destination_instance_type)
    _execute_request(request)

# Query the resources that can be used to upgrade system disks. 
def describe_resource_system_disk():
    request = build_request()
    request.set_DestinationResource(destination_system_disk)
    request.set_InstanceType(instance_type)
    _execute_request(request)

def _execute_request(request):
    response = _send_request(request)
    if response is None:
        print ('response is None')
        return
    if response.get('Code') is None:
        availableZones = response.get('AvailableZones').get('AvailableZone')
        if availableZones is None:
            print ('availableZones is None')
            return
        for availableZone in availableZones:
            zoneId = availableZone.get('ZoneId')
            values = []
            availableResources = availableZone.get('AvailableResources').get('AvailableResource')
            if availableResources is None:
                print ('availableResources is None')
                return
            for availableResource in availableResources:
                supportedResources = availableResource.get('SupportedResources').get('SupportedResource')
                if supportedResources is None:
                    print ('supportedResource is None')
                    return
                for supportedResource in supportedResources:
                    status = supportedResource.get('Status')
                    if status == "Available":
                        value = supportedResource.get('Value')
                        values.append(value)
            print ("ecs in zone %s resource value list is %s"%(zoneId, values))

def build_request():
    request = DescribeResourcesModificationRequest()
    request.set_ResourceId(resource_id)
    request.set_MigrateAcrossZone(migrate_across_zone)
    request.set_OperationType(operation_type)
    return request

# Initiate an API request. 
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)

Scenario 1: Query the resources that can be used to upgrade instance types

# Query the resources that can be used to upgrade instance types.
def describe_resource_instance_type():
    request = build_request()
    request.set_DestinationResource(destination_instance_type)
    _execute_request(request)

Scenario 2: Query the resources that can be used to upgrade system disks

# Query the resources that can be used to upgrade system disks.
def describe_resource_system_disk():
    request = build_request()
    request.set_DestinationResource(destination_system_disk)
    request.set_InstanceType(instance_type)
    _execute_request(request)

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.6.3, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging

from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DescribeResourcesModificationRequest import DescribeResourcesModificationRequest

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')

# Your AccessKey ID. 
ak_id = "YOUR_ACCESS_KEY_ID"

# Your AccessKey secret. 
ak_secret = "YOUR_ACCESS_SECRET"

# The ID of the region where your resource resides. 
region_id = "cn-hangzhou"

# Your resource ID, such as an instance ID. 
resource_id = "i-bp1187lghfcy8nnz****"

# The target resource type. Valid values: InstanceType and SystemDisk. 
destination_instance_type ='InstanceType'
destination_system_disk ='SystemDisk'

# The operation that you want to perform to change configurations. Valid values: Upgrade, Downgrade, RenewDowngrade, and RenewModify. 
operation_type = 'Upgrade'

# The new instance type. You can call the DescribeInstanceTypes operation to query the most recent list of instance types. When the DestinationResource parameter is set to SystemDisk, you must specify the InstanceType parameter. 
instance_type = "ecs.g6.large"

"""
Exercise caution when you set the MigrateAcrossZone parameter. MigrateAcrossZone (Boolean) specifies whether the configurations of an ECS instance can be changed across generations. Default value: False. 
If the MigrateAcrossZone parameter is set to True, take note of the following items when you upgrade the configurations of the ECS instance based on the response:
Instances of the classic network type:
1. For Generation-I instances, when non-I/O-optimized instances are upgraded to I/O-optimized instances, the private IP addresses, disk device names, and software authorization codes of the instances are changed. For Linux instances, basic disks (cloud) are identified by the prefix xvd such as xvda and xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified by the prefix vd such as vda and vdb. 
2. For instances of other generations, the private IP addresses of the instances are changed when you change the configurations of the instances across generations. 
Instances of the VPC type: For Generation-I instances, when you upgrade non-I/O-optimized instances to I/O-optimized instances, the disk device names and software authorization codes of the instances are changed. For Linux instances, basic disks (cloud) are identified by the prefix xvd such as xvda and xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified by the prefix vd such as vda and vdb. 
"""
migrate_across_zone = False

clt = client.AcsClient(ak_id, ak_secret, region_id)

# Query the resources that can be used to upgrade instance types. 
def describe_resource_instance_type():
    request = build_request()
    request.set_DestinationResource(destination_instance_type)
    _execute_request(request)

# Query the resources that can be used to upgrade system disks. 
def describe_resource_system_disk():
    request = build_request()
    request.set_DestinationResource(destination_system_disk)
    request.set_InstanceType(instance_type)
    _execute_request(request)

def _execute_request(request):
    response = _send_request(request)
    if response is None:
        print ('response is None')
        return
    if response.get('Code') is None:
        availableZones = response.get('AvailableZones').get('AvailableZone')
        if availableZones is None:
            print ('availableZones is None')
            return
        for availableZone in availableZones:
            zoneId = availableZone.get('ZoneId')
            values = []
            availableResources = availableZone.get('AvailableResources').get('AvailableResource')
            if availableResources is None:
                print ('availableResources is None')
                return
            for availableResource in availableResources:
                supportedResources = availableResource.get('SupportedResources').get('SupportedResource')
                if supportedResources is None:
                    print ('supportedResource is None')
                    return
                for supportedResource in supportedResources:
                    status = supportedResource.get('Status')
                    if status == "Available":
                        value = supportedResource.get('Value')
                        values.append(value)
            print ("ecs in zone %s resource value list is %s"%(zoneId, values))

def build_request():
    request = DescribeResourcesModificationRequest()
    request.set_ResourceId(resource_id)
    request.set_MigrateAcrossZone(migrate_across_zone)
    request.set_OperationType(operation_type)
    return request

# Initiate an API request. 
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__':
    print ("hello ecs describe resources")
    # Query the resources that can be used to upgrade instance types. 
    describe_resource_instance_type()
    # Query the resources that can be used to upgrade system disks. 
    # describe_resource_system_disk()