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: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"]}]} -
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
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"}}, -
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.
- Installing dependencies