У меня есть сценарий AWS CodeBuild, который создает слой Lambda с двумя сторонними (чистыми) пакетами Python, markdown
и yaml
-
version: 0.2
phases:
install:
runtime-versions:
python: $PYTHON_VERSION
commands:
- echo "installing pip packages"
- apt-get update
- apt-get install zip python3-pip -y
- mkdir -p site-packages
- pip3 install --upgrade --target site-packages markdown
- pip3 install --upgrade --target site-packages pyyaml
build:
commands:
- echo "building layer deployable"
- mkdir -p build/python
- cd build && cp -r ../site-packages/markdown python/markdown && cd ..
- cd build && cp -r ../site-packages/yaml python/yaml && cd ..
artifacts:
files:
- '**/*'
base-directory: build
name: layer.zip
Затем у меня есть Cloudformation шаблон для развертывания этого, а затем отдельно тестировать каждый импорт пакета -
---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
AppName:
Type: String
S3DeployBucket:
Type: String
S3LayerKey:
Type: String
LambdaRuntime:
Type: String
Default: python3.7
LambdaMemory:
Type: Number
Default: 512
LambdaTimeout:
Type: Number
Default: 30
LambdaHandler:
Type: String
Default: index.handler
Outputs:
MarkdownLambdaARN:
Value: !GetAtt MarkdownLambda.Arn
YamlLambdaARN:
Value: !GetAtt YamlLambda.Arn
Resources:
MarkdownLambda:
Properties:
Code:
ZipFile: |
import markdown
def handler(event, context):
return "Hello World markdown!"
FunctionName: !Sub "${AppName}-markdown-lambda"
Handler: !Ref LambdaHandler
Layers:
- Ref: LambdaLayer
MemorySize: !Ref LambdaMemory
Role: !GetAtt LambdaRole.Arn
Runtime: !Ref LambdaRuntime
Timeout: !Ref LambdaTimeout
Type: AWS::Lambda::Function
YamlLambda:
Properties:
Code:
ZipFile: |
import yaml
def handler(event, context):
return "Hello World yaml!"
FunctionName: !Sub "${AppName}-yaml-lambda"
Handler: !Ref LambdaHandler
Layers:
- Ref: LambdaLayer
MemorySize: !Ref LambdaMemory
Role: !GetAtt LambdaRole.Arn
Runtime: !Ref LambdaRuntime
Timeout: !Ref LambdaTimeout
Type: AWS::Lambda::Function
LambdaRole:
Properties:
Policies:
- PolicyDocument:
Statement:
- Action: logs:*
Effect: Allow
Resource: '*'
Version: 2012-10-17
PolicyName: !Sub "${AppName}-lambda-role"
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: 2012-10-17
Type: AWS::IAM::Role
LambdaLayer:
Properties:
CompatibleRuntimes:
- Ref: LambdaRuntime
Content:
S3Bucket: !Ref S3DeployBucket
S3Key: !Ref S3LayerKey
LayerName: !Sub "${AppName}-layer"
Type: AWS::Lambda::LayerVersion
Обратите внимание, в частности, на две встроенные лямбда-функции.
Когда я пингую лямбда-выражение YAML, я get -
justin@justin-XPS-13-9360:~/work$ python ping_lambda.py arn:aws:lambda:eu-west-1:119552584133:function:markdown-layer-demo-yaml-lambda
b'"Hello World yaml!"'
Однако, когда я проверяю Markdown Lambda, я получаю -
justin@justin-XPS-13-9360:~/work$ python ping_lambda.py arn:aws:lambda:eu-west-1:119552584133:function:markdown-layer-demo-markdown-lambda
b'{"errorMessage": "Unable to import module \'index\': No module named \'importlib_metadata\'", "errorType": "Runtime.ImportModuleError"}'
Таким образом, кажется, что слой строится нормально, поскольку YAML Lambda работает. Обработка пакетов pyyaml
и markdown
во фрагменте кода CodeBuild аналогична. Пакет markdown
выглядит чистым Python и, похоже, не требует для работы каких-либо дополнительных зависимостей.
Итак, что это за структура пакета markdown
, вызывающая импорт в Lambda выйти из строя, когда yaml
работает нормально?
TIA.