npm package: @ixor/aws-cdk-ixor-lambda
Description: ## Overview
Author: Rik Tytgat
Latest version: 1.2.0-rc-18

# @ixor/aws-cdk-ixor-lambda module

## Overview

```
+----+ Ixor Lambda Construct+----------------------------------+
|                                                              |
| +--------------------+   +---------------------------------+ |
| |                    |   |                                 | |
| | CW Event Rule      |   | Lambda Function                 | |
| |                    |   |                                 | |
| |                    |   | if (event.dummy) {              | |
| |{                   |   |   sleep(event.dummySleepSeconds | |
| |  "count": 2,       |   |   return({})                    | |
| |  "lambdaArn": "arn"|   | }                               | |
| |}                   |   | ...                             | |
| |                    |   |                                 | |
| +---------------+----+   +---^-----------------------------+ |
|                 |            |                               |
+--------------------------------------------------------------+
                  |            +
                  |         count times
                  |            |
                  |            |
            +-----v------------+---------+
            |                            |
            |  keepWarmLambdaFunction    |
            |                            |
            |  {                         |
            |    "dummy": "dummy",       |
            |    "dummySleepSeconds": 1  |
            |  }                         |
            +----------------------------+
```

This is a aws-cdk construct that extends the default Lambda `Function` class with
_keepWarm_ functionality.

The `Function` class can have 4 optional properties that configure the _keepWarm_ behaviour
of the function:

```typescript
interface IxorLambdaFunctionProps extends lambda.FunctionProps {
      keepWarm?: boolean,
      keepWarmEventSchedule?: events.Schedule,
      keepWarmLambdaFunction?: lambda.IFunction,
      keepWarmCount?: number
}
```

When `keepWarm` is `true`, the `keepWarmLambdaFunction` is required.

`keepWarmCount` defaults to `2` is not specified.

`keepWarmEventSchedule` defaults to business hours.

## Prerequisite: the _keep warm_ lambda function

This function should already exist in the AWS account. It is triggered by the _CloudWatch_ rule with
an event that looks like this:

```json
{
  "count": 2,
  "lambdaArn": "arn-of-the-lambda-function-to-keep-warm"
}
```

The function should have invoke permissions on all Lambda's to keep warm, and it will asynchonously
invoke the function in `lambdaArn` `count` times.

This is an implementation of the _keep warm_ Lambda, it is also
[available on npm](https://www.npmjs.com/package/@ixor/aws-cdk-lambda-warmer).

```python
import json
import logging
import boto3
import os

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

client = boto3.client("lambda")

dummy_sleep_seconds = os.getenv('DUMMY_SLEEP_SECONDS', '1')

def lambda_handler(event, context):
    logger.info(json.dumps(event))
    count = event.get('count', 3)
    lambda_arn = event.get('lambdaArn')
    logger.debug(f"Lambda to warm: {lambda_arn}")
    logger.debug(f"How many? {count}")
    logger.info(f"Asynchronously starting {count} target lambdas")

    success_count = 0

    for i in range(count):
        logger.debug(f"Iteration {i+1}")
        try:
            client.invoke(
                FunctionName=lambda_arn,
                InvocationType='Event',
                Payload=f'{{"dummy": "dummy", "dummySleepSeconds": {dummy_sleep_seconds} }}'
            )
        except Exception as e:
            logger.error(f"Exception occured: {e}")
        else:
            success_count = success_count + 1

    logger.info(f"{success_count}/{count} successful invocations")

    return {
        'statusCode': 200,
        'body': json.dumps('Finished')
    }
```

## How it works

The construct creates 2 resources:

* A _CloudWatch_ rule
* The Lambda function (that optionally needs to be kept Warm)

### The _CloudWatch_ rule

The _CloudWatch_ rule is configured to start the keep warm Lambda function with a preconfigured event. The event
has 2 required properties:

* `count`: How many instances of the target Lambda to try to keep warm
* `lambdaArn`: The _ARN_ of the Lambda function to keep warm

### The Lambda Function

The Lambda function is created as documented in the AWS CDK Lambda `Function` class. But in order
to be kept warm, the function should be able to process a dummy event. The _keep warm_ lambda function (see
the prerequisite section) will invoke the function with a dummy event that looks like this:

```json
{
  "dummy": "dummy",
  "dummySleepSeconds": 1
}
```

The Lambda function should check for the dummy event and _sleep_ the requested amount of time (in seconds).

### Testing

A test stack is added in `lib\test-aws-cdk-ixor-lambda-stack`. Created in this stack: 
* `keepWarmLambda`: this lambda will send out a dummy event every 10 minutes.
* `lambdaToKeepWarm`: this is a lambda created through the `IxorFunction` and needs to be kept warm
* The appropriate permissions for the `keepWarmLambda` to invoke the `lambdaToKeepWarm`.

The code for both lambdas is situated in the `test_aws_cdk_ixor_lambda_handler` directory.

To test this stack, deploy the `test/test-aws-cdk-ixor-lambda` app to sandbox. Every 10 minutes, the keepWarm 
lambda will trigger the lambdaToKeepWarm with a dummy event, both log this in CloudWatch.