This topic describes how to query information about available resources before you change the configurations of an ECS instance.

Background information

Before you call an API to modify the configuration of an ECS instance (such as ModifyInstanceSpec or ModifyPrepayInstanceSpec), you can call DescribeResourcesModification to:

  • Query the information of available resources you can use to upgrade an ECS instance.
  • Query the information of available resources you can use to upgrade a system disk.

Limits

If you need to change the configurations of one or more ECS instances of different network types and different instance generations at a time, you can configure MigrateAcrossZone=true in DescribeResourcesModification. However, such changes will modify the private IP addresses of ECS instances of the Classic network type. If you are using phased-out instance types, you must exercise caution when you upgrade a non-I/O-optimized instance to an I/O-optimized instance. Depending on the network type or instance type family, changes to the configurations of one or more ECS instances at a time may cause the following results.

Item subject to change Change configurations of a non-I/O-optimized Generation I instance across instance types Change configurations of instances of other generations
Classic network VPC Classic network VPC
Private IP address Will change Will not change Will change Will not change
Drive name (Linux only) Basic cloud disk cloud Changes to xvda or xvdb Will not change
Ultra disk cloud_efficiency Changes to vda or vdb
Software license code Will change

Prerequisites

You have obtained the AccessKey and the region ID of the related resource. For more information, see Regions and zones and Create an AccessKey.

Install the Python SDK

Note Make sure that your Python SDK version is v4.6.3 or later. To get the latest ECS SDK, go to GitHub Repo Alibaba Cloud.

The following examples show how to install the Python SDK in the Linux (the version of Python is v2.7):

  • For root users, run:
    pip install aliyun-python-sdk-ecs
  • For ordinary users, run:
    sudo pip install aliyun-python-sdk-ecs
Note Make sure that your Python SDK version is v4.6.3 or later. To get the latest ECS SDK, go to GitHub Repo Alibaba Cloud.

Scenario example

# Your AccessKeyId
ak_id = "YOU_ACCESS_KEY_ID"

# Your AccessKeySeret
ak_secret = "YOU_ACCESS_SECRET"

# ID of the region to which the resource belongs
region_id = "cn-hangzhou"

# Resource ID, such as an instance ID
resource_id = "i-xxxx"

# Target resource type. Valid values: Instanceype| SystemDisk
destination_instance_type ='InstanceType'
destination_system_disk ='SystemDisk'

# Actions for changing configurations. Valid values: Upgrade | Downgrade | RenewDongrade | RenewModify
operation_type = 'Upgrade'

# Target instance type. You can call DescribeInstanceTypes to get the latest instance types. When the DestinationResource parameter takes the value of SystemDisk, the InstanceType parameter must be specified.
instance_type = "ecs.n1.large"

# Exercise caution when configuring the MigrateAcrossZone parameter. MigrateAcrossZone (Boolean) allows you to change configurations across one or more instances. Default value: False
# If the parameter MigrateAcrossZone takes the value of True, after you have upgraded your ECS instance according to the returned information, note the following:
# Classic network instances:
# 1. For a Generation I ECS instance, if it is upgraded from a non-I/O-optimized instance to an I/O-optimized instance, its private IP address, drive name, and software license code will change. For Linux instances, the basic cloud disk (cloud) will be identified as xvda or xvdb, and the Ultra Disk (cloud_efficiency) and SSD Cloud disk (cloud_ssd) will be identified as vda or vdb.
# 2. For other generations of instances, the private IP address will change.
# VPC instances: For a Generation I ECS instance, if it is upgraded from a non-I/O-optimized instance to an I/O-optimized instance, its drive name and software license code will change. For Linux instances, the basic cloud disk (cloud) will be identified as xvda or xvdb, and the Ultra Disk (cloud_efficiency) and SSD Cloud disk (cloud_ssd) will be identified as vda or vdb.
migrate_across_zone = False

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

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

# Send 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)        return response_detail
    except Exception as e:
        logging.error(e)

Scenario 1: Query available resources for upgrading an instance type

# Query available resources for upgrading an instance type
def describe_resource_instance_type():
    request = build_request()
    request.set_DestinationResource(destination_instance_type)
    _execute_request(request)

Scenario 2: Query available resources for upgrading a system disk

# Query available resources for upgrading a system disk
def describe_resource_system_disk():
    request = build_request()
    request.set_DestinationResource(destination_system_disk)
    request.set_InstanceType(instance_type)
    _execute_request(request)

Complete code

#  coding=utf-8

# if the python sdk is not install, run 'sudo pip install aliyun-python-sdk-ecs'
# if the python sdk is install, run 'sudo pip install --upgrade aliyun-python-sdk-ecs'
# make sure the sdk version is 4.6.3. To check your version, run 'pip show aliyun-python-sdk-ecs' '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 AccessKeyId
ak_id = "YOU_ACCESS_KEY_ID"

# Your AccessKeySecret
ak_secret = "YOU_ACCESS_SECRET"

# ID of the region to which the resource belongs

region_id = "cn-hangzhou"

# Resource ID, such as an instance ID
resource_id = "i-xxxx"

# Target resource type. Valid values: InstanceType| SystemDisk
destination_instance_type ='InstanceType'
destination_system_disk ='SystemDisk'

# Actions for changing configurations. Valid values: Upgrade | Downgrade | RenewDowngrade | RenewModify
operation_type = 'Upgrade'

# Target instance type. You can call DescribeInstanceTypes to get the latest instance types. When the DestinationResource parameter takes the value of SystemDisk, the InstanceType parameter must be specified.
instance_type = "ecs.n1.large"

# Exercise caution when configuring the MigrateAcrossZone parameter. MigrateAcrossZone (Boolean) allows you to change configurations across one or more instances. Default value: False
# If the parameter MigrateAcrossZone takes the value of True, after you have upgraded your ECS instance according to the returned information, note the following:
# Classic network instances:
# 1. For a Generation I ECS instance, if it is upgraded from a non-I/O-optimized instance to an I/O-optimized instance, its private IP address, drive name, and software license code will change. For Linux instances, the basic cloud disk (cloud) will be identified as xvda or xvdb, and the Ultra Disk (cloud_efficiency) and SSD Cloud disk (cloud_ssd) will be identified as vda or vdb.
# 2. For other generations of instances, the private IP address will change.
# VPC instances: For a Generation I ECS instance, if it is upgraded from a non-I/O-optimized instance to an I/O-optimized instance, its drive name and software license code will change. For Linux instances, the basic cloud disk (cloud) will be identified as xvda or xvdb, and the Ultra Disk (cloud_efficiency) and SSD Cloud disk (cloud_ssd) will be identified as vda or vdb.
migrate_across_zone = False

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

# Query available resources for upgrading an instance type
def describe_resource_instance_type():
    request = build_request()
    request.set_DestinationResource(destination_instance_type)
    _execute_request(request)

# Query available resources for upgrading a system disk
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

# Send the 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"
    # describe_resource_instance_type()
    # describe_resource_system_disk()
    # describe_resource_instance_type()
    # describe_resource_system_disk()