AWS Lambda is a serverless computing service that lets you run code without provisioning any servers. Lambda functions can also be used to automate processes. The property of the Lambda function that makes it useful in automation is the Lambda trigger. These triggers can be invoked by various AWS services, allowing Lambda to execute its code based on the results of different processes being run on other AWS services.
We’ll look at this trigger implementation by configuring our Lambda function to be triggered each time an object is added to a specific S3 bucket.
Before we can create a Lambda function, we’ll require an IAM role because Lambda mostly uses other AWS services and AWS services are required to assume an IAM role to use other AWS services. The code below creates an IAM role for our Lambda function.
Enter your AWS access_key_id
and secret_access_key
in the widget below before executing the code. To generate these keys, you can check our Answer on “How to generate AWS access keys.’’
Note: The IAM user whose credentials are being used must have the permissions to perform all the required actions.
import boto3import jsonaws_region = 'us-east-1'# Configure an IAM clientiam = boto3.client('iam', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)# Define the trust policytrust_policy = {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "lambda.amazonaws.com"},"Action": "sts:AssumeRole"}]}# Create an IAM role which can only be assumed by Lambdarole = iam.create_role(RoleName='LambdaRole', AssumeRolePolicyDocument=json.dumps(trust_policy))# Attach the AWSLambda_FullAccess policy to the roleiam.attach_role_policy(RoleName='LambdaRole', PolicyArn='arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole')# Get the ARN of the created rolerole_arn = role['Role']['Arn']print("IAM Role ARN:", role_arn)
Copy the role ARN we’ll get in response and save it in the iam_role_arn
field in the playground below.
Now that we have the required IAM role, let’s create the Lambda function. Execute the code given below to create a Lambda function titled EducativeLambda
. The lambda_function.py
file contains the code which we’ll run using our Lambda function. This file is zipped using the start script and sent along with the configurations in the Code
argument of create_function
method used in lines 21–32.
import boto3aws_region = 'us-east-1' # Change this to your desired AWS region# Create a Boto3 Lambda clientlambda_client = boto3.client('lambda', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)# Lambda function codelambda_function_name = 'S3ObjectCreatedLambda'lambda_role_arn = role_arn# Lambda function handlerlambda_handler = 'lambda_function.lambda_handler'# Read the zip file contentwith open('lambda_function.zip', 'rb') as f:zip_content = f.read()# Create the Lambda functionresponse = lambda_client.create_function(FunctionName='EducativeLambda',Runtime='python3.8',Role=lambda_role_arn,Handler=lambda_handler,Code={'ZipFile': zip_content},Description='Lambda function for S3 object creation event',Timeout=30, # Set the function timeout (in seconds)MemorySize=128, # Set the function memory size (in MB))# Print the function ARNprint('Lambda Function ARN:', response['FunctionArn'])
Copy the Lambda ARN we’ll get in response and save it in the lambda_role_arn
field in the playground below.
The code we’ve written in our Lambda function will read the name of the object added to the S3 bucket and publish it on CloudWatch Logs. We are yet to set up the trigger, but the code was written keeping in mind the kind of trigger we’ll set up later.
Now, let’s create an S3 bucket, which we’ll use to test our Lambda trigger. The code below creates an S3 bucket. Before executing the code, enter a name for the bucket in the s3_bucket_name
field in the widget below.
import boto3aws_region = 'us-east-1'# Initialize an S3 clients3 = boto3.client('s3', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)bucket_name = bucket_name# Create the S3 buckets3.create_bucket(Bucket=bucket_name)print(f"Bucket {bucket_name} created successfully.")
Our S3 bucket is created successfully.
Now that everything is ready, let’s set up the Lambda trigger. The code below sets up a Lambda trigger, invoking the Lambda function each time an object is added to the bucket.
import boto3aws_region = 'us-east-1'# Initialize Lambda and S3 clientslambda_client = boto3.client('lambda', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)s3_client = boto3.client('s3', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)# Add permission to the Lambda function for S3lambda_response = lambda_client.add_permission(FunctionName='EducativeLambda',StatementId='S3InvokeLambdaPermission',Action='lambda:InvokeFunction',Principal='s3.amazonaws.com',SourceArn=f'arn:aws:s3:::{bucket_name}')# Define the S3 bucket notification configurationnotification_config = {'LambdaFunctionConfigurations': [{'LambdaFunctionArn': lambda_arn,'Events': ['s3:ObjectCreated:*']}]}# Add the S3 trigger for your Lambda functions3_response = s3_client.put_bucket_notification_configuration(Bucket=bucket_name, NotificationConfiguration=notification_config)print('Added S3 trigger to Lambda function for the S3 bucket.')
S3 is not directly allowed to trigger the Lambda function. So, we’ve first added a resource-based policy in the Lambda function using the add_permission
method in lines 10–16. After that, we’ve set up the trigger using the put_bucket_notification_configuration
method in line 29.
Let’s create an object in the S3 bucket and see if our Lambda trigger is working or not. The code below creates an object in the S3 bucket.
import boto3aws_region = 'us-east-1's3_bucket_name = bucket_names3_object_key = 'educative_object'# Initialize an S3 clients3_client = boto3.client('s3', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)# Create a simple text object in the S3 buckets3_client.put_object(Bucket=s3_bucket_name,Key=s3_object_key,Body="This is a sample text object.")print(f"Created S3 object at s3://{s3_bucket_name}/{s3_object_key}")
Now, let’s look at the Lambda logs to confirm whether the trigger worked. The code below prints all the logs of the Lambda function.
import boto3aws_region = 'us-east-1'# Initialize a CloudWatch Logs clientlogs_client = boto3.client('logs', region_name=aws_region, aws_access_key_id=aws_key_id, aws_secret_access_key=secret_access_key)log_group_name = '/aws/lambda/EducativeLambda'# List the log streams in the specified log grouplog_streams_response = logs_client.describe_log_streams(logGroupName=log_group_name,orderBy='LastEventTime',descending=True,limit=1)if 'logStreams' in log_streams_response and len(log_streams_response['logStreams']) > 0:log_stream_name = log_streams_response['logStreams'][0]['logStreamName']# Fetch and print the logs from the latest log streamresponse = logs_client.get_log_events(logGroupName=log_group_name,logStreamName=log_stream_name,startFromHead=True # Start from the beginning of the log stream)for event in response['events']:print(event['message'])else:print(f"No log streams found in log group {log_group_name}")
You should see S3 object created: educative_object
in the logs, which indicates that our trigger is working as required. So, just like that, we can implement Lambda triggers to invoke Lambda functions using other AWS services.
AWS Lambda triggers provide a powerful mechanism for automating processes by executing code in response to events from various AWS services. By configuring Lambda functions with appropriate triggers, such as those from S3 bucket operations, we can create efficient and automated workflows. This implementation shows the effectiveness of AWS Lambda in streamlining and automating tasks within the AWS environment.
Free Resources