As it is, deploy it including the library such as lbxxx.so, generate a zip with a password on AWS lambda, and store it in the S3 bucket.
The wall stands in front of what I want to do.
I would like to leave here how I got over this wall.
It was developed conveniently using the "Remote-Containers" function of VS Code. Please refer to this article for Remote-Containers.
I don't have to write anything in particular ...
AWS Management Console --Lambda --"Create Function"
"Create from scratch"
Function name "zip-sample"
Runtime "Python 3.8"
Launch VS Code locally and create the following directory structure
zip-sample/
    └ .devcontainer/
        ├ Dockerfile
        └ devcontainer.json
    └ package/
        └  lambda_hundler.py
    └ requirements.txt
For Dockerfile and devcontainer.json, I got it from source code here. lambda_hundler.py is as follows.
lambda_hundler.py
#It is the source code of lambda
import json
def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
Let's get started when we're ready. Why can't the zipfile module generate a password-protected zip file! (Abrupt) After investigating, it seems that ** pyminizip ** can generate a zip file with a password. Let's check it immediately.
pyminizip requires zlib (a free library for compressing and decompressing data), so install it.
$ sudo apt install zlib
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package zlib
** I was angry. ** ** Use "zlib1g" instead.
$ sudo apt install zlib1g
Put the following in requirements.txt and type the pip install command.
requirements.txt
pyminizip==0.2.4
$ cd /workspaces/zip-sample
$ pip install -r requirements.txt -t ./package
Add the following to lambda_hundler.py.
lambda_hundler.py
import json
import os
import pyminizip
def lambda_handler(event, context):
    #We will use the tmp directory in consideration of uploading it to lambda later.
    zip_path = "/tmp/zip/"
    # /tmp/If the zip directory does not exist, create one.
    if not os.path.isdir(zip_path):
        os.mkdir(zip_path)
    KEY = "/tmp/hello.txt"
    with open(KEY, mode='w') as f:
        f.write('this is test.')
    password = "password"
    compression_level = 9 #Compression level 1-9, the larger the compression, the stronger
    #The first argument is an array of file paths to include in the zip file
    #The second argument is the hierarchy in the zip file
    #The third argument is the location and file name of the zip file.
    #The fourth argument is the password
    #The fifth argument is the compression level
    pyminizip.compress_multiple([KEY], ["\\"], "/tmp/zip/sample.zip", password, compression_level)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
#The following is excluded at the time of deployment.
lambda_hundler('a','a')
Let's start it below.
$ python lambda_hundler.py
$ ls /tmp/zip
sample.zip
You've done it safely!
Now that you have successfully generated a password-protected zip file locally (docker container), let's deploy it to lambda.
lambda_hundler ('a','a') in lambda_handler.py and delete it.$ cd /workspaces/zip-sample/package
$ zip -r ../function.zip .
$ aws lambda update-function-code --function-name sample-zip --zip-file fileb://../function.zip
After the deployment is completed, let's execute "test" from the AWS Management Console --lambda --sample-zip.
[ERROR] OSError: error in closing \tmp\zip\sample.zip (-102)
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 78, in lambda_handler
    pyminizip.compress_multiple([KEY], ["\\"], r"\tmp\zip\sample.zip", "password03", 1)
I got scolded
After a lot of research, it seems that this is happening because ** zlib is not included in the deployment package ... **
If you type the following command, it will be included in the deployment package.
$ wget http://www.zlib.net/zlib-1.2.11.tar.gz
$ tar -xvzf zlib-1.2.11.tar.gz
$ cd zlib-1.2.11
$ ./configure --prefix=/workspaces/sample-zip
share lib include/workspaces/sample-zip/Should be able to
$ sudo make install
$ cd /workspaces/sample-zip/
Include share lib include in zip file
$ zip -gr function.zip lambda_function.py share lib include
Deploy
$ aws lambda update-function-code --function-name sample-zip --zip-file fileb://function.zip
As for the linux library, once you do the above, you do not have to change it, so after that you only need to zip the source code.
$ cd /workspaces/zip-sample/package
$ zip -r ../function.zip .
$ aws lambda update-function-code --function-name sample-zip --zip-file fileb://../function.zip
After the deployment is completed, let's execute "test" from the AWS Management Console --lambda --sample-zip. **success! ** (should)
The source code after overcoming the wall is as follows.
lambda_hundler.py
def lambda_handler(event, context):
    zip_path = "/tmp/zip/"
    if not os.path.isdir(zip_path):
        os.mkdir(zip_path)
    KEY = '/tmp/hello.txt'
    with open(KEY, mode='w') as f:
        f.write("this is test.")
    password = "password"
    compression_level = 9 #Compression level 1-9, the larger the compression, the stronger
    pyminizip.compress_multiple([KEY], ["\\"], "/tmp/zip/sample.zip", password, compression_level)
    
    #Upload the created zip file to s3
    s3 = boto3.resource('s3')
    s3.Bucket(BUCKET).upload_file(Filename="/tmp/zip/sample.zip", Key="sample.zip")
    return {
        'status': 200,
        'body': 'Processing is finished'
    }
--If you want to create a password-protected zip file in Python, "pyminizip"! --When deploying to lambda, include "zlib" in the deploy package!
Recommended Posts