Elizabeth
Engineer
Engineer
  • UID625
  • Fans2
  • Follows1
  • Posts68
Reads:820Replies:0

Group and manage ECS using tags

Created#
More Posted time:Mar 1, 2017 14:57 PM
This article is the first one for ECS management using OpenAPI. It mainly focuses on resource grouping using tags. Only clear grouping can help you to operate, maintain and manage ECS conveniently in the future.
Resource grouping using tags
Many users will group resources by the ECS name and descriptions during ECS usage. A defect here is that a cloud resource only supports one name and description. An important task for ECS batch management is to group the resources. To facilitate resource management, ECS has enabled an important concept of tag, which has the following conventions:
• The tag here is not quite the same with the traditional tag. Tag supports the Key-Value model and you can specify them at the same time.
• Tag supports ECS instances, disks, snapshots, images and security groups.
• Each resource can bind up to ten tags.
• If the key of the tag you want to bind already exists in the specified resource, the value will be overwritten.
You can try to use tag functionality in ECS Console. With OpenAPI, you can conveniently create and change a tag.
Bind a tag to cloud resources
You should specify the resource ID and type to bind a tag to it. Currently images, instances, snapshots, disks and security groups are supported.
def add_tag_to_resource(resource_id, resource_type, tag_key, tag_value):
    request = AddTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_ResourceType(resource_type)
    request.set_Tag1Key(tag_key)
    request.set_Tag1Value(tag_value)
    _send_request(request)


The operation below creates two tag groups on one ECS instance, one is ecs-console and the other is ecs-console-pre.
instance_id = 'i-1111'
    tag_key = 'ecs-console'
    tag_value = 'product'
    resource_type = 'instance'
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value)
    add_tag_to_resource(instance_id, resource_type, tag_key + '-pre', tag_value)


If two values are assigned to the same key, the second value will overwrite the first one. The operation below will only add one group of key-value successfully.
instance_id = 'i-1111'
    tag_key = 'ecs-console'
    tag_value = 'product'
    resource_type = 'instance'
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value)
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value + '-pre')


Query a bound tag
The query of a tag can be completed directly. For example, you can achieve this by querying the instance list of the ECS instances.
def describe_instance_tags(instance_id):
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get('Instances').get('Instance')
        if len(instance_list) > 0:
            instance_detail = instance_list[0]
            if instance_detail.get('Tags') is not None:
                return instance_detail.get('Tags').get('Tag')


You can quickly query resources of varied combinations of dimensions through querying tags directly and achieve highly customized applications through the tag for the combination. For example, you can add the pre tag for the pre-release environment and the product tag for the production environment to manage resources conveniently.
We have also provided the tag query feature to facilitate multi-dimensional search.
def describe_tags(tag_key=None, tag_value=None, resource_type=None, resource_id=None):
    request = DescribeTagsRequest()
    if resource_type is not None:
        request.set_ResourceType(resource_type)
    if resource_id is not None:
        request.set_ResourceId(resource_id)
    if tag_key is not None:
        request.set_Tag1Key(tag_key)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    response = _send_request(request)
    return response.get('Tags').get('Tag')

The returned content of the query is as follows:
[{u'TagKey': u'ecs-console-pre', u'TagValue': u'product'}, {u'TagKey': u'ecs-console', u'TagValue': u'product'}]

Delete a bound tag
Apart from overwriting a tag, you can also conveniently delete a tag. The resource ID and type should be specified to delete a tag. You can also specify the tag to delete all the values under it. You can also delete a group of key-values.
def remove_tag_from_resource(resource_id, resource_type, tag_key, tag_value=None):
    request = RemoveTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_Tag1Key(tag_key)
    request.set_ResourceType(resource_type)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    _send_request(request)


Summary
You can group your applications conveniently by using tags flexibly. You can also differentiate your testing, pre-release, production, stress testing and elastic environments through tags for convenient batch resource operations.
The full code is as follows:
#  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 2.1.2, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging

from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.AddTagsRequest import AddTagsRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.DescribeTagsRequest import DescribeTagsRequest
from aliyunsdkecs.request.v20140526.RemoveTagsRequest import RemoveTagsRequest

# configuration the log output formatter, if you want to save the output to file,
# append ",filename='ecs_invoke.log'" after datefmt.

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('Your Access Key Id', 'Your Access Key Secrect', 'cn-beijing')

def add_tag_to_resource(resource_id, resource_type, tag_key, tag_value):
    '''
    add tag to resource
    :param resource_id: it can be instance id ,disk id
    :param resource_type: support image、instance、snapshot、disk、securitygroup
    :param tag_key: tag's key
    :param tag_value: tag's value
    :return:
    '''
    '''
    :param resource_id:
    :param resource_type:
    :param tag_key:
    :param tag_value:
    :return:
    '''
    request = AddTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_ResourceType(resource_type)
    request.set_Tag1Key(tag_key)
    request.set_Tag1Value(tag_value)
    _send_request(request)


def remove_tag_from_resource(resource_id, resource_type, tag_key, tag_value=None):
    '''
    remove tag from resource
    :param resource_id: required. it can be instance id ,disk id.
    :param resource_type: support image、instance、snapshot、disk、securitygroup
    :param tag_key: tag key to remove
    :param tag_value: tag value to remove
    :return:
    '''
    request = RemoveTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_Tag1Key(tag_key)
    request.set_ResourceType(resource_type)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    _send_request(request)


def describe_tags(tag_key=None, tag_value=None, resource_type=None, resource_id=None):
    '''
    describe resource group according tag query condition.
    :param tag_key:
    :param tag_value:
    :param resource_type:
    :param resource_id:
    :return:
    '''
    request = DescribeTagsRequest()
    if resource_type is not None:
        request.set_ResourceType(resource_type)
    if resource_id is not None:
        request.set_ResourceId(resource_id)
    if tag_key is not None:
        request.set_Tag1Key(tag_key)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    response = _send_request(request)
    return response.get('Tags').get('Tag')


def describe_instance_tags(instance_id):
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get('Instances').get('Instance')
        if len(instance_list) > 0:
            instance_detail = instance_list[0]
            if instance_detail.get('Tags') is not None:
                return instance_detail.get('Tags').get('Tag')

# send open 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__':
    logging.info("Manager ECS by OpenApi!")
    instance_id = 'i-1111'
    tag_key = 'ecs-console'
    tag_value = 'product'
    resource_type = 'instance'
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value)
    add_tag_to_resource(instance_id, resource_type, tag_key + '-pre', tag_value)
    logging.info(describe_instance_tags(instance_id))
    remove_tag_from_resource(instance_id, resource_type, tag_key)
    logging.info(describe_instance_tags(instance_id))
    describe_tags(resource_id=instance_id)
Guest