Asynchronous Invocation

Next, let’s invoke a second Lambda Function asynchronously.

When you invoke a function asynchronously, you don’t wait for a response from the function code. You hand off the event to Lambda and Lambda handles the rest.

In this setupStack function, we’ll use the destinations namespace to achieve this.

Import the namespace

From aws/compute import the destinations namespace:

import { NodejsFunction, destinations } from "terraconstructs/lib/aws/compute";

Configure Async Invocation

Use the configureAsyncInvoke method on the first lambda with the second lambda as a FunctionDestination.

export function setupStack(stack: AwsStack) {
const first = new NodejsFunction(stack, "First", {
path: logEventhandlerPath,
});
const second = new NodejsFunction(stack, "Second", {
path: logEventhandlerPath,
});
first.configureAsyncInvoke({
onSuccess: new destinations.FunctionDestination(second),
});
}

The synthesized Terraform Configuration now includes the lambda_function_event_config resource.

Also notice the First_ServiceRole_DefaultPolicy_... includes the necessary permissions to invoke the Second Lambda Function.

{
"statement": [
{
8 collapsed lines
"actions": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"effect": "Allow",
"resources": [
"*"
]
},
{
"actions": [
"lambda:InvokeFunction"
],
"effect": "Allow",
"resources": [
"${aws_lambda_function.Second_394350F9.arn}",
"${aws_lambda_function.Second_394350F9.qualified_invoke_arn}"
]
}
]
}

Explore other Destinations

Post a successful execution message to a Queue with the SqsDestination:

// import Queue from aws/notify
import { Queue } from "terraconstructs/lib/aws/notify";
// Send Success events to an SQS Queue
const queue = new Queue(stack, "Queue");
first.configureAsyncInvoke({
onSuccess: new destinations.SqsDestination(queue),
});

You will notice the First_ServiceRole_DefaultPolicy_... now includes permissions to send messages to the Queue instead.

{
"statement": [
{
8 collapsed lines
"actions": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"effect": "Allow",
"resources": [
"*"
]
},
{
"actions": [
"sqs:SendMessage",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl"
],
"effect": "Allow",
"resources": [
"${aws_sqs_queue.Queue_4A7E3555.arn}"
]
}
]
}

Modifying the Payload

Sometimes the payload should be modified before sending it to the destination, this can be done through AWS EventBridge rules.

A shortcut to send only the responsePayload field of the source function is provided:

export function setupStack(stack: AwsStack) {
const first = new NodejsFunction(stack, "First", {
path: logEventhandlerPath,
});
const second = new NodejsFunction(stack, "Second", {
path: logEventhandlerPath,
});
first.configureAsyncInvoke({
onSuccess: new destinations.FunctionDestination(
second,
{
responseOnly: true,
}
),
});
}

The resulting Terraform Configuration has significant changes:

  1. The first Lambda must have events:PutEvents permissions:

    {
    "statement": [
    {
    8 collapsed lines
    "actions": [
    "xray:PutTraceSegments",
    "xray:PutTelemetryRecords"
    ],
    "effect": "Allow",
    "resources": [
    "*"
    ]
    },
    {
    "actions": [
    "events:PutEvents"
    ],
    "effect": "Allow",
    "resources": [
    1 collapsed line
    "arn:${data.aws_partition.Partitition.partition}:events:us-east-1:${data.aws_caller_identity.CallerIdentity.account_id}:event-bus/default"
    ]
    }
    ]
    }
  2. An EventBridge Rule with event_pattern:

    {
    "source": [
    "lambda"
    ],
    "detail-type": [
    "Lambda Function Invocation Result - Success"
    ],
    3 collapsed lines
    "resources": [
    "${aws_lambda_function.First_8D4707F1.arn}:$LATEST"
    ]
    }
  3. An EventBridge Target to invoke the Second Lambda Function with only the $.detail.responsePayload as input.

    "aws_cloudwatch_event_target": {
    "First_EventInvokeConfig_Success_Target0_EDB5EF3B": {
    "arn": "${aws_lambda_function.Second_394350F9.arn}",
    "input_path": "$.detail.responsePayload",
    "rule": "${aws_cloudwatch_event_rule.First_EventInvokeConfig_Success_865FF6FF.name}",
    "target_id": "Target0"
    }
    },
  4. Lambda Permissions for EventBridge to invoke the second lambda

    "aws_lambda_permission": {
    "First_EventInvokeConfig_Success_AllowEventRuleworkshopSecondB5BBED9A_D7DAB648": {
    "action": "lambda:InvokeFunction",
    "function_name": "${aws_lambda_function.Second_394350F9.arn}",
    "principal": "events.amazonaws.com",
    "source_arn": "${aws_cloudwatch_event_rule.First_EventInvokeConfig_Success_865FF6FF.arn}"
    }
    }

Conclusion

In this lesson we saw how flexible the TerraConstructs library is with examples of Asynchronous Invocation configurations.

Read more about Asynchronous invocation.

Powered by WebContainers
Files
Preparing Environment
  • Installing dependencies