This topic describes how to use Alibaba Cloud ECS SDK for Python to query available resources in Python 2.7 that you can use to change the configurations of an ECS instance.

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.

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 information:
  • Available resources that you can use to upgrade the configurations of the ECS instance
  • Available resources that you can use to upgrade the system disk
When you call the DescribeResourcesModification operation, you can set the MigrateAcrossZone parameter to true to query available resources that you can use to change the configurations of an ECS instance across generations. The private IP address of the ECS instance of the classic network type will change if you change the configurations of the instance across generations. If you are using a phased-out 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 subject to change Change configurations of a non-I/O optimized generation 1 instance across instance types Change configurations of an instance of other generations
Classic network VPC Classic network VPC
Private IP address Changed Unchanged Changed Unchanged
Driver name (only in Linux) Basic disk: cloud Changed to xvda or xvdb Unchanged
Ultra disk: cloud_efficiency Changed to vda or vdb
Software authorization code Changed

Install SDK for Python

The following example shows how to install 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 Ensure that you are using SDK for Python 4.6.3 or later. For more information about the latest version of ECS SDK for Python, visit GitHub Repo Alibaba Cloud.

Usage 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 = "YOU_ACCESS_KEY_ID"

# Your AccessKey secret.
ak_secret = "YOU_ACCESS_SECRET"

# The region ID of the ECS resource.
region_id = "cn-hangzhou"

# The resource ID, such as the 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 target instance type. You can call DescribeInstanceTypes 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.
When the MigrateAcrossZone parameter is set to True, and you upgrade the configurations of the ECS instance based on the returned information, take note of the following considerations:
Instances of the classic network type:
1. For generation 1 instances, when non-I/O optimized instances are upgraded to I/O optimized instances, the information of the instances is changed, such as the private IP addresses, drive names, and software authorization codes. For Linux instances, basic disks (cloud) are identified as xvda or xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified as vda or 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 1 instances, when non-I/O optimized instances are upgraded to I/O optimized instances, the information of the instances is changed, such as the drive names and software authorization codes. For Linux instances, basic disks (cloud) are identified as xvda or xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified as vda or vdb.
"""
migrate_across_zone = False

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

# Query available 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 available 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 available resources that can be used to upgrade instance types

# Query available 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 available resources that can be used to upgrade system disks

# Query available 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 = "YOU_ACCESS_KEY_ID"

# Your AccessKey secret.
ak_secret = "YOU_ACCESS_SECRET"

# The region ID of the ECS resource.
region_id = "cn-hangzhou"

# The resource ID, such as the 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 target instance type. You can call DescribeInstanceTypes 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.
When the MigrateAcrossZone parameter is set to True, and you upgrade the configurations of the ECS instance based on the returned information, take note of the following considerations:
Instances of the classic network type:
1. For generation 1 instances, when non-I/O optimized instances are upgraded to I/O optimized instances, the information of the instances is changed, such as the private IP address, drive name, and software authorization code. For Linux instances, basic disks (cloud) are identified as xvda or xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified as vda or 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 1 instances, when non-I/O optimized instances are upgraded to I/O optimized instances, the information of the instances is changed, such as the drive name and software authorization code. For Linux instances, basic disks (cloud) are identified as xvda or xvdb. Ultra disks (cloud_efficiency) and standard SSDs (cloud_ssd) are identified as vda or vdb.
"""
migrate_across_zone = False

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

# Query available 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 available 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 available resources that can be used to upgrade instance types.
    describe_resource_instance_type()
    # Query available resources that can be used to upgrade system disks.
    # describe_resource_system_disk()