
Lambda のコンテナイメージを sam cli で作成&ビルドして実行してみよう
はじめに
Lambda のパッケージとしてコンテナイメージがサポートされました。AWSドキュメントを参照すると、プロジェクトのディレクトリ作成からDockerファイル作成などと設定がたくさんあります。大変そうな印象ですよね。
なんとsam cliでも既にコンテナイメージがサポート済みで、簡単にコンテナイメージのプロジェクト作成からビルド、テスト実行までできるようになっています。
今回は、sam cli でコンテナイメージの Lambda を作成し、動作確認してみましょう。Lambda関数は、Python3.8で作ります。
実施環境
・mac OS(10.14.5)
・sam cli(1.24)
・aws cli(2.0.59)
事前準備
sam cliのインストール手順は前回の記事 に記載していますので、こちらを参照ください。
sam cli 「v1.13.1」 以上からコンテナイメージサポートしているので、バージョンが古ければ最新にアップデートしましょう。
$ brew upgrade aws-sam-cli $ sam --version SAM CLI, version 1.24.
コンテナイメージのプロジェクト作成
sam initでプロジェクト作成します。
パッケージタイプに「image」が追加されていますね!
順番に「2: image」、「4: amazon/python3.8-base」、今回動作確認用なので「1: Hello World Lambda Image Example」を選択します。
$ sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 2
Which base image would you like to use?
1 - amazon/nodejs14.x-base
2 - amazon/nodejs12.x-base
3 - amazon/nodejs10.x-base
4 - amazon/python3.8-base
5 - amazon/python3.7-base
6 - amazon/python3.6-base
7 - amazon/python2.7-base
8 - amazon/ruby2.7-base
9 - amazon/ruby2.5-base
10 - amazon/go1.x-base
11 - amazon/java11-base
12 - amazon/java8.al2-base
13 - amazon/java8-base
14 - amazon/dotnet5.0-base
15 - amazon/dotnetcore3.1-base
16 - amazon/dotnetcore2.1-base
Base image: 4
Project name [sam-app]: my_functions
Cloning from https://github.com/aws/aws-sam-cli-app-templates
AWS quick start application templates:
1 - Hello World Lambda Image Example
2 - PyTorch Machine Learning Inference API
3 - Scikit-learn Machine Learning Inference API
4 - Tensorflow Machine Learning Inference API
5 - XGBoost Machine Learning Inference API
Template selection: 1
-----------------------
Generating application:
-----------------------
Name: my_functions
Base Image: amazon/python3.8-base
Dependency Manager: pip
Output Directory: .
Next steps can be found in the README file at ./my_functions/README.mdScikit-learnやTensorflowなど機械学習のテンプレートが既にあるんですね!
sam init を実行すると、カレントディレクトリにプロジェクトが作成されます。
hello_world配下にDockerfileができています。
ls -l hello_world total 24 -rw-r--r--@ 1 xxx staff 242 6 12 20:10 Dockerfile -rw-r--r-- 1 xxx staff 0 6 12 20:10 __init__.py -rw-r--r--@ 1 xxx staff 1826 5 16 00:57 app.py -rw-r--r--@ 1 xxx staff 14 6 12 20:19 requirements.txt
Dockerfileも自動生成してくれるのはありがたいですね。
中身は下記のようになっています。
FROM :python 3.8イメージ(ECRになっていますね)
COPY:Lambda関数ファイル app.py、requirements.txtをイメージへコピー
CMD:Lambdaハンドラー
FROM public.ecr.aws/lambda/python:3.8 COPY app.py requirements.txt ./ RUN python3.8 -m pip install -r requirements.txt -t . # Command can be overwritten by providing a different command in the template directly. CMD ["app.lambda_handler"]
Lambda関数作成
前回の記事 で作成したLambda関数を流用しました。
- template.yaml
中身を見ると PacakeType が「image」、Metadataの箇所も「Dockerfile」になっていますね。
template.yaml に HelloWorldFunction>Properties>Environment に環境変数を追加します。設定内容は前回の記事と同様です。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
python3.8
Sample SAM Template for my_functions
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
PackageType: Image
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Environment:
Variables:
S3_BUCKET: 'test-bucket'
S3_PATH: '/sample_data/test.csv'
SECRET_KEY: 'test_key'
TZ: 'Asia/Tokyo'
Metadata:
Dockerfile: Dockerfile
DockerContext: ./hello_world
DockerTag: python3.8-v1
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
- requirements.txt
- テスト用データ
前回の記事と同様です。
ビルド
sam buildを実行すると、docker buildも実行されます。
実行ログ見ると、コンテナイメージのビルドされていますね。
$ sam build --use-container
Starting Build inside a container
Building codeuri: /Users/xxx/jupiter_study/image_test/my_functions runtime: None metadata: {'Dockerfile': 'Dockerfile', 'DockerContext': '/Users/xxx/jupiter_study/image_test/my_functions/hello_world', 'DockerTag': 'python3.8-v1'} functions: ['HelloWorldFunction']
Building image for HelloWorldFunction function
Setting DockerBuildArgs: {} for HelloWorldFunction function
Step 1/4 : FROM public.ecr.aws/lambda/python:3.8
---> 7f7dc1f0e633
Step 2/4 : COPY app.py requirements.txt ./
---> 6c2b75a7e429
Step 3/4 : RUN python3.8 -m pip install -r requirements.txt -t .
---> Running in d370e30aea17
Collecting requests
Downloading requests-2.25.1-py2.py3-none-any.whl (61 kB)
Collecting boto3
Downloading boto3-1.17.93-py2.py3-none-any.whl (131 kB)
Collecting certifi>=2017.4.17
Downloading certifi-2021.5.30-py2.py3-none-any.whl (145 kB)
Collecting urllib3<1.27,>=1.21.1
Downloading urllib3-1.26.5-py2.py3-none-any.whl (138 kB)
Collecting chardet<5,>=3.0.2
Downloading chardet-4.0.0-py2.py3-none-any.whl (178 kB)
Collecting idna<3,>=2.5
Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
Collecting botocore<1.21.0,>=1.20.93
Downloading botocore-1.20.93-py2.py3-none-any.whl (7.6 MB)
Collecting jmespath<1.0.0,>=0.7.1
Downloading jmespath-0.10.0-py2.py3-none-any.whl (24 kB)
Collecting s3transfer<0.5.0,>=0.4.0
Downloading s3transfer-0.4.2-py2.py3-none-any.whl (79 kB)
Collecting python-dateutil<3.0.0,>=2.1
Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting six>=1.5
Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, urllib3, python-dateutil, jmespath, botocore, s3transfer, idna, chardet, certifi, requests, boto3
Successfully installed boto3-1.17.93 botocore-1.20.93 certifi-2021.5.30 chardet-4.0.0 idna-2.10 jmespath-0.10.0 python-dateutil-2.8.1 requests-2.25.1 s3transfer-0.4.2 six-1.16.0 urllib3-1.26.5
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.1.1; however, version 21.1.2 is available.
You should consider upgrading via the '/var/lang/bin/python3.8 -m pip install --upgrade pip' command.
---> 0e06e91917d7
Step 4/4 : CMD ["app.lambda_handler"]
---> Running in ee34c9f68eda
---> 2f2ef4fffc19
Successfully built 2f2ef4fffc19
Successfully tagged helloworldfunction:python3.8-v1
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guidedLambda実行
sam cliで作成しているため local invoke で実行できます。
$sam local invoke HelloWorldFunction --docker-network <テスト用のlocalstackネットワークID> --log-file check.log --profile=localstack
いかがでしたでしょうか。sam cliを利用することで簡単にコンテナイメージのLambdaの作成からローカル実行までできました。