I am building a solution to manage the migration of AWS Lambdas from one region/account to another. AWS's Lambda dashboard currently only supports exporting Lambdas one at a time, which will be too slow for me.
I want to use boto3's client.get_function(...)
and client.create_function(...)
to automate this.
Following the docs, I use client.get_function("myFunc")
to get my function's config and code details:
response = client.get_function(FunctionName = "myFunc")
fConfig = response["Configuration"]
fCode = response["Code"]
print(fCode)
>>> 'RepositoryType': 'S3',
'Location': 'https://awslambda-us-east-2-tasks.s3.us-east-2.amazonaws.com/snapshots/1234567890123/myFunc-d6abcd8d-8a83...'
My question is how do I use fCode["Location"]
to download the Lambda's deployment package so that I can later use it when I call client.create_function(...)
?
I have read the boto3 S3 docs, but couldn't find anything that would help me there. Simply following the 'Location' link returns: AccessDenied: No AWSAccessKey was presented.
If someone could please explain how response["Code"]
is meant to be used.
CodePudding user response:
Below is a snippet of code that downloads the Lambda to the tmp dir on the local machine.
import requests
import boto3
import json
lambda_client = boto3.client('lambda')
# Download the lambda
def download_lambda(function_arn):
tmp_dir = '/tmp/'
arn = function_arn
arn_parts = arn.split(':')
func_name = arn_parts[6]
func_details = lambda_client.get_function(FunctionName=function_arn)
zip_file = tmp_dir func_name '.zip'
url = func_details['Code']['Location']
r = requests.get(url)
with open(zip_file, "wb") as code:
code.write(r.content)
CodePudding user response:
According to the documentation the Location
returned by get_function
returns a presigned S3 URL. That means you should be able to just download the zip package by GET
ing this URL.
You can then use the zip as input to create_function
.
I haven't tried with boto but when I use the AWS cli's aws lambda get-function --function-name <A_FUNCTION_NAME>
it works like described. I can open the URL in a browser and am able to download the zip of the function.
For me it seems that the credentials/role used by boto is not allowed to call s3:GetObject on the resource.
Can you try if it works with the aws cli (make sure to use the same role/user as from within boto)!?
CodePudding user response:
As @Korgen pointed out, the get_function
command returns a S3 presigned URL.
I have successfully generated and used a download URL using boto3
in a lambda with the default Basic Execution Role plus the get_function
permission. No further permissions (e.g. no S3 permissions) are required.
The URL can be used by anyone (e.g. you can paste it into the browser). The URL does, however, expire after 10 minutes (X-Amz-Expires=599
header). This is a feature of the presigned URL, that it is public, but short-lived.