はじめに
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.md
Scikit-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 --guided
Lambda実行
sam cliで作成しているため local invoke で実行できます。
$sam local invoke HelloWorldFunction --docker-network <テスト用のlocalstackネットワークID> --log-file check.log --profile=localstack
いかがでしたでしょうか。sam cliを利用することで簡単にコンテナイメージのLambdaの作成からローカル実行までできました。