AWS Lambda con capas de Oracle
Capas de Oracle – Recientemente, encontré la necesidad de finalmente usar Lambda en AWS. Estaba buscando consultar una base de datos de Oracle y exportar la tabla de Oracle a un archivo CSV.
Mientras usaba Python, me di cuenta de que el cliente de Oracle no está disponible en Lambda, por lo que necesitaba una forma de agregar bibliotecas y dependencias para ejecutar mi código.
Las capas Lambda le permiten hacer esto. Puede agregar varias capas a su función Lambda. Este artículo documenta cómo crear Oracle Layer para Python en Lambda con las bibliotecas requeridas.
La principal limitación que descubrí al usar capas Lambda es el límite de tamaño de 250 megas para todo su código y bibliotecas. Afortunadamente, estaba justo por debajo de esta limitación, pero hay varias formas de evitar esto si te encuentras con este problema. Una es dividir su código en varios microservicios. La otra es usar EFS y colocar todas sus bibliotecas en el volumen EFS y montar el volumen en su función Lambda.
Construyendo la capa de Oracle
- Opcional, pero preferible, comisione una instancia EC2 para que pueda comenzar desde un entorno limpio.
- Verificar la versión de Python
python3 --version
- Crea tu directorio de proyectos
mkdir project
- Crear un directorio llamado Python
mkdir python
- Crear directorio de biblioteca
mkdir lib
- Instale la biblioteca cx_Oracle Python
pip3 install cx_Oracle -t python/
- Descargue el último cliente de Oracle desde:
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html
wget https://download.oracle.com/otn_software/linux/instantclient/218000/instantclient-basic-linux.x64-21.8.0.0.0dbru.zip -O oracli.zip
- Descomprima Oracle Client en la carpeta de la biblioteca
unzip -j oracli.zip -d lib/
- Asegúrese de que Libaio esté instalado en la instancia EC2 (debería estarlo)
sudo yum install libaio -y
- Copiar Libaio a la biblioteca
cp /lib64/libaio.so.1 lib/libaio.so.1
- Comprima todas sus bibliotecas para usarlas en la capa Lambda
zip -y -r oracletable.zip python/ lib/
- Copie su archivo de biblioteca comprimido en un depósito S3 para que la función Lambda pueda acceder a él.
Agregar capa en Lambda
- Copie la URL que se usará al crear la capa.
- Vaya a lambda y cree una capa utilizando la documentación de AWS Lambda Layer.
- https://docs.aws.amazon.com/es_es/lambda/latest/dg/configuration-layers.html
- Cree la función de Lambda utilizando la documentación de AWS Lambda.
- https://docs.aws.amazon.com/es_es/lambda/latest/dg/getting-started.html
- Agrega tu código
- Agrega la capa que creaste
- Ejecute la función Lambda
Uso de formaciones en la nube
A continuación se muestra un ejemplo del código de CloudFormation para crear una capa Lambda y una función Lambda.
Nota: la documentación de Amazon Python Power Tools Layer se encuentra en:
- https://awslabs.github.io/aws-lambda-powertools-python/2.6.0/
Role:
Type: 'AWS::IAM::Role'
Properties:
RoleName: lambda-role-name
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- s3.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: lambda-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
# Add access to secrets manager to give access to Lambda function to use
- Effect: Allow
Action:
- secretsmanager:GetResourcePolicy
- secretsmanager:GetSecretValue
Resource: 'arn:aws:secretsmanager:<region>:<account>:secret:<secretname>'
- Effect: "Allow"
Action:
- s3:ListBucket
Resource:
- !Sub 'arn:aws:s3:::<S3 Bucket>'
- Effect: "Allow"
Action:
- s3:GetObject
- s3:PutObject
- s3:PutObjectAcl
Resource:
- !Sub 'arn:aws:s3:::<S3 Bucket>/*'
- !Sub 'arn:aws:s3:::<S3 Bucket>/*'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole'
# Create the Oracle Layer for Python
OrcaleLayer:
Type: AWS::Lambda::LayerVersion
Properties:
CompatibleRuntimes:
- python3.7
Content:
S3Bucket: <S3 Lambda Bucket with code>
S3Key: <layer ip file>
Description: "Oracle Layer"
LayerName: oracle-layer
# Create Lambda Function
OracleFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: oracle-lambda
Handler: oraclelambda.lambda_handler
Layers:
# Oracle Client Library Layer
- !Ref OracleLayer
# Add Python Power Tools
- 'arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:13'
Role:
Fn::GetAtt:
- Role
- Arn
Environment:
#Pass Secret Name, Target Bucket, and S3 Prefix to the Python code
Variables:
SecretName: <secret name>
TargetBucket: <target bucket>
S3Prefix: <target prefix>
# Location of the Python Code
Code:
S3Bucket: <S3 Lambda Bucket with code>
S3Key: <pthon code zip file>
Runtime: python3.7
Timeout: 90
TracingConfig:
Mode: Active
VpcConfig:
SecurityGroupIds: <security group id>
- !Ref SecurityGroupId
SubnetIds:
- <subnet 1>
- <subnet 2>
¿Que sigue?
Actualmente, el proceso de actualización de las capas y el código es muy manual. Estoy buscando formas de automatizar la actualización de las plantillas de CloudFormation y Lambda cuando se realizan nuevos cambios.
Gracias por llegar hasta aquí, si encuentras esto útil no olvides dejar un👍🏼y suscribirse para recibir más contenido.
Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre Node.js y AWS Lambda: