Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New serverless pattern - EventBridge Scheduler to invoke Step Functions to get the List of Inactive Lambda functions #2533

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions eventbridge-stepfunction-lambda-getfunctionstatus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# EventBridge Scheduler to invoke Step Functions to get the List of Inactive Lambda functions

This pattern will create a one time schedule in EventBridge Scheduler with State machine as Target & Invoke the Lambda ListFunctions & GetFunction API using the SDK integration in Step Functions and publish the List of Inactive functions to SNS Topic.

Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.

## Requirements

* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) (AWS SAM) installed

## Deployment Instructions

1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
```
git clone https://github.com/aws-samples/serverless-patterns
```
2. Change directory to the pattern directory:
```
cd eventbridge-stepfunction-lambda-getfunctionstatus
```
3. Build the dependencies:
```
sam build
```
4. From the command line, use AWS SAM to deploy the AWS resources for the pattern as specified in the template.yml file:
```
sam deploy --guided
```
5. During the prompts:
* Enter a stack name
* Enter the desired AWS Region
* Parameter EmailAddress
* Allow SAM CLI to create IAM roles with the required permissions.

Once you have run `sam deploy --guided` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy` in future to use these defaults.

6. Note the outputs from the SAM deployment process. These contain the resource names and/or ARNs which are used for testing.

## How it works

1. When the stack is deployed it creates a Step Functions state machine, an EventBridge Scheduler,a SNS Topic with Email subscription, a Lambda Function and required IAM roles.

2. Event Bridge scheduler invokes the State machine on defined schedule, Default schedule to invoke the state machine daily at 00::00 UTC with payload. Modify the schedule as per your requirement.

```json
{
"Function_ARN_List_existing": {
"lambda_arn_list_combined": []
},
"NextMarker": null
}
```

3) In Step function, the 1st step is to get the List of Lambda functions using the ListFunctions API call, ListFunctions API is called multiple times as it return max 50 Functions in a single API Call. NextMarker in the response is used to get the list of next 50 Functions.

4) Lambda Invoke - Combine data Step : This a custom lambda function python script to create a combined json array of Lambda function ARN's.

5) Map - Loop Functions State : In this state, GetFunction API is called for each Lambda ARN taken as input from previous step & status of each function is checked and appended to the output.

6) Filter Inactive Functions State : This filters out the Active functions from the Json array and passes only the Inactive Functions list to the next step.

7) SNS Publish : List of Inactive functions is published to the SNS Topic.


## Cleanup

1. Delete the stack
```bash
sam delete
```

2. Also, you have to manually delete any schedules you created if required.

----
Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.

SPDX-License-Identifier: MIT-0
73 changes: 73 additions & 0 deletions eventbridge-stepfunction-lambda-getfunctionstatus/pattern.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"title": "Find Inactive lambda functions and Publish it to SNS topic using Step Functions.",
"description": "Simple pattern that creates a Step Functions & uses SDK integration to find Inactive functions and Publish it to SNS topic.",
"language": "Python",
"level": "200",
"framework": "SAM",
"introBox": {
"headline": "How it works",
"text": [
"Creates a one time schedule in EventBridge Scheduler with Step Functions as target and uses SDK integration to find the Lambda function Status and return list of Inactive Functions and then publishing to the SNS Topic."
]
},
"gitHub": {
"template": {
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/eventbridge-stepfunction-lambda-getfunctionstatus",
"templateURL": "serverless-patterns/eventbridge-stepfunction-lambda-getfunctionstatus",
"projectFolder": "eventbridge-stepfunction-lambda-getfunctionstatus",
"templateFile": "eventbridge-stepfunction-lambda-getfunctionstatus/template.yaml"
}
},
"resources": {
"bullets": [
{
"text": "Introducing Amazon EventBridge Scheduler",
"link": "https://aws.amazon.com/blogs/compute/introducing-amazon-eventbridge-scheduler/"
},
{
"text": "Amazon EventBridge Scheduler Docs",
"link": "https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html"
},
{
"text": "Amazon EventBridge Scheduler Docs",
"link": "https://docs.aws.amazon.com/lambda/latest/api/API_ListFunctions.html"
},
{
"text": "Lambda ListFunctions API",
"link": "https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html"
},
{
"text": "Lambda GetFunction API",
"link": "https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html"
},
{
"text": "SNS Publish API",
"link": "https://docs.aws.amazon.com/sns/latest/api/API_Publish.html"
}
]
},
"deploy": {
"text": [
"sam deploy"
]
},
"testing": {
"text": [
"See the GitHub repo for detailed testing instructions."
]
},
"cleanup": {
"text": [
"Delete the stack: <code>sam delete</code>."
]
},
"authors": [
{
"name": "Sahil Kapoor",
"image": "https://media.licdn.com/dms/image/v2/D5603AQHTVptga3RxcA/profile-displayphoto-shrink_800_800/B56ZO3ZfseHoAc-/0/1733948735068?e=1739404800&v=beta&t=FX6MFZ2JFH17KQc89u4gY6tQXGoMJLiLkB2qT3MtV2g",
"bio": "AWS Cloud Support Engineer",
"linkedin": "sahil-kapoor-503391a7",
"twitter": ""
}
]
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"Comment": "A description of my state machine",
"StartAt": "ListFunctions",
"States": {
"ListFunctions": {
"Type": "Task",
"Arguments": {
"Marker": "{% $states.input.NextMarker%}"
},
"Resource": "arn:aws:states:::aws-sdk:lambda:listFunctions",
"Next": "Lambda Invoke - Combine data",
"Output": {
"ListFunctions_output": "{% $states.result%}",
"Function_ARN_List_existing": {
"lambda_arn_list_combined": "{% $states.input.Function_ARN_List_existing.lambda_arn_list_combined%}"
}
}
},
"Lambda Invoke - Combine data": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Output": "{% $states.result.Payload %}",
"Arguments": {
"FunctionName": "${LambdaFunctionArn}",
"Payload": "{% $states.input %}"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2,
"JitterStrategy": "FULL"
}
],
"Next": "Check NextMarker"
},
"Check NextMarker": {
"Type": "Choice",
"Choices": [
{
"Next": "ListFunctions",
"Condition": "{% $states.input.NextMarkercheck = 'true' %}",
"Output": "{% $states.input%}"
}
],
"Default": "Map - Loop Functions"
},
"Map - Loop Functions": {
"Type": "Map",
"ItemProcessor": {
"ProcessorConfig": {
"Mode": "INLINE"
},
"StartAt": "GetFunction",
"States": {
"GetFunction": {
"Type": "Task",
"Arguments": {
"FunctionName": "{% $states.input.ARN %}"
},
"Resource": "arn:aws:states:::aws-sdk:lambda:getFunction",
"Next": "Check Function Status"
},
"Check Function Status": {
"Type": "Choice",
"Choices": [
{
"Next": "Inactive",
"Output": {
"FunctionConfig": {
"ARN": "{% $states.input.Configuration.FunctionArn %}",
"State": "{% $states.input.Configuration.State %}",
"StateReason": "{% $states.input.Configuration.StateReason %}",
"StateReasonCode": "{% $states.input.Configuration.StateReasonCode %}",
"LastModified": "{% $states.input.Configuration.LastModified %}"
}
},
"Condition": "{% $states.input.Configuration.State = 'Inactive' %}"
}
],
"Default": "Pass",
"Output": {
"FunctionConfig": {
"ARN": "{% $states.input.Configuration.FunctionArn %}",
"State": "{% $states.input.Configuration.State %}"
}
}
},
"Pass": {
"Type": "Pass",
"End": true
},
"Inactive": {
"Type": "Pass",
"End": true
}
}
},
"Items": "{% $states.input.Function_ARN_List_existing.lambda_arn_list_combined %}",
"Next": "Filter Inactive Functions",
"MaxConcurrency": 40
},
"Filter Inactive Functions": {
"Type": "Pass",
"Next": "Choice",
"Output": {
"Inactive_Functions": "{% $states.input.FunctionConfig[State='Inactive'] ? $states.input.FunctionConfig[State='Inactive'] : false %}"
}
},
"Choice": {
"Type": "Choice",
"Choices": [
{
"Condition": "{% $states.input.Inactive_Functions = false %}",
"Next": "No Inactivce Function",
"Output": {
"Inactive_Functions": " No Inactive Functions"
}
}
],
"Default": "Pass (2)"
},
"Pass (2)": {
"Type": "Pass",
"Next": "SNS Publish"
},
"No Inactivce Function": {
"Type": "Pass",
"Next": "SNS Publish"
},
"SNS Publish": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Arguments": {
"TopicArn": "${TopicARN}",
"Message": "{% $states.input.Inactive_Functions %}",
"Subject": "Inactive Lambda functions List"
},
"End": true
}
},
"QueryLanguage": "JSONata"
}
Loading