All Products
Search
Document Center

Elastic Compute Service:Query available resources for configuration changes

Last Updated:Sep 13, 2023

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 you can use to change the configurations of an ECS instance. In this topic, Python 2.7 is used.

Prerequisites

An 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:

  • Available resources that you can use to upgrade the instance type

  • Available resources that you can use to upgrade the system disk

When you call the DescribeResourcesModification operation, you can set MigrateAcrossZone to true to query the resources that are available for cross-generation instance configuration changes. The private IP address of the 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 if the configurations of an ECS instance are changed. The results vary based on the network type and generation of the instance.

Item subject to change

Change configurations of a non-I/O optimized Generation I instance across instance types in the classic network

Change configurations of a non-I/O optimized Generation I instance across instance types in a VPC

Change configurations of an instance of other generations in the classic network

Change configurations of an instance of other generations in a VPC

Private IP address

Changed

Unchanged

Changed

Unchanged

Device name (only in Linux)

Basic disk: cloud

Changes to xvd* such as xvda and xvdb

Unchanged

Ultra disk: cloud_efficiency

Changes 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.

Examples

#  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
import os

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

# 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 resources within 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. The sample code is for reference only. We recommend that you use Security Token Service (STS) tokens, which provide higher security.
ak_id = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']
ak_secret = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']

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

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

# Specify the 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 is a boolean parameter that 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 response, take note of the following items:
Instances that reside in the classic network:
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 as xvd* such as xvda and xvdb, ultra disks (cloud_efficiency), and standard SSDs (cloud_ssd) are identified as 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 that reside in a virtual private cloud (VPC): 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 as xvd* such as xvda and xvdb, ultra disks (cloud_efficiency), and standard SSDs (cloud_ssd) are identified as vd* such as vda and 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
import os

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

# 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 resources within 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. The sample code is for reference only. We recommend that you use STS tokens, which provide higher security.
ak_id = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']
ak_secret = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']

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

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

# Specify the 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 is a boolean parameter that 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 response, take note of the following items:
Instances that reside in the classic network:
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 as xvd* such as xvda and xvdb, ultra disks (cloud_efficiency), and standard SSDs (cloud_ssd) are identified as 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 that reside in a VPC: 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 as xvd* such as xvda and xvdb, ultra disks (cloud_efficiency), and standard SSDs (cloud_ssd) are identified as vd* such as vda and 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()