AWS SAMでLambdaとAPI Gatewayをデプロイしてみた(Python)


はじめに

今までシンプルにLambdaを触ってきましたが、AWS SAMを使ってみたいと思ったので試しました。
sam initで作られるREADME.mdに従っています。

環境

  • Windows 10
  • Python 3.6

各種インストール

AWS CLI

コマンドでAWSの各種サービス等が使えるようになります。
インストール後、aws configureで認証情報を設定しておきます。

Docker

Dockerをインストールします。インストール済みの場合は次へ!

AWS SAM

$ pip install aws-sam-cli

使ってみる

サンプル作成

$ sam init --runtime python3.6 --name sample
[+] Initializing project structure...
[SUCCESS] - Read sample/README.md for further instructions on how to proceed
[*] Project initialization is now complete

なお、runtime部分を変えると他言語でもできます。(以下sam init --helpより)

 -r, --runtime [python3.6|python2.7|python|nodejs6.10|nodejs8.10|nodejs4.3|nodejs|dotnetcore2.0|dotnetcore1.0|dotnetcore|dotnet|go1.x|go|java8|java]

必要ライブラリのインストール

buildフォルダ以下に必要なファイル等を集めます。

$ pip install -r requirements.txt -t hello_world/build/
$ cp hello_world/*.py hello_world/build/

ローカルテスト

まずはAPIを起動します。

$ sam local start-api

次にエンドポイントにアクセスしましょう。

$ curl http://127.0.0.1:3000/hello
StatusCode        : 200
StatusDescription : OK
Content           : {"message": "hello world", "location": "xxx.xxx.xxx.xxx"}
RawContent        : HTTP/1.0 200 OK
                    Content-Length: 57
                    Content-Type: application/json
                    Date: Sat, 11 Aug 2018 12:29:28 GMT
                    Server: Werkzeug/0.14.1 Python/3.6.3

                    {"message": "hello world", "location": "xxx.xxx.xxx.xx...
Forms             : {}
Headers           : {[Content-Length, 57], [Content-Type, application/json], [Date, Sat, 11 Aug 2018 12:29:28 GMT], [Se
                    rver, Werkzeug/0.14.1 Python/3.6.3]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 57

動きました!!

実行時にdocker.errors.APIError: 500 Server Error: Internal Server Error ("b'Drive has not been shared'")というエラーが出た場合は、下記を参考にDockerの共有設定を行います。

パッケージ化

コード類を格納するS3バケットを作成します。すでにある場合は次へ!

$ aws s3 mb s3://gnk263-lambda-bucket

続いてS3バケットにパッケージ化します。

$ sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket gnk263-lambda-bucket
Uploading to 1729e204b620d03419b6ec4a99b8fac9  1047173 / 1047173.0  (100.00%)
Successfully packaged artifacts and wrote output template to file packaged.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file D:\xxx\yyy\packaged.yaml --stack-name <YOUR STACK NAME>

デプロイ

次にデプロイします。1分ほど待ちます。WebブラウザでCloudFormationにアクセスすると動いているのが分かります。

$ sam deploy --template-file packaged.yaml --stack-name sam-sample --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - sam-sample

API Gatewayのエンドポイントを取得

$ aws cloudformation describe-stacks --stack-name sam-sample --query 'Stacks[].Outputs'
[
    [
        {
            "Description": "Implicit IAM Role created for Hello World function",
            "OutputKey": "HelloWorldFunctionIamRole",
            "OutputValue": "arn:aws:iam::yyyyyyy:role/sam-sample-HelloWorldFunctionRole-1RAI3BIXXK7RS"
        },
        {
            "Description": "API Gateway endpoint URL for Prod stage for Hello World function",
            "OutputKey": "HelloWorldApi",
            "OutputValue": "https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/"
        },
        {
            "Description": "Hello World Lambda Function ARN",
            "OutputKey": "HelloWorldFunction",
            "OutputValue": "arn:aws:lambda:ap-northeast-1:yyyyyyyy:function:sam-sample-HelloWorldFunction-10SCXHEFU9F2H"
        }
    ]
]

動作確認

取得したエンドポイントにアクセスしてみます。

$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
StatusCode        : 200
StatusDescription : OK
Content           : {"message": "hello world", "location": "xxx.xxx.xxx.xxx"}
RawContent        : HTTP/1.1 200 OK
                    Connection: keep-alive
                    x-amzn-RequestId: c6a52235-9d77-11e8-9c19-e5ad43c51296
                    x-amz-apigw-id: Ldwi6G_UNjMFdTA=
                    X-Amzn-Trace-Id: Root=1-5b6efadf-18477a72e6ee65fc3d0b2342;Sampled=0
                    ...
Forms             : {}
Headers           : {[Connection, keep-alive], [x-amzn-RequestId, c6a52235-9d77-11e8-9c19-e5ad43c51296], [x-amz-apigw-i
                    d, Ldwi6G_UNjMFdTA=], [X-Amzn-Trace-Id, Root=1-5b6efadf-18477a72e6ee65fc3d0b2342;Sampled=0]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 56

成功しました!

Webブラウザで様子を見てみる

s3

トップ

バケットの中

API Gateway

トップ

詳細

Lambda

トップ

CloudFormation

参考