AWS SAM を使ってみたいので、API Gateway 経由で Hello World メッセージを表示する Lambda を呼び出すアプリケーションを SAM でデプロイしてみます。
前提条件
- AWS アカウントの作成
- Docker のインストール
- AWS SAM CLI のインストール
- "sam --version" と叩いてバージョンが表示されれば OK
サンプルアプリケーションのダウンロード
sam コマンド経由でサンプルとしてダウンロードできるアプリケーションがあるので、ダウンロードしていきます。
まずは下記のコマンドを入力します。
$ sam init
途中でテンプレートソース、パッケージタイム、ランタイムを選択していきます。
プロジェクト名は任意の名前で問題ありません。
ここでは「hello-sam」としています。
$ 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: 1
Which runtime would you like to use?
1 - nodejs14.x
2 - python3.8
3 - ruby2.7
4 - go1.x
5 - java11
6 - dotnetcore3.1
7 - nodejs12.x
8 - nodejs10.x
9 - python3.7
10 - python3.6
11 - python2.7
12 - ruby2.5
13 - java8.al2
14 - java8
15 - dotnetcore2.1
Runtime: 9
Project name [sam-app]: hello-sam
ここまで入力したら、自動で GitHub からテンプレートがローカルにダウンロードされてきます。
最後にテンプレートを選択します。
Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates
AWS quick start application templates:
1 - Hello World Example
2 - EventBridge Hello World
3 - EventBridge App from scratch (100+ Event Schemas)
4 - Step Functions Sample App (Stock Trader)
Template selection: 1
-----------------------
Generating application:
-----------------------
Name: hello-sam
Runtime: python3.7
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./hello-sam/README.md
ここまで表示されれば最初の準備は OK です。
アプリケーションの構築
プロジェクトディレクトリに移動して中身を確認してみましょう。
$ cd hello-sam
$ tree
.
├── README.md
├── __init__.py
├── events
│ └── event.json
├── hello_world
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── template.yaml
└── tests
├── __init__.py
└── unit
├── __init__.py
└── test_handler.py
この中の **template.yaml** というファイルが重要です。
AWS SAM では template.yaml という設定ファイルを作成し、AWS SAM リソースを定義します。
template.yaml の中身はこんな感じです。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
hello-sam
Sample SAM Template for hello-sam
# 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:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.7
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
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
AWS SAM は中で CloudFormation が動作して、コードとして書いた設定ファイルをもとに AWS リソースを作成してくれます。
template.yaml 内の Resources の欄で今回つくる Lambda、そして API Gateway を定義しています。
ではこの template.yaml をもとにビルドしましょう。
$ sam build
...
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
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
Build Succeeded と表示されればビルドは完了です。
ローカルでテスト
このままデプロイすることもできますが、デプロイする前に事前にローカルで実行し、ローカルで API を叩いてテストすることもできます。
Docker をインストールしておく必要はありますが、コマンド一つでローカル環境で実行できるので便利かつ楽です。
通常はクラウドにデプロイしてはじめて確認できる API Gateway ですが、ローカルでテストするためには sam local start-api コマンドを実行します。
$ sam local start-api
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
start-api コマンドによってローカルでテストするためのエンドポイントを起動することができます(中身としては Docker コンテナが動いています)。
さて、ローカルでテストするための URL が表示されているので、curl コマンドでアクセスしてみます。
※別なターミナルを立ち上げて実行します。
$ curl http://127.0.0.1:3000/hello
{"message": "hello world"}~ $
JSON 形式で Hello World のレスポンスが返ってきました。
この結果は API Gateway としてクラウドでデプロイした結果と同じ結果となります。
AWSへデプロイ
無事にローカルでテストすることができましたので、実際にデプロイしてみましょう。
基本的には sam deploy --guided と実行し、画面に表示される指示に従っていけば問題ありません。
今回の設定は下記の通りに指定していきます。
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [ap-northeast-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: N
#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]: n
内部で CloudFormation が動き、デプロイが完了すると次のように出力されます。
(一部情報はマスクしています)
CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------------
Key HelloWorldFunctionIamRole
Description Implicit IAM Role created for Hello World function
Value arn:aws:iam::xxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-XXXXXXXXXX
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:sam-app-
HelloWorldFunction-DL88K6
--------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
curl コマンドで API を叩いて試すには、Key が HelloWorldApi の欄に表示されている Value の URL にアクセスします。
$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world"}
ローカルでテストした時と同じレスポンスが返ってきていることが分かります。