チュートリアル: Hello World アプリケーションのデプロイ - AWS Serverless Application Model

チュートリアル: Hello World アプリケーションのデプロイ

このガイドでは、AWS SAM を使用してサンプルの Hello World アプリケーションをダウンロード、構築、およびデプロイします。その後、AWS クラウドでアプリケーションをテストし、オプションとして開発ホスト上でアプリケーションをローカルにテストします。

このアプリケーションは、基本的な API バックエンドを実装し、Amazon API Gateway エンドポイントと AWS Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数が呼び出されます。この関数は、hello world メッセージを返します。

以下の図は、このアプリケーションのコンポーネントを示しています。


      API Gateway エンドポイントに GET リクエストを送信するときに呼び出される Lambda 関数の図。

サンプルアプリケーションを初期化するときは、Zip または Image の Lambda デプロイパッケージタイプのオプションがあります。パッケージタイプの詳細については、AWS Lambda デベロッパーガイドの「Lambda デプロイパッケージ」を参照してください。

以下は、Hello World アプリケーションを作成するために実行するコマンドのプレビューです。各コマンドの詳細については、このチュートリアル後半のセクションを参照してください。

#Step 1 - Download a sample application sam init #Step 2 - Build your application cd sam-app sam build #Step 3 - Deploy your application sam deploy --guided

Prerequisites

このガイドは、「AWS SAM CLI のインストール」でオペレーティングシステム向けのステップを完了していることを前提としています。これには以下が含まれます。

  1. AWS アカウントの作成。

  2. AWS Identity and Access Management (IAM) 許可の設定。

  3. Docker のインストール。注意: Docker が前提条件となるのは、アプリケーションをローカルでテストする場合のみです。

  4. Homebrew のインストール。注意: Homebrew は、Linux と macOS 限定の前提条件です。

  5. AWS SAM コマンドラインインターフェイス (CLI) のインストール。注意: バージョン 1.13.0 以降を使用していることを確認してください。バージョンは、sam --version コマンドを実行してチェックします。

ステップ 1: サンプル AWS SAM アプリケーションをダウンロードする

実行するコマンド:

sam init

画面に表示されるプロンプトに従ってください。このチュートリアルでは、AWS Quick Start TemplatesZip パッケージタイプ、希望のランタイム、および Hello World Example を選択することが推奨されます。

出力例:

   
 -----------------------
 Generating application:
 -----------------------
 Name: sam-app
 Runtime: python3.7
 Dependency Manager: pip
 Application Template: hello-world
 Output Directory: .

 Next steps can be found in the README file at ./sam-app/README.md
        

AWS SAM が実行する事柄:

このコマンドは、ユーザーがプロジェクト名として提供した名前でディレクトリを作成します。プロジェクトディレクトリのコンテンツは以下に近いものになります。

 
 sam-app/
   ├── README.md
   ├── events/
   │   └── event.json
   ├── hello_world/
   │   ├── __init__.py
   │   ├── app.py            #Contains your AWS Lambda handler logic.
   │   └── requirements.txt  #Contains any Python dependencies the application requires, used for sam build
   ├── template.yaml         #Contains the AWS SAM template defining your application's AWS resources.
   └── tests/
       └── unit/
           ├── __init__.py
           └── test_handler.py
        
注記

これらのプロジェクトディレクトリコンテンツは、Python ランタイムの 1 つ、および Hello World Example を選択するときに作成されます。

以下の 3 つのファイルは特に重要です。

  • AWS: アプリケーションの AWS SAM リソースを定義する template.yaml テンプレートが含まれます。

  • hello_world/app.py: 実際の Lambda ハンドラーロジックが含まれます。

  • hello_world/requirements.txt: アプリケーションが必要とするすべての Python 依存関係が含まれ、sam build に使用されます。

ステップ 2: アプリケーションを構築する

実行するコマンド:

まず、サンプルアプリケーションの template.yaml ファイルがあるプロジェクトディレクトリに移動します。(デフォルトで、このディレクトリは sam-app です。) 次に、以下のコマンドを実行します。

sam build

出力例:

  
 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 が実行する事柄:

AWS SAM CLI には、依存関係を構築するための多数の Lambda ランタイムの抽象化が含まれており、すべてのパッケージ化およびデプロイ準備が整うように、ソースコードをステージングフォルダにコピーします。sam build コマンドは、アプリケーションが持つあらゆる依存関係を構築し、zip 形式で圧縮され、Lambda にアップロードされる .aws-sam/build 下のフォルダにアプリケーションソースコードをコピーします。

次の最上位のツリーが .aws-sam の下に表示されます。

 
 .aws-sam/
   └── build/
       ├── HelloWorldFunction/
       └── template.yaml
            

HelloWorldFunction は、app.py ファイルと、アプリケーションで使用するサードパーティーの依存関係を含むディレクトリです。

ステップ 3: アプリケーションを AWS クラウドにデプロイする

実行するコマンド:

sam deploy --guided

画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、Enter を押して応答します。

注記

HelloWorldFunction may not have authorization defined, Is this okay? [y/N] というプロンプトは、サンプルアプリケーションが認証なしで API Gateway API を設定することを AWS SAM が通知するプロンプトです。サンプルアプリケーションのデプロイ時、AWS SAM は一般に利用可能な URL を作成します。

この通知は、プロンプトに「Y」と応答することで承認できます。認証の設定については、「API Gateway API へのアクセスの制御」を参照してください。

出力例:

 
    Deploying with following values
    ===============================
    Stack name                 : sam-app
    Region                     : us-east-1
    Confirm changeset          : False
    Deployment s3 bucket       : sam-bucket
    Capabilities               : ["CAPABILITY_IAM"]
    Parameter overrides        : {}

 Initiating deployment
 =====================

 Waiting for changeset to be created..

 CloudFormation stack changeset
 ---------------------------------------------------------------------------------------------------------------------------------------------------
 Operation                                         LogicalResourceId                                 ResourceType
 ---------------------------------------------------------------------------------------------------------------------------------------------------
 + Add                                             HelloWorldFunctionHelloWorldPermissionProd        AWS::Lambda::Permission
 + Add                                             ServerlessRestApiDeployment47fc2d5f9d             AWS::ApiGateway::Deployment
 + Add                                             ServerlessRestApiProdStage                        AWS::ApiGateway::Stage
 + Add                                             ServerlessRestApi                                 AWS::ApiGateway::RestApi
 * Modify                                          HelloWorldFunctionRole                            AWS::IAM::Role
 * Modify                                          HelloWorldFunction                                AWS::Lambda::Function
 ---------------------------------------------------------------------------------------------------------------------------------------------------

 2019-11-21 14:33:24 - Waiting for stack create/update to complete

 CloudFormation events from changeset
 -------------------------------------------------------------------------------------------------------------------------------------------------
 ResourceStatus                       ResourceType                         LogicalResourceId                    ResourceStatusReason
 -------------------------------------------------------------------------------------------------------------------------------------------------
 UPDATE_IN_PROGRESS                   AWS::IAM::Role                       HelloWorldFunctionRole               -
 UPDATE_COMPLETE                      AWS::IAM::Role                       HelloWorldFunctionRole               -
 UPDATE_IN_PROGRESS                   AWS::Lambda::Function                HelloWorldFunction                   -
 UPDATE_COMPLETE                      AWS::Lambda::Function                HelloWorldFunction                   -
 CREATE_IN_PROGRESS                   AWS::ApiGateway::RestApi             ServerlessRestApi                    -
 CREATE_COMPLETE                      AWS::ApiGateway::RestApi             ServerlessRestApi                    -
 CREATE_IN_PROGRESS                   AWS::ApiGateway::RestApi             ServerlessRestApi                    Resource creation Initiated
 CREATE_IN_PROGRESS                   AWS::ApiGateway::Deployment          ServerlessRestApiDeployment47fc2d5   Resource creation Initiated
                                                                          f9d
 CREATE_IN_PROGRESS                   AWS::Lambda::Permission              HelloWorldFunctionHelloWorldPermis   Resource creation Initiated
                                                                          sionProd
 CREATE_IN_PROGRESS                   AWS::Lambda::Permission              HelloWorldFunctionHelloWorldPermis   -
                                                                          sionProd
 CREATE_IN_PROGRESS                   AWS::ApiGateway::Deployment          ServerlessRestApiDeployment47fc2d5   -
                                                                          f9d
CREATE_COMPLETE                      AWS::ApiGateway::Deployment          ServerlessRestApiDeployment47fc2d5   -
                                                                          f9d
 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              HelloWorldFunctionHelloWorldPermis   -
                                                                          sionProd
 UPDATE_COMPLETE_CLEANUP_IN_PROGRES   AWS::CloudFormation::Stack           sam-app                              -
 S
 UPDATE_COMPLETE                      AWS::CloudFormation::Stack           sam-app                              -
 -------------------------------------------------------------------------------------------------------------------------------------------------

 Stack sam-app outputs:
 ---------------------------------------------------------------------------------------------------------------------------------------------------
 OutputKey-Description                                                     OutputValue
 ---------------------------------------------------------------------------------------------------------------------------------------------------
 HelloWorldFunctionIamRole - Implicit IAM Role created for Hello World     arn:aws:iam::123456789012:role/sam-app-
 function                                                                  HelloWorldFunctionRole-104VTJ0TST7M0
 HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello World   https://0ks2zue0zh.execute-api.us-east-1.amazonaws.com/Prod/hello/
 function
 HelloWorldFunction - Hello World Lambda Function ARN                      arn:aws:lambda:us-east-1:123456789012:function:sam-app-
                                                                          HelloWorldFunction-1TY92MJX0BXU5
 ---------------------------------------------------------------------------------------------------------------------------------------------------

 Successfully created/updated stack - sam-app in us-east-1
        

AWS SAM が実行する事柄:

このコマンドは、アプリケーションを AWS クラウドにデプロイします。sam build コマンドで構築したデプロイアーティファクトを取得してパッケージ化し、AWS SAM CLI が作成する Amazon Simple Storage Service (Amazon S3) バケットにそれらをアップロードしてから、AWS CloudFormation を使用してアプリケーションをデプロイします。sam deploy コマンドの出力では、AWS CloudFormation スタックに行われた変更を確認できます。

アプリケーションが HTTP エンドポイントを作成した場合、sam deploy が生成する出力には、テストアプリケーションのエンドポイント URL も表示されます。そのエンドポイント URL を使用したアプリケーションへのリクエストの送信には curl を使用できます。以下がその例です。

curl https://<restapiid>.execute-api.us-east-1.amazonaws.com/Prod/hello/

アプリケーションが正常にデプロイされると、以下のような出力が表示されます。

 
 {"message": "hello world"}
        

curl コマンドの実行後に {"message": "hello world"} が表示される場合は、サーバーレスアプリケーションが AWS に正常にデプロイされ、ライブ Lambda 関数を呼び出していることになります。これが表示されない場合は、このチュートリアルの後半にある「Troubleshooting」セクションを参照してください。

ステップ 4: (オプション) アプリケーションをローカルでテストする

アプリケーションを開発しているときは、ローカルでのテストが役立つ場合があります。AWS SAM CLI は、Lambda の実行環境をシミュレートする Docker コンテナを使用してアプリケーションを実行する sam local コマンドを提供します。これには、以下の 2 つのオプションがあります。

  • API をローカルでホストする

  • Lambda 関数を直接呼び出す

このステップでは、両方のオプションについて説明します。

API をローカルでホストする

実行するコマンド:

sam local start-api

出力例:

 
 2019-07-12 15:27:58 Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
 2019-07-12 15:27:58 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
 2019-07-12 15:27:58  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

 Fetching lambci/lambda:python3.7 Docker container image......................................................................................................................................................................................
 2019-07-12 15:28:56 Mounting /<working-development-path>/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
 START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST
 END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
 REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72  Duration: 4.42 ms       Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 22 MB
 2019-07-12 15:28:58 No Content-Type given. Defaulting to 'application/json'.
 2019-07-12 15:28:58 127.0.0.1 - - [12/Jul/2019 15:28:58] "GET /hello HTTP/1.1" 200 -
            

Docker イメージのロードには時間がかかる場合があります。ロード完了後、curl を使用して、ローカルホストで実行されているアプリケーションにリクエストを送信できます。

curl http://127.0.0.1:3000/hello

出力例:

 
 2019-07-12 15:29:57 Invoking app.lambda_handler (python3.7)
 2019-07-12 15:29:57 Found credentials in shared credentials file: ~/.aws/credentials

 Fetching lambci/lambda:python3.7 Docker container image......
 2019-07-12 15:29:58 Mounting /<working-development-path>/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
 START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST
 END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
 REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72  Duration: 7.92 ms       Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 22 MB
 {"statusCode":200,"body":"{\"message\": \"hello world\"}"}
            

AWS SAM が実行する事柄:

start-api コマンドは、REST API エンドポイントをレプリケートするローカルエンドポイントを起動します。これは、関数をローカルで実行できる実行コンテナをダウンロードします。その結果、AWS クラウドで関数を呼び出したときと同じ出力が得られます。

Lambda 関数を直接呼び出す

実行するコマンド:

sam local invoke "HelloWorldFunction" -e events/event.json

出力例:

 
 2019-07-01 14:08:42 Found credentials in shared credentials file: ~/.aws/credentials
 2019-07-01 14:08:42 Invoking app.lambda_handler (python3.7)

 Fetching lambci/lambda:python3.7 Docker container image...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
 2019-07-01 14:09:39 Mounting /<working-development-path>/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
 START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST
 END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
 REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72    Duration: 3.51 ms    Billed Duration: 100 ms    Memory Size: 128 MB    Max Memory Used: 22 MB    
 {"statusCode":200,"body":"{\"message\": \"hello world\"}"}
            

AWS SAM が実行する事柄:

invoke コマンドは Lambda 関数を直接呼び出し、ユーザー提供の入力イベントペイロードを渡すことができます。このコマンドを使用して、サンプルアプリケーションが提供するファイル event.json のイベントペイロードを渡します。

初期化されたアプリケーションには、API Gateway 用のデフォルトの aws-proxy イベントが含まれています。いくつかの値が事前に入力されています。この場合、HelloWorldFunction は特定の値を認識しないため、スタブされたリクエストで十分です。実際のリクエストに期待するものをシミュレートするために、リクエストに代入する値をいくつか指定できます。以下は、独自の入力イベントを生成し、出力をデフォルトの event.json オブジェクトと比較する例です。

sam local generate-event apigateway aws-proxy --body "" --path "hello" --method GET > api-event.json diff api-event.json events/event.json

出力例:

 
 <   "body": "",
 ---
 >   "body": "{\"message\": \"hello world\"}",
 4,6c4,6
 <   "path": "/hello",
 <   "httpMethod": "GET",
 <   "isBase64Encoded": true,
 ---
 >   "path": "/path/to/resource",
 >   "httpMethod": "POST",
 >   "isBase64Encoded": false,
 11c11
 <     "proxy": "/hello"
 ---
 >     "proxy": "/path/to/resource"
 56c56
 <     "path": "/prod/hello",
 ---
 >     "path": "/prod/path/to/resource",
 58c58
 <     "httpMethod": "GET",
 ---
 >     "httpMethod": "POST",
            

Troubleshooting

AWS SAM CLI エラー: 「Security Constraints Not Satisfied」

sam deploy --guided の実行時に、HelloWorldFunction may not have authorization defined, Is this okay? [y/N] という質問のプロンプトが表示されます。このプロンプトに「N」(デフォルトのレスポンス) と答えた場合、以下のエラーが表示されます。

 
Error: Security Constraints Not Satisfied
            

このプロンプトは、デプロイしようとしているアプリケーションに、認証なしで設定された Amazon API Gateway API が存在する可能性があることを知らせています。このプロンプトに「N」と答えることによって、この状態は望ましくないと伝えることになります。

この問題を解決するには、以下のオプションがあります。

  • 認証を使用してアプリケーションを設定する。認証の設定については、「API Gateway API へのアクセスの制御」を参照してください。

  • この質問に「Y」と答えて、認証なしで設定された API Gateway API が存在するアプリケーションをデプロイしてもよいことを示す。

AWS SAM CLI エラー: 「no such option: --app-template」

sam init の実行時に、以下のエラーが表示されます。

 
Error: no such option: --app-template
            

これは、AWS SAM パラメータをサポートしていない古いバージョンの --app-template CLI を使用していることを意味します。これを修正するには、AWS SAM CLI のバージョンを 0.33.0 以降に更新するか、--app-template コマンドから sam init パラメータを削除します。

AWS SAM CLI エラー: 「no such option: --guided」

sam deploy の実行時に、以下のエラーが表示されます。

 
Error: no such option: --guided
            

これは、AWS SAM パラメータをサポートしていない古いバージョンの --guided CLI を使用していることを意味します。これを修正するには、AWS SAM CLI のバージョンを 0.33.0 以降に更新するか、--guided コマンドから sam deploy パラメータを削除します。

AWS SAM CLI エラー: 「Failed to create managed resources: Unable to locate credentials」

sam deploy の実行時に、以下のエラーが表示されます。

 
Error: Failed to create managed resources: Unable to locate credentials
            

これは、AWS 認証情報をセットアップして、AWS SAM CLI が AWS のサービスの呼び出せるようにしていないことを意味します。これを修正するには、AWS 認証情報をセットアップする必要があります。詳細については、「AWS 認証情報のセットアップ」を参照してください。

AWS SAM CLI エラー: 「Running AWS SAM projects locally requires Docker. Have you got it installed?」

sam local start-api の実行時に、以下のエラーが表示されます。

 
Error: Running AWS SAM projects locally requires Docker. Have you got it installed?
            

これは、Docker が正しくインストールされていないことを意味します。ローカルでアプリケーションをテストするには、Docker が必要です。これを修正するには、開発ホスト用の Docker をインストールする手順を実行します。「AWS SAM CLI のインストール」に移動して、適切なプラットフォームを選択してから「Docker をインストールする」というタイトルのセクションにある手順に従ってください。

Curl エラー: 「Missing Authentication Token」

API Gateway エンドポイントを呼び出そうとしているときに、以下のエラーが表示されます。

 
 {"message":"Missing Authentication Token"}
            

これは、正しいドメインにリクエストを送信しようとしたものの、URI を認識できないことを意味します。この問題を解決するには、完全な URL を確認し、正しい URL で curl コマンドを更新します。

Curl エラー: 「curl: (6) Could not resolve: ...」

API Gateway エンドポイントを呼び出そうとしているときに、以下のエラーが表示されます。

 
 curl: (6) Could not resolve: endpointdomain (Domain name not found)
            

これは、無効なドメインにリクエストを送信しようとしたことを意味します。このエラーは、サーバーレスアプリケーションが正常にデプロイされなかった場合、または curl コマンドに入力ミスがある場合に発生します。AWS CloudFormation コンソールまたは AWS CLI を使用して、アプリケーションが正常にデプロイされたこと、および curl コマンドが正しいことを確認します。

クリーンアップ

このチュートリアルを実行して作成した AWS リソースが不要になった場合は、デプロイした AWS CloudFormation スタックを削除することでそれらを削除できます。

AWS Management Console を使用して作成した AWS CloudFormation スタックを削除するには、以下のステップを実行します。

  1. AWS Management Console にサインインし、AWS CloudFormation コンソール (https://console.aws.amazon.com/cloudformation) を開きます。

  2. 左のナビゲーションペインで [Stacks] (スタック) をクリックします。

  3. スタックのリストで、sam-app (または作成したスタックの名前) を選択します。

  4. [Delete] (削除) をクリックします。

これが完了すると、スタックのステータスが DELETE_COMPLETE に変わります。

または、以下の AWS CLI コマンドを実行して AWS CloudFormation スタックを削除することもできます。

aws cloudformation delete-stack --stack-name sam-app --region region

削除されたスタックを確認する

どちらの AWS CloudFormation スタック削除方法でも、AWS CloudFormation コンソールでスタックが削除されたことを確認できます。左側のナビゲーションペインで [Stacks] (スタック) をクリックしてから、検索ボックスの横にあるドロップダウンリストで [Delete] (削除) を選択します。削除されたスタックのリストに、削除したスタック名が表示されます。

Conclusion

このチュートリアルでは、以下の作業を行いました。

  1. AWS SAM を使用して、サーバーレスアプリケーションの作成、構築、および AWS へのデプロイを実行する。

  2. AWS SAM CLI と Docker を使用してアプリケーションをローカルでテストする。

  3. 不要になった AWS リソースを削除する。

次のステップ

これで、AWS SAM CLI を使用して独自のアプリケーションの構築を開始する準備が整いました。

開始しやすくするために、GitHub の AWS Serverless Application Repository Examples リポジトリからサンプルアプリケーションをダウンロードすることができます。