Home > OS >  How do I tell my lambda to look for a specific filepath/key in S3?
How do I tell my lambda to look for a specific filepath/key in S3?

Time:10-27

I'm creating a Lambda that that will be triggered on a schedule. It's purpose is to copy files from a WebDAV server to an S3 bucket utilizing the webdavclient3 Python library.

From the webdavclient3 library I am using the following example:

from webdav3.client import Client
    options = {
     'webdav_hostname': "https://webdav.server.ru",
     'webdav_login':    "w_login",
     'webdav_password': "w_password",
     'cert_path':       "/etc/ssl/certs/certificate.crt",
     'key_path':        "/etc/ssl/private/certificate.key"
    }

client = Client(options)

My current issues stems from properly populating the cert_path and key_path parameters with a filepath in S3. My Lambda does have the necessary IAM Permissions.

My current implementation looks like this, but this is putting the data into the variable rather than the location of the file.

    certPath = s3.get_object(
    Bucket = "bucketName",
    Key = 'folder/securityStuff.crt'
    )
certPathFile = certPath["Body"].read()

The error I get shows that I'm passing the contents rather than the key:

"errorMessage": "Could not find the TLS certificate file, invalid path: b'-----BEGIN CERTIFICAT..etc...

I've also tried using just certPath variable but then I get a TypeError since the item is an object and not a string.

I feel like I am missing something fundamental, and any help would be greatly appreciated.

CodePudding user response:

webdavclient3 expects the certificate and key to be local files. So instead of reading the objects from S3 into variables or pointing to an S3 URL, you"d have to copy the object from S3 to the local file system of the AWS Lambda function. You could do that like that:

import boto3
from webdav3.client import Client


s3 = boto3.client("s3")

s3.download_file(
    Bucket="bucketName",
    Key="folder/certificate.crt"
    Filename="/tmp/certificate.crt"
)
s3.download_file(
    Bucket="bucketName",
    Key="folder/certificate.key"
    Filename="/tmp/certificate.key"
)

options = {
    "webdav_hostname": "https://webdav.server.ru",
    "webdav_login": "w_login",
    "webdav_password": "w_password",
    "cert_path": "/tmp/certificate.crt",
    "key_path": "/tmp/certificate.key"
}

client = Client(options)

Data in /tmp is persisted between multiple AWS Lambda executions running in the same container, so you'd only have to copy the files once per AWS Lambda cold start.

If you don't require to store the files in S3, an easier solution could be to package them together with your Python code, avoiding the copy from S3 to the local filesystem as part of the execution of the AWS Lambda function all together.

  • Related