Skip to content

Instantly share code, notes, and snippets.

@votaguz
Created January 1, 2018 23:23
Show Gist options
  • Save votaguz/c55a7ef5f6540e0fc233fe66e877516f to your computer and use it in GitHub Desktop.
Save votaguz/c55a7ef5f6540e0fc233fe66e877516f to your computer and use it in GitHub Desktop.
Script to clone lambda functions in AWS
import argparse
import os
import random
import string
import boto3
LAMBDA_CONFIG_TEMPLATE = ["TracingConfig", "FunctionName", "VpcConfig", "MemorySize", "Environment", "Handler", "Role", "Timeout", "Runtime", "Description"]
def clone_lambda(aws_client, name, code_zipfile_path):
"""
This function clones a lambda in your AWS stack
"""
absolute_file_path = os.path.abspath(code_zipfile_path)
random_suffix = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(12)])
with open(absolute_file_path) as zipfile:
new_lambda_config = {}
print("Getting configuration of {}".format(name))
current_lambda = aws_client.get_function(FunctionName=name)
current_lambda_config = current_lambda.get('Configuration')
print("Creating configuration for new lambda")
for config in current_lambda_config.keys():
if config in LAMBDA_CONFIG_TEMPLATE:
new_lambda_config[config] = current_lambda_config[config]
new_lambda_config.get('VpcConfig').pop('VpcId')
new_lambda_config['Code'] = {}
new_lambda_config['Code']['ZipFile'] = b'{}'.format(zipfile.read())
new_lambda_function_name = "{}-{}".format(current_lambda_config['FunctionName'], random_suffix)
new_lambda_config['FunctionName'] = new_lambda_function_name
print("Creating new lambda function")
aws_client.create_function(**new_lambda_config)
print("{} Created".format(new_lambda_function_name))
if __name__ == "__main__":
argument_parser = argparse.ArgumentParser(description='Clone a lambda function from AWS')
argument_parser.add_argument('name', type=str, help='Name of function to be cloned')
argument_parser.add_argument('code_zipfile_path', type=str, help='Code zipfile path')
args = argument_parser.parse_args()
aws_client = boto3.client('lambda')
clone_lambda(aws_client, args.name, args.code_zipfile_path)
@gubatron
Copy link

gubatron commented Jan 1, 2018

you assume everything is going to work.
You need to add some error handling when things like these fail:

aws_client hasn't been initialized (e.g. network error)

when this fails:
current_lambda = aws_client.get_function(FunctionName=name)

when this fails:
current_lambda_config = current_lambda.get('Configuration')

You assume this will always work, what if these keys no longer work in the future?
new_lambda_config.get('VpcConfig').pop('VpcId')

I'd probably factor this out (into a copy_lambda_config(source, target) method, to shorten the logic of the main method

print("Creating configuration for new lambda")
for config in current_lambda_config.keys():    
    if config in LAMBDA_CONFIG_TEMPLATE:    
       new_lambda_config[config] = current_lambda_config[config]

@gubatron
Copy link

gubatron commented Jan 2, 2018

Then this would look like this:

with open(absolute_file_path) as zipfile:
        new_lambda_config = {}
        print("Getting configuration of {}".format(name))
        current_lambda = aws_client.get_function(FunctionName=name)
        copy_lambda_config(current_lambda.get('Configuration'), new_lambda_config)
        ...

@gubatron
Copy link

gubatron commented Jan 2, 2018

things can go wrong here too:
new_lambda_config['Code']['ZipFile'] = b'{}'.format(zipfile.read())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment