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/notifyimport { Queue } from "terraconstructs/lib/aws/notify";
// Send Success events to an SQS Queueconst 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:
-
The first Lambda must have
events:PutEventspermissions:{"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"]}]} -
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"]} -
An EventBridge Target to invoke the
SecondLambda Function with only the$.detail.responsePayloadas 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"}}, -
Lambda Permissions for EventBridge to invoke the
secondlambda"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.
- Installing dependencies