SAMでLambdaのアプリケーションを作成する


AWS SAM CLI でLambdaアプリケーションを作成したのでメモを残します。


環境

SAMは前提として、Docker、AWS CLIが必要です。

$ docker --version
Docker version 20.10.5, build 55c4c88
$ aws --version
aws-cli/2.1.34 Python/3.8.8 Linux/5.4.0-52-generic exe/x86_64.ubuntu.20 prompt/off
$ sam --version
SAM CLI, version 1.21.1

アプリケーションの作成

sam initでアプリケーションを作成します。 imageを選択する場合は、デプロイ時にECRにリポジトリを作成しておく必要があります。

$ 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]: sample-app

Cloning app templates 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: sample-app
    Base Image: amazon/python3.8-base
    Dependency Manager: pip
    Output Directory: .

    Next steps can be found in the README file at ./sample-app/README.md
$
$ tree .
.
└── sample-app
    ├── README.md
    ├── __init__.py
    ├── events
    │   └── event.json
    ├── hello_world
    │   ├── Dockerfile
    │   ├── __init__.py
    │   ├── app.py
    │   └── requirements.txt
    ├── template.yaml
    └── tests
        ├── __init__.py
        └── unit
            ├── __init__.py
            └── test_handler.py

5 directories, 11 files
$

hello_world/app.pyの内容はこんな内容です。

import json

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps(
            {
                "message": "hello world",
            }
        ),
    }

ビルド

sam buildでアプリケーションをビルドします。

$ cd sample-app/
sample-app$ sam build
Building codeuri: /home/ryosh/tmp/sample-app runtime: None metadata: {'Dockerfile': 'Dockerfile', 'DockerContext': '/home/ryosh/tmp/sample-app/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
 ---> 8947af745e23
Step 2/4 : COPY app.py requirements.txt ./
 ---> Using cache
 ---> d9f36219dbdb
Step 3/4 : RUN python3.8 -m pip install -r requirements.txt -t .
 ---> Using cache
 ---> 4c6308880eff
Step 4/4 : CMD ["app.lambda_handler"]
 ---> Using cache
 ---> XXXX
Successfully built XXXX
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

$

AWSへのデプロイ

sam deploy --guidedでアプリケーションをデプロイします。
初回のデプロイは設定ファイルsamconfig.tomlがないため、オプション--guidedで対話形式でデプロイします。
2回目以降は、sam deployでデプロイできます。

$ sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Not found

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: sample-app
        AWS Region [ap-northeast-1]:
        Image Repository for HelloWorldFunction: XXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world
          helloworldfunction:python3.8-v1 to be pushed to XXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world:helloworldfunction-XXXX-python3.8-v1

        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: y
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: Y
        HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: Y
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

        Looking for resources needed for deployment: Found!

                Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-XXXX
                A different default S3 bucket can be set in samconfig.toml

        Saved arguments to config file
        Running 'sam deploy' for future deployments will use the parameters saved above.
        The above parameters can be changed by modifying samconfig.toml
        Learn more about samconfig.toml syntax at
        https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

The push refers to repository [XXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world]
0c67873405d3: Pushed
fd9b1cf90daf: Pushed
9edbcf394a04: Layer already exists
406666406289: Pushed
d6fa53d6caa6: Layer already exists
94573decf7db: Layer already exists
fafc052823c1: Pushed
c6507cec3c87: Layer already exists
helloworldfunction-XXXX-python3.8-v1: digest: sha256:eda15f8fca8821ae22562364f6d312eb8f7f3837a7205ec63981b486ef239240 size: 1999


        Deploying with following values
        ===============================
        Stack name                   : sample-app
        Region                       : ap-northeast-1
        Confirm changeset            : True
        Deployment image repository  :
                                       {
                                           "HelloWorldFunction": "XXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world"
                                       }
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-XXXX
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}

Initiating deployment
=====================
HelloWorldFunction may not have authorization defined.
Uploading to sample-app/2c9eb9404cc575576a9fb3b0652ea193.template  1170 / 1170  (100.00%)

Waiting for changeset to be created..

CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------
Operation                             LogicalResourceId                     ResourceType                          Replacement
-----------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                 HelloWorldFunctionHelloWorldPermiss   AWS::Lambda::Permission               N/A
                                      ionProd
+ Add                                 HelloWorldFunctionRole                AWS::IAM::Role                        N/A
+ Add                                 HelloWorldFunction                    AWS::Lambda::Function                 N/A
+ Add                                 ServerlessRestApiDeployment47fc2d5f   AWS::ApiGateway::Deployment           N/A
                                      9d
+ Add                                 ServerlessRestApiProdStage            AWS::ApiGateway::Stage                N/A
+ Add                                 ServerlessRestApi                     AWS::ApiGateway::RestApi              N/A
-----------------------------------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:XXXX:changeSet/samcli-deploy1618403206/8a2eacf7-5e27-4e6c-ab91-41c4e5e6187e


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2021-04-14 21:27:03 - Waiting for stack create/update to complete

CloudFormation events from changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                        ResourceType                          LogicalResourceId                     ResourceStatusReason
-----------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                    AWS::IAM::Role                        HelloWorldFunctionRole                -
CREATE_IN_PROGRESS                    AWS::IAM::Role                        HelloWorldFunctionRole                Resource creation Initiated
CREATE_COMPLETE                       AWS::IAM::Role                        HelloWorldFunctionRole                -
CREATE_IN_PROGRESS                    AWS::Lambda::Function                 HelloWorldFunction                    -
CREATE_IN_PROGRESS                    AWS::Lambda::Function                 HelloWorldFunction                    Resource creation Initiated
CREATE_COMPLETE                       AWS::Lambda::Function                 HelloWorldFunction                    -
CREATE_IN_PROGRESS                    AWS::ApiGateway::RestApi              ServerlessRestApi                     -
CREATE_IN_PROGRESS                    AWS::ApiGateway::RestApi              ServerlessRestApi                     Resource creation Initiated
CREATE_COMPLETE                       AWS::ApiGateway::RestApi              ServerlessRestApi                     -
CREATE_IN_PROGRESS                    AWS::Lambda::Permission               HelloWorldFunctionHelloWorldPermiss   Resource creation Initiated
                                                                            ionProd
CREATE_IN_PROGRESS                    AWS::ApiGateway::Deployment           ServerlessRestApiDeployment47fc2d5f   -
                                                                            9d
CREATE_IN_PROGRESS                    AWS::Lambda::Permission               HelloWorldFunctionHelloWorldPermiss   -
                                                                            ionProd
CREATE_IN_PROGRESS                    AWS::ApiGateway::Deployment           ServerlessRestApiDeployment47fc2d5f   Resource creation Initiated
                                                                            9d
CREATE_COMPLETE                       AWS::ApiGateway::Deployment           ServerlessRestApiDeployment47fc2d5f   -
                                                                            9d
CREATE_IN_PROGRESS                    AWS::ApiGateway::Stage                ServerlessRestApiProdStage            -
CREATE_IN_PROGRESS                    AWS::ApiGateway::Stage                ServerlessRestApiProdStage            Resource creation Initiated
CREATE_COMPLETE                       AWS::ApiGateway::Stage                ServerlessRestApiProdStage            -
CREATE_COMPLETE                       AWS::Lambda::Permission               HelloWorldFunctionHelloWorldPermiss   -
                                                                            ionProd
CREATE_COMPLETE                       AWS::CloudFormation::Stack            sample-app                            -
-----------------------------------------------------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
-------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
-------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::XXXX:role/sample-app-HelloWorldFunctionRole-XXXX

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://XXXX.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:XXXX:function:sample-app-HelloWorldFunction-XXXX
-------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sample-app in ap-northeast-1

$
  • 作成されたsamconfig.toml
$ cat samconfig.toml
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sample-app"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-XXXX"
s3_prefix = "sample-app"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = ["HelloWorldFunction=XXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world"]

アプリケーションの削除

下記のコマンドでデプロイしたアプリケーションを削除できます。
ただし、ECRに登録したコンテナイメージは削除されません。

aws cloudformation delete-stack --stack-name sample-app

AWS  Lambda  SAM  Python 

See also