[PYTHON] Try AWS Lambda Destinations

AWS has announced some amazing features.

Introducing AWS Lambda Destinations https://aws.amazon.com/jp/blogs/compute/introducing-aws-lambda-destinations/

スクリーンショット 2019-11-27 6.51.44.png

The next action (AWS service) can be specified according to the execution result of Lambda. If you want to control the flow based on success / failure conditions, you can now complete it with Lambda without using Step Functions.

Try immediately.

Define the calling Lambda appropriately

Write Python like this. (Using Python 3.7)

import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)


def destination_sample_handler(event, context):
    logger.info("destination sample lambda started.")
    if event['Success'] == True:
        return {
            'statusCode': 200,
            'body': event
        }
    else:
        raise Exception('Success is False', event)
    

When calling, the Success variable is defined in event, and the judgment is changed depending on whether the content is True or False.

Set Destination

In the AWS blog, I change the call destination of success / failure between SNS and Lambda, but I cut corners and make both Lambda.

When you access your Lambda function, you should find an item called "Add destination" in the "Designer" part "Cofiguration" tag.

スクリーンショット 2019-11-29 7.10.51.png

This is a success pattern スクリーンショット 2019-11-27 7.16.10.png

The contents of the success pattern are like this. It just outputs to Log.

import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("Success dest lambda started.")
    logger.info(event)
    return {
        'statusCode': 200,
        'message': 'Success in dest lambda',
        'body': event
    }

This is the destination setting of failure スクリーンショット 2019-11-27 7.18.20.png

The contents are the same as the success pattern


import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("Failure dest lambda started.")
    logger.info(event)
    return {
        'statusCode': 200,
        'message': "Failure in dest lambda",
        'body': event
    }

Try to run

Execution is performed from the CLI.

$ aws lambda invoke --function-name destination-sample --invocation-type Event --payload '{ "Success": false }' response.json
{
    "StatusCode": 202
}

It seems that 202 is returned as Status Code if the execution is successful.

success

When I made it successful, there was an output like this in CloudWatch Logs on the successful side. CloudWatch Logs

[INFO]	2019-11-26T22:26:49.792Z	xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	{'version': '1.0', 'timestamp': '2019-11-26T22:26:49.425Z', 'requestContext': {'requestId': '26fab6f9-a2b7-45f2-bce2-47c612cdb8b7', 'functionArn': 'arn:aws:lambda:us-east-1:000000000000:function:destination-sample:$LATEST', 'condition': 'Success', 'approximateInvokeCount': 1}, 'requestPayload': {'Success': True}, 'responseContext': {'statusCode': 200, 'executedVersion': '$LATEST'}, 'responsePayload': {'statusCode': 200, 'body': {'Success': True}}}

I logged out the contents of the called event, but it looks like the following.

--Condition has success / failure --The original caller event is included in requestPayload --The value returned from the caller is entered in responsePayload.

When I edited the code a little and put the Message element in event, the contents of responsePayload were added.

    if event['Success'] == True:
        event['Message'] = "Successful finished."
        return {
            'statusCode': 200,
            'body': event
        }
[INFO]	2019-11-26T23:41:21.229Z	xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	{'version': '1.0', 'timestamp': '2019-11-26T23:41:20.730Z', 'requestContext': {'requestId': 'ba73f7a2-77f4-4166-a95d-d43020e5cc32', 'functionArn': 'arn:aws:lambda:us-east-1:000000000000:function:destination-sample:$LATEST', 'condition': 'Success', 'approximateInvokeCount': 1}, 'requestPayload': {'Success': True}, 'responseContext': {'statusCode': 200, 'executedVersion': '$LATEST'}, 'responsePayload': {'statusCode': 200, 'body': {'Success': True, 'Message': 'Successful finished.'}}}

By the way, when I increased the Destination at the time of success by one, the setting on the On success side was overwritten. There seems to be one service that can be called for one condition.

スクリーンショット 2019-11-27 8.55.42.png

Even if Add destination is executed, the call destination of On success is only overwritten.

スクリーンショット 2019-11-27 8.40.59_deco.png

Failure

A similar log appeared on CloudWatch Logs on the failed side.

[INFO]	2019-11-26T22:30:46.594Z	xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	{'version': '1.0', 'timestamp': '2019-11-26T22:30:46.203Z', 'requestContext': {'requestId': '6fc2d258-fafb-40a2-8d18-886df8510fa1', 'functionArn': 'arn:aws:lambda:us-east-1:000000000000:function:destination-sample:$LATEST', 'condition': 'RetriesExhausted', 'approximateInvokeCount': 3}, 'requestPayload': {'Success': False}, 'responseContext': {'statusCode': 200, 'executedVersion': '$LATEST', 'functionError': 'Unhandled'}, 'responsePayload': {'errorMessage': "('Success is False', {'Success': False})", 'errorType': 'Exception', 'stackTrace': ['  File "/var/task/lambda_function.py", line 17, in destination_sample_handler\n    raise Exception(\'Success is False\', event)\n']}}

The contents of the Exception are also propagated properly.

By the way, what is the display on X-Ray?

In X-Ray, the process properly branched from Lambda. As you can imagine, this is amazing. You can almost trace with this.

スクリーンショット 2019-11-27 8.51.34.png

Summary

I could easily branch the process depending on success / failure. This is enough for a little script control.

Recommended Posts

Try AWS Lambda Destinations
Try giving AWS Lambda environment variables?
[AWS] Try tracing API Gateway + Lambda with X-Ray
Tweet from AWS Lambda
[Python] Scraping in AWS Lambda
The simplest AWS Lambda implementation
Try using AWS SageMaker Studio
AWS Lambda with PyTorch [Lambda import]
Web scraping using AWS lambda
lambda
Summary if using AWS Lambda (Python)
Touch AWS Lambda environment variable support
[AWS] Create API with API Gateway + Lambda
Write AWS Lambda function in Python
Run Python on Schedule on AWS Lambda
Tweet WakaTime Summary using AWS Lambda
Using Lambda with AWS Amplify with Go
Notify HipChat with AWS Lambda (Python)
AWS Lambda Development My Best Practices
[AWS] Using ini files with Lambda [Python]
[Linux] [AWS Lambda] Cron format setting manual
Environment when AWS Lambda includes native libraries
Regularly post to Twitter using AWS lambda!
[AWS] Link Lambda and S3 with boto3
[Python] Run Headless Chrome on AWS Lambda
Connect to s3 with AWS Lambda Python
[AWS] Do SSI-like things with S3 / Lambda
Summary of how to write AWS Lambda
Try assigning or switching with Python: lambda
Python + Selenium + Headless Chromium with aws lambda
I just did FizzBuzz with AWS Lambda
Try implementing a Cisco Spark bot with AWS Lambda + Amazon API Gateway (Python)