How to Deploy Lambda Functions

How to Deploy Lambda Functions Amazon Web Services (AWS) Lambda is a serverless compute service that lets you run code without provisioning or managing servers. It automatically scales your application in response to incoming traffic and charges only for the compute time consumed. Deploying Lambda functions is a foundational skill for modern cloud developers, DevOps engineers, and infrastructure a

Oct 30, 2025 - 12:15
Oct 30, 2025 - 12:15
 1

How to Deploy Lambda Functions

Amazon Web Services (AWS) Lambda is a serverless compute service that lets you run code without provisioning or managing servers. It automatically scales your application in response to incoming traffic and charges only for the compute time consumed. Deploying Lambda functions is a foundational skill for modern cloud developers, DevOps engineers, and infrastructure architects aiming to build scalable, cost-efficient, and highly available applications.

Deploying Lambda functions is not merely about uploading codeit involves configuring triggers, managing permissions, setting environment variables, integrating with monitoring tools, and ensuring security compliance. Whether you're building a REST API, processing real-time data streams, automating infrastructure tasks, or handling file uploads, understanding how to deploy Lambda functions correctly is critical to success in cloud-native development.

This comprehensive guide walks you through every step of deploying Lambda functionsfrom initial setup to production-grade deploymentwith best practices, real-world examples, and essential tools. By the end, youll have a complete, repeatable process for deploying Lambda functions reliably and securely across development, staging, and production environments.

Step-by-Step Guide

Prerequisites

Before deploying your first Lambda function, ensure you have the following:

  • An AWS account with appropriate permissions (preferably with IAM roles configured)
  • AWS CLI installed and configured on your local machine
  • Node.js, Python, or another supported runtime installed (depending on your functions language)
  • A code editor (e.g., VS Code, Sublime Text, or JetBrains IDEs)
  • Basic understanding of JSON, YAML, and command-line interfaces

For enterprise environments, ensure you have access to AWS Organizations, IAM policies, and AWS CloudFormation or Terraform for infrastructure-as-code workflows.

Step 1: Write Your Lambda Function Code

Start by creating the core logic of your function. Lambda supports multiple runtimes, including Node.js, Python, Java, C

, Go, and Ruby. For this guide, well use Python 3.12 as its widely adopted and easy to read.

Create a new directory for your project:

mkdir my-lambda-function

cd my-lambda-function

Create a file named lambda_function.py:

def lambda_handler(event, context):

Log the incoming event

print("Received event: " + str(event))

Process the event

message = event.get('message', 'No message provided')

response = {

'statusCode': 200,

'headers': {

'Content-Type': 'application/json'

},

'body': {

'message': f'Hello, you said: {message}',

'invoked': True

}

}

return response

This function receives an event (typically from an API Gateway, S3, or SQS trigger), logs it, and returns a structured HTTP-like response. The lambda_handler is the entry point required by AWS Lambda.

Step 2: Package Your Function

Lambda requires your code to be packaged as a ZIP file. If your function uses external libraries (e.g., requests, boto3), you must include them in the package.

Install dependencies locally (if any):

pip install requests -t .

This installs the requests library into the current directory. Then, create the ZIP archive:

zip -r my-lambda-function.zip lambda_function.py

If you used external libraries:

zip -r my-lambda-function.zip lambda_function.py requests/

Ensure the ZIP files root contains your handler file and any dependencies. Do not include parent directories or unnecessary files like .git or __pycache__.

Step 3: Create the Lambda Function via AWS Console

Log in to the AWS Lambda Console.

Click Create function and choose Author from scratch.

  • Function name: Enter a descriptive name like my-first-lambda
  • Runtime: Select Python 3.12
  • Architecture: Choose x86_64 (or arm64 if optimizing for cost/performance)

Click Create function.

Once created, scroll down to the Function code section. Under Code source, click Upload from and select .zip file. Upload your my-lambda-function.zip.

In the Handler field, enter: lambda_function.lambda_handler

Click Save.

Step 4: Test Your Function

On the same page, click Test to create a test event.

Choose Configure test events ? Create new event.

Name it TestEvent and use the following JSON:

{

"message": "This is a test message"

}

Click Create. Then click Test again.

If configured correctly, youll see a success response with the status code 200 and the message you provided. Scroll down to the Execution result section to view logs and output.

Step 5: Set Environment Variables

For configuration that varies between environments (e.g., database URLs, API keys), use environment variables.

In the Lambda console, under Environment variables, click Edit.

Add:

  • Key: STAGE
  • Value: dev

Then update your code to read it:

import os

def lambda_handler(event, context):

stage = os.getenv('STAGE', 'unknown')

print(f"Running in {stage} environment")

message = event.get('message', 'No message provided')

response = {

'statusCode': 200,

'headers': {

'Content-Type': 'application/json'

},

'body': {

'message': f'Hello, you said: {message}',

'environment': stage,

'invoked': True

}

}

return response

Re-package and re-upload the ZIP file, or use the AWS CLI (see Step 7) for automation.

Step 6: Configure Triggers

A Lambda function is useless without a trigger. Common triggers include:

  • API Gateway: For HTTP endpoints
  • S3: For file uploads
  • SQS: For message queues
  • EventBridge: For scheduled or event-driven workflows

To attach an API Gateway trigger:

  1. In the Lambda console, under Designer, click Add trigger.
  2. Select API Gateway.
  3. Choose Create a new API.
  4. Select HTTP API (recommended for new projects) or REST API.
  5. Choose Open for security (for testing) or Private if behind a VPC.
  6. Click Add.

After saving, youll see an API endpoint URL. Copy it and paste it into your browser or use curl to test:

curl -X POST https://your-api-id.execute-api.region.amazonaws.com/ -d '{"message": "Hello from curl"}'

You should receive a response from your Lambda function.

Step 7: Deploy Using AWS CLI

Manual deployment via the console is fine for testing, but for production, use automation. The AWS CLI enables scripted, repeatable deployments.

First, ensure the AWS CLI is configured:

aws configure

Enter your AWS Access Key ID, Secret Access Key, region (e.g., us-east-1), and output format (json).

Then, create a ZIP file as before and upload it:

aws lambda update-function-code \

--function-name my-first-lambda \

--zip-file fileb://my-lambda-function.zip

To update environment variables:

aws lambda update-function-configuration \

--function-name my-first-lambda \

--environment Variables={STAGE=prod}

To create a new function from scratch:

aws lambda create-function \

--function-name my-first-lambda \

--runtime python3.12 \

--role arn:aws:iam::123456789012:role/lambda-execution-role \

--handler lambda_function.lambda_handler \

--zip-file fileb://my-lambda-function.zip \

--environment Variables={STAGE=dev}

Replace the role ARN with the ARN of an IAM role that grants Lambda execution permissions (see Best Practices).

Step 8: Use AWS SAM or Serverless Framework for Advanced Deployments

For complex applications with multiple functions, APIs, and resources, use infrastructure-as-code tools like AWS Serverless Application Model (SAM) or the Serverless Framework.

Install AWS SAM CLI:

pip install aws-sam-cli

Create a template.yaml:

AWSTemplateFormatVersion: '2010-09-09'

Transform: AWS::Serverless-2016-10-31

Resources:

MyLambdaFunction:

Type: AWS::Serverless::Function

Properties:

CodeUri: src/

Handler: lambda_function.lambda_handler

Runtime: python3.12

Environment:

Variables:

STAGE: prod

Events:

Api:

Type: Api

Properties:

Path: /hello

Method: post

Place your lambda_function.py in a src/ folder.

Build and deploy:

sam build

sam deploy --guided

The guided deployment walks you through stack name, region, permissions, and confirms changes before applying them.

Best Practices

Use Infrastructure as Code (IaC)

Never configure Lambda functions manually in the console for production. Use AWS CloudFormation, Terraform, or AWS SAM to define your infrastructure in code. This ensures:

  • Reproducibility across environments
  • Version control and audit trails
  • Rollback capabilities
  • Consistent deployments

Example CloudFormation snippet:

MyLambdaFunction:

Type: AWS::Lambda::Function

Properties:

Code:

S3Bucket: my-deployment-bucket

S3Key: lambda-functions/my-lambda.zip

Handler: lambda_function.lambda_handler

Runtime: python3.12

Role: !GetAtt LambdaExecutionRole.Arn

Environment:

Variables:

STAGE: !Ref Environment

Minimize Deployment Package Size

Larger packages increase cold start times and deployment failures. Only include necessary files.

  • Use .dockerignore-style exclusions: remove __pycache__, .git, logs, tests
  • Use layer dependencies for shared libraries (e.g., boto3, numpy)
  • Consider using AWS Lambda Layers to separate dependencies from code

Set Appropriate Memory and Timeout Values

Lambda allocates CPU power proportionally to memory. Increasing memory also increases CPU, which can reduce execution time.

Use AWS Lambda Power Tuning (an open-source tool) to find the optimal memory configuration for cost and performance.

Set timeout values conservatively:

  • Default: 3 seconds
  • Recommended for most APIs: 1030 seconds
  • For batch jobs: up to 15 minutes (max)

Always set timeouts lower than downstream service limits (e.g., API Gateway timeout is 30 seconds).

Implement Proper IAM Permissions

Follow the principle of least privilege. Create dedicated IAM roles for each Lambda function.

Example minimal policy for a function that reads from S3:

{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": [

"logs:CreateLogGroup",

"logs:CreateLogStream",

"logs:PutLogEvents"

],

"Resource": "arn:aws:logs:*:*:*"

},

{

"Effect": "Allow",

"Action": [

"s3:GetObject"

],

"Resource": "arn:aws:s3:::my-bucket/*"

}

]

}

Avoid using AdministratorAccess or broad policies like s3:* unless absolutely necessary.

Use Environment-Specific Configurations

Never hardcode values like database URLs or API keys. Use environment variables and deploy different configurations per stage (dev, staging, prod).

Use AWS Systems Manager Parameter Store or AWS Secrets Manager for sensitive data:

import os

import boto3

ssm = boto3.client('ssm')

db_password = ssm.get_parameter(Name='/prod/database/password', WithDecryption=True)['Parameter']['Value']

Enable Monitoring and Logging

By default, Lambda logs to Amazon CloudWatch. Ensure your function writes meaningful logs:

  • Log events, errors, and key processing steps
  • Use structured logging (JSON) for easier parsing
  • Set CloudWatch Log Retention to 3090 days (avoid indefinite retention)

Enable AWS X-Ray for distributed tracing:

  • Go to Lambda ? Configuration ? Monitoring and operations ? Enable active tracing
  • Install the X-Ray SDK in your package
  • Wrap your handler with aws_xray_sdk.core.patch_all() (Python)

Manage Concurrency and Reserved Concurrency

By default, Lambda scales automatically. However, for critical functions, set reserved concurrency to:

  • Prevent one function from consuming all available capacity
  • Ensure other functions (e.g., authentication, notifications) remain responsive

Example: Reserve 50 concurrent executions for a payment processing function to guarantee throughput.

Use Versioning and Aliases for Safe Deployments

Always use versions and aliases (e.g., PROD, STAGING) to manage deployments.

After deploying a new code version:

  1. AWS Lambda automatically creates a new version (e.g., $LATEST, 1, 2)
  2. Update an alias (e.g., prod) to point to version 2
  3. Test the alias endpoint before redirecting production traffic

This allows rollback: if version 2 fails, re-point the alias to version 1.

Secure Your Functions

  • Place functions behind a VPC only if necessary (increases cold start time)
  • Use VPC endpoints for S3 and DynamoDB to avoid public internet exposure
  • Enable function URLs with IAM authentication for internal use
  • Validate and sanitize all input events to prevent injection attacks
  • Use AWS WAF with API Gateway to filter malicious requests

Tools and Resources

Core AWS Tools

  • AWS Lambda Console: Web interface for manual testing and configuration
  • AWS CLI: Command-line tool for scripting deployments and automation
  • AWS SAM CLI: Simplifies building, testing, and deploying serverless applications
  • AWS CloudFormation: Declarative infrastructure-as-code for full AWS stack management
  • Amazon CloudWatch: Monitoring, logging, and alerting
  • AWS X-Ray: Distributed tracing for performance analysis
  • AWS CodePipeline / CodeBuild: CI/CD pipelines for automated deployments

Third-Party Tools

  • Serverless Framework: Popular open-source framework for multi-provider serverless apps
  • Terraform: Infrastructure-as-code tool supporting AWS Lambda and many other providers
  • Chalice: AWS-backed Python microframework for Lambda and API Gateway
  • Netlify Functions / Vercel Serverless: Alternatives if using frontend platforms
  • Lambda Power Tuning: Open-source tool to optimize memory and cost
  • Serverless Eye: Security scanning for serverless configurations

Learning Resources

Community and Support

  • Stack Overflow: Use tags aws-lambda and serverless
  • Reddit: r/AWS and r/serverless
  • AWS re:Invent Sessions: Archived videos on Lambda best practices
  • AWS Developer Forums: Official support channel

Real Examples

Example 1: Image Thumbnail Generator

Use Case: Automatically generate thumbnails when users upload images to S3.

Architecture:

  • User uploads image ? S3 bucket
  • S3 triggers Lambda function
  • Function resizes image using Pillow (Python)
  • Uploads thumbnail to another S3 bucket

Code:

import boto3

from PIL import Image

import io

s3 = boto3.client('s3')

def lambda_handler(event, context):

bucket = event['Records'][0]['s3']['bucket']['name']

key = event['Records'][0]['s3']['object']['key']

Download original image

response = s3.get_object(Bucket=bucket, Key=key)

image_data = response['Body'].read()

Resize image

image = Image.open(io.BytesIO(image_data))

image.thumbnail((200, 200))

Upload thumbnail

thumbnail_buffer = io.BytesIO()

image.save(thumbnail_buffer, format='JPEG')

thumbnail_buffer.seek(0)

thumbnail_key = 'thumbnails/' + key

s3.put_object(

Bucket=bucket,

Key=thumbnail_key,

Body=thumbnail_buffer,

ContentType='image/jpeg'

)

return {'statusCode': 200, 'body': f'Thumbnail created: {thumbnail_key}'}

Deployment:

  • Package with Pillow dependency
  • Attach S3 trigger to source bucket
  • Grant Lambda permission to read from source and write to destination

Example 2: REST API for User Registration

Use Case: Create a secure API endpoint for user sign-ups.

Architecture:

  • HTTP POST to API Gateway ? Lambda
  • Lambda validates input ? writes to DynamoDB ? sends welcome email via SES

Code:

import json

import boto3

from datetime import datetime

dynamodb = boto3.resource('dynamodb')

ses = boto3.client('ses')

table = dynamodb.Table('Users')

def lambda_handler(event, context):

body = json.loads(event['body'])

Validate input

if not all(k in body for k in ('email', 'name')):

return {

'statusCode': 400,

'body': json.dumps({'error': 'Missing required fields'})

}

Save to DynamoDB

table.put_item(

Item={

'email': body['email'],

'name': body['name'],

'createdAt': datetime.utcnow().isoformat()

}

)

Send email

ses.send_email(

Source='noreply@company.com',

Destination={'ToAddresses': [body['email']]},

Message={

'Subject': {'Data': 'Welcome!'},

'Body': {'Text': {'Data': f'Hello {body["name"]}, welcome to our service!'}}

}

)

return {

'statusCode': 201,

'headers': {'Content-Type': 'application/json'},

'body': json.dumps({'message': 'User registered successfully'})

}

Deployment:

  • Use SAM or CloudFormation to define API Gateway + Lambda + DynamoDB + SES permissions
  • Enable CORS on API Gateway
  • Set up domain and SSL certificate via ACM

Example 3: Scheduled Data Cleanup

Use Case: Delete old log files from S3 every night.

Architecture:

  • EventBridge rule triggers every day at 2 AM
  • Lambda lists objects in bucket older than 30 days
  • Deletes matching objects

Code:

import boto3

from datetime import datetime, timedelta

s3 = boto3.client('s3')

def lambda_handler(event, context):

bucket = 'my-logs-bucket'

cutoff = datetime.utcnow() - timedelta(days=30)

List objects

response = s3.list_objects_v2(Bucket=bucket)

if 'Contents' not in response:

return {'statusCode': 200, 'body': 'No files to delete'}

to_delete = [

obj['Key'] for obj in response['Contents']

if obj['LastModified']

]

if to_delete:

s3.delete_objects(

Bucket=bucket,

Delete={'Objects': [{'Key': k} for k in to_delete]}

)

return {'statusCode': 200, 'body': f'Deleted {len(to_delete)} files'}

else:

return {'statusCode': 200, 'body': 'No old files found'}

Deployment:

  • Create EventBridge rule with cron expression: cron(0 2 * * ? *)
  • Attach as trigger to Lambda
  • Grant S3:ListBucket and S3:DeleteObject permissions

FAQs

What is the maximum size for a Lambda deployment package?

The uncompressed deployment package size limit is 250 MB. If you exceed this, use AWS Lambda Layers for dependencies or store large files in S3 and download them at runtime.

How do I handle secrets in Lambda functions?

Never store secrets in code or environment variables directly. Use AWS Secrets Manager or Systems Manager Parameter Store with encryption. Lambda can retrieve them securely at runtime using IAM roles.

Why is my Lambda function taking too long to start?

Cold starts occur when Lambda initializes a new execution environment. Reduce them by:

  • Using smaller deployment packages
  • Increasing memory (faster CPU)
  • Using provisioned concurrency for high-traffic functions
  • Choosing runtimes with faster startup (e.g., Python, Node.js over Java)

Can I use Docker with Lambda?

Yes. AWS Lambda now supports container images up to 10 GB. Use docker build and push to ECR, then create a Lambda function from the image. Ideal for complex dependencies or legacy apps.

How do I monitor Lambda function performance?

Use CloudWatch Metrics (invocations, duration, errors) and enable AWS X-Ray for end-to-end tracing. Set up CloudWatch Alarms for error rates above 1% or duration spikes.

Can Lambda functions call other Lambda functions?

Yes, using the AWS SDK (boto3 in Python). However, avoid tight coupling. Prefer event-driven patterns (SNS, EventBridge) for decoupled communication.

What happens if my Lambda function fails?

By default, Lambda retries failed invocations twice (for asynchronous events). For S3 or EventBridge triggers, failed events are sent to a Dead Letter Queue (DLQ) if configured. Always set up a DLQ for critical functions.

How much does Lambda cost?

Lambda charges based on:

  • Number of requests (first 1M free per month)
  • Duration (GB-seconds): memory allocated execution time

Example: A 128 MB function running 500 ms costs $0.000000833 per invocation. Extremely cost-effective for low-to-medium traffic.

Is Lambda suitable for long-running tasks?

Lambda has a 15-minute timeout limit. For tasks longer than that, use AWS Step Functions to orchestrate multiple Lambda functions, or use EC2, ECS, or EKS for long-running processes.

How do I roll back a Lambda deployment?

Use aliases and versions. Point the alias (e.g., prod) to the previous version number. No code changes neededjust update the alias target.

Conclusion

Deploying Lambda functions is more than uploading codeits about architecting reliable, secure, and scalable serverless systems. From writing clean, minimal handlers to automating deployments with CI/CD pipelines, every step contributes to the stability and performance of your application.

This guide provided a complete workflow: from initial code creation and packaging to testing, triggering, securing, and monitoring. Youve learned how to deploy using the console, CLI, SAM, and infrastructure-as-code tools. Real-world examples demonstrated practical use cases across file processing, APIs, and automation.

Remember: serverless doesnt mean no operations. It means operations are abstracted, not eliminated. The best serverless deployments are those that are automated, monitored, and designed with failure in mind.

As you continue building with AWS Lambda, prioritize:

  • Automation over manual configuration
  • Security through least privilege
  • Observability through logging and tracing
  • Cost optimization through memory tuning and cold start reduction

With these principles in place, youre not just deploying functionsyoure building resilient, cloud-native applications that scale effortlessly with your business.