This topic describes how to define a function in the Function Compute console to search for disks that are attached to an Elastic Compute Service (ECS) instance and create snapshots for the disks after the ECS instance is restarted.

Define function code

  1. Log on to the Function Compute console.
  2. In the top navigation bar, select your region.
  3. In the left-side navigation pane, click Service/Function.
  4. Find the target function in the target service and click the name of the function.
  5. Click the Code tab and write code in the code editor.

    In the following example, Python is used to define the function:

    # -*- coding: utf-8 -*-
    import logging
    import json, random, string, time
    from aliyunsdkcore import client
    from aliyunsdkecs.request.v20140526.DeleteSnapshotRequest import DeleteSnapshotRequest
    from aliyunsdkecs.request.v20140526.CreateSnapshotRequest import CreateSnapshotRequest
    from aliyunsdkecs.request.v20140526.DescribeDisksRequest import DescribeDisksRequest
    from aliyunsdkcore.auth.credentials import StsTokenCredential
    
    LOGGER = logging.getLogger()
    clt = None
    
    def handler(event, context):
      creds = context.credentials
      sts_token_credential = StsTokenCredential(creds.access_key_id, creds.access_key_secret, creds.security_token)
      '''
      {
        "product": "ECS",
        "content": {
            "executeFinishTime": "2018-06-08T01:25:37Z",
            "executeStartTime": "2018-06-08T01:23:37Z",
            "ecsInstanceName": "timewarp",
            "eventId": "e-t4nhcpqcu8fqushpn3mm",
            "eventType": "InstanceFailure.Reboot",
            "ecsInstanceId": "i-bp18l0uopocfc98xxxx" 
        },
        "resourceId": "acs:ecs:cn-hangzhou:12345678:instance/i-bp18l0uopocfc98xxxx",
        "level": "CRITICAL",
        "instanceName": "instanceName",
        "status": "Executing",
        "name": "Instance:SystemFailure.Reboot:Executing", 
        "regionId": "cn-hangzhou"
      }
      '''
    
      evt = json.loads(event)
      content = evt.get("content");
      ecsInstanceId = content.get("ecsInstanceId");
      regionId = evt.get("regionId");
    
      global clt
      clt = client.AcsClient(region_id=regionId, credential=sts_token_credential)
      name = evt.get("name");
      name = name.lower()
    
      if name in [ 'Instance:SystemFailure.Reboot:Executing'.lower(), "Instance:InstanceFailure.Reboot:Executing".lower()]:
        pass
        # do other things
    
      if name in ['Instance:SystemFailure.Reboot:Executed'.lower(), "Instance:InstanceFailure.Reboot:Executed".lower()]:
        request = DescribeDisksRequest()
        request.add_query_param("RegionId", regionId)
        request.set_InstanceId(ecsInstanceId)
        response = _send_request(request)
        disks = response.get('Disks').get('Disk', [])
        for disk in disks:
          diskId = disk["DiskId"]
          SnapshotId = create_ecs_snap_by_id(diskId)
          LOGGER.info("Create ecs snap sucess, ecs id = %s , disk id = %s ", ecsInstanceId, diskId)
    
    def create_ecs_snap_by_id(disk_id):
        LOGGER.info("Create ecs snap, disk id is %s ", disk_id)
        request = CreateSnapshotRequest()
        request.set_DiskId(disk_id)
        request.set_SnapshotName("reboot_" + ''.join(random.choice(string.ascii_lowercase) for _ in range(6)))
        response = _send_request(request)
        return response.get("SnapshotId")
    
    # send open api request
    def _send_request(request):
        request.set_accept_format('json')
        try:
            response_str = clt.do_action_with_exception(request)
            LOGGER.info(response_str)
            response_detail = json.loads(response_str)
            return response_detail
        except Exception as e:
            LOGGER.error(e)