How to make aws lambda function copy same with another one
There is no provided function to copy/clone Lambda Functions and API Gateway configurations. You will need to create new a new function from scratch.
If you envision having to duplicate functions in the future, it may be worthwhile to use AWS CloudFormation to create your Lambda Functions. You can then easily deploy more in future.
When editing a lambda function, you can go Actions > Export Function > Download deployment package.
This downloads a .zip file of the function.
Then create a new Lambda, and go Actions (right above the code editor, different to the first actions button) > Upload a .zip file
This duplicates the code and npm modules etc... Not the triggers or permissions of the function though.
Use a Lambda function to duplicate other functions
Unfortunately neither the AWS web console nor the command line tools have a feature to duplicate a function in the service.
This is a glaring oversight that makes it difficult to do seemingly simple things, like create new functions from a "template" function or rename a function (which is also not possible directly) by creating a copy with a different name.
The easiest way I have found to do this job is to create a Lambda function that duplicates other functions.
The do_duplicate_function.py
Python 3 function
code below can be deployed to Lambda, or be run locally, to duplicate a function in
your AWS account.
To use it, configure a test event in the AWS console or otherwise invoke the function with event data containing at least:
{
"SourceFunctionName": "function_name_to_copy",
"FunctionName": "function_name_to_create"
}
Where SourceFunctionName
is the name of a function to be duplicated, and
FunctionName
is the name of the function to create.
There is more documentation at the top of the function code itself about how to use it and deploy it, see the code for details.
Note: I have written this up separately in this mini-post where you can also get the do_duplicate_function.py function code file. Check there for the latest version. I have put everything here as well so this answer would be complete and self-contained.
"""
This is a Python 3 utility function that creates a duplicate copy of another
function in this AWS account with the same configuration settings, environment
variables, etc.
In short, this does the job that should be handled by a "Duplicate" feature
that is missing from the AWS console and CLI.
Usage in AWS
------------
To use this function, configure a test event in the AWS console or otherwise
invoke the function with event data containing at least:
{
"SourceFunctionName": "function_name_to_copy",
"FunctionName": "function_name_to_create"
}
Where `SourceFunctionName` is the name of a function to be duplicated, and
`FunctionName` is the name of the function to create.
You can override configuration settings of the new function copy by including
extra optional variables in the event data like `Description`, `Timeout`,
`MemorySize`, etc to have your provided values override the values of the
source function's configuration.
See the parameters for the boto3 `create_function()` method for details:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda.html#Lambda.Client.create_function
Usage locally
-------------
You can run this function locally without needing to deploy it to AWS Lambda at
all provided you meet these requirements:
- run it within a python3 virtualenv with `boto3` installed
- set up an AWS profile and credentials as for the AWS CLI tool, with
sufficient permissions to do the work.
Once you have these in place, run the function like this:
AWS_PROFILE=your-aws-profile \
python3 do_duplicate_function.py \
'{"SourceFunctionName": "fn_to_copy", "FunctionName": "fn_to_create"}'
Deployment to AWS
-----------------
Deploy this function with the Python 3.8 runtime (it might work on earlier
versions of Python 3 but hasn't been tested).
This function must have sufficient permissions to fetch and create Lambda
functions and to pass copy roles to the new function. To permit this, apply
something like the following permissions policy document to the deployed
function:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:CreateFunction",
"lambda:ListFunctions",
"lambda:GetFunction",
"iam:GetRole",
"iam:PassRole"
],
"Resource": "*"
}
]
}
Author: James Murty (https://github.com/jmurty) License: MIT
"""
import os
import json
import sys
import boto3
import urllib3
def lambda_handler(event, context):
# Optional envvar, only used to run functions locally
aws_profile = os.environ.get("AWS_PROFILE")
if aws_profile:
session = boto3.Session(profile_name=aws_profile)
lambda_client = session.client("lambda")
else:
lambda_client = boto3.client("lambda")
# Fetch source function metadata
function_data = lambda_client.get_function(
FunctionName=event.pop("SourceFunctionName"),
Qualifier=event.pop("SourceFunctionVersion", "$LATEST"),
)
function_data.pop("ResponseMetadata")
# Download function code from temporary URL
code_url = function_data.pop("Code")["Location"]
http = urllib3.PoolManager()
response = http.request("GET", code_url)
if not 200 <= response.status < 300:
raise Exception(f"Failed to download function code: {response}")
function_code = response.data
# Build metadata for new function based on original function's
new_function_data = {
n: v
for n, v in function_data["Configuration"].items()
if n in (
"Runtime",
"Role",
"Handler",
"Description",
"Timeout",
"MemorySize",
"Publish",
"Environment",
)
}
# Override function metadata values with those provided in event
new_function_data.update(event)
# Provide function code zip data
new_function_data["Code"] = {"ZipFile": function_code}
# Create a new function
return lambda_client.create_function(**new_function_data)
# Support running this function locally
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <EVENT_JSON_TEXT_OR_FILE>")
sys.exit(1)
# Parse event data from JSON file path, or literal JSON
try:
with open(sys.argv[1], "rt") as f:
event = json.load(f)
except Exception:
event = json.loads(sys.argv[1])
context = None
print(lambda_handler(event, context))