サーバーレスのローカル開発環境を整備する ~中編

2023-03-13
デベロッパーのためのクラウド活用方法

Author : 杉 達也

「サーバーレスのローカル開発環境を整備する」というテーマで、前編 ではローカルPC環境でのサーバーレス開発環境の設定について触れました。本記事では実際の開発およびデバッグ手順を紹介します。

この連載記事のその他の記事はこちら

選択
  • 選択
  • サーバーレスのローカル開発環境を整備する ~前編
  • サーバーレスのローカル開発環境を整備する ~中編
  • サーバーレスのローカル開発環境を整備する ~後編

Step 3 - ローカル環境での開発作業

各開発ツール環境での設定が完了していれば、ツール上のメニューや新規プロジェクト・ダイアログなどから SAM アプリケーションの開発をスタートできます。

  • Visual Studio Code
  • Eclipse
  • IntelliJ IDEA

それぞれ、ウィザード形式で SAM アプリケーションのテンプレートを選択することで、プロジェクトが雛形のアプリケーションファイルとともに構成されます。なお、この GUI 型のウィザードで選択できるテンプレートとは別に、コマンドラインから SAM CLI を利用する (次項にて説明します) ことで、より多くのテンプレートが選択できます。

これらのテンプレートのいくつかは、典型的なサーバーレスのパターン実装例です。以下の表では、本記事の執筆時点での Visual Studio Code、Eclipse、IntelliJ IDEA の AWS Toolikt ウィザードと、SAM CLI コマンドで選択できるテンプレートの一覧、およびそれらに対応する開発言語とバージョン、サーバーレスパターンの対応を表しています。

Template Java .NET Go Node.js Python Ruby Rust サーバーレスパターンの関連するケース コメント
VS Code SAM CLI テンプレートの一部と同じ。コメント部の appTemplate で判別可能。
SAM Hello World 11, 8 6, 5, 3.1 1.x 18, 16, 14, 12 3.10, 3.9, 3.8, 3.7     (シンプルな API) hello-world
SAM CLI -1 と同じ
EventBridge Hello World     1.x   3.10, 3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント eventbridge-hello-app
SAM CLI -8 のうちの一つ
EventBridge App From Scracth     1.x   3.10, 3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント eventbridge-scheme-app
SAM CLI -8 のうちの一つ
Step Functions Sample 11, 8 6, 3.1 1.x 18, 16, 14, 12 3.10, 3.9, 3.8, 3.7     アプリケーションフロー処理 step-functions-sample-app
SAM CLI -4 と同じ
App Backend using TypeScript       12         quick-start-typescript-app
Eclipse 注: Eclipse 2021-12 以前でのみ機能します
article x             動的 Web / モバイルバックエンド  
hello-world x             (単独のLambda関数)  
recognition x             画像処理 / シンプルなデータ加工  
IntelliJ / Rider 多くは SAM CLI テンプレートの一部と同じ。
SAM Hello World 17, 11, 8 6, 3.1   18, 16, 14 3.11, 3.10, 3.9, 3.8, 3.7     (シンプルな API) hello-world
SAM CLI -1 と同じ
EventBridge Hello World 17, 11, 8       3.11, 3.10, 3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント eventbridge-hello-app
SAM CLI -8 のうちの一つ
EventBridge App From Scracth 17, 11, 8       3.11, 3.10, 3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント eventbridge-scheme-app
SAM CLI -8 のうちの一つ
DynamoDB Event Example         3.11, 3.10, 3.9, 3.8, 3.7     データ変更トリガー処理 aws-samples/cookiecutter-aws-sam-dynamodb-python
SAM CLI useCaseName で判別可能。
1 - Hello World Example 17, 11, 8 7, 6 1.x 18, 16, 14 3.11, 3.10, 3.9, 3.8, 3.7 3.2, 2.7 x (シンプルな API)  
2 - Data processing   6   18, 16, 14       シンプルなデータ加工、イベント駆動の業務処理連携  
3 - Hello World Example with Powertools 17, 11, 8 6   18, 16, 14 3.10, 3.9, 3.8, 3.7     (シンプルな API)  
4 - Multi-step workflow 17, 11, 8 6 1.x 18, 16, 14 3.11, 3.10, 3.9, 3.8, 3.7 3.2, 2.7   アプリケーションフロー処理  
5 - Scheduled task   6   18, 16, 14       スケジュール・ジョブ  
6 - Standalone function   6   18, 16, 14       (単独のLambda関数)  
7 - Serverless API   6   18, 16, 14       動的 Web / モバイルバックエンド  
8 - Infrastructure event management 17, 11, 8   1.x   3.11, 3.10, 3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント  
9 - Lambda Response Streaming     1.x 18, 16         Response Streaming 機能 + Function URLs のサンプル
10 - Serverless Connector Hello World Example       16, 14 3.11, 3.10, 3.9, 3.8, 3.7     (シンプルな API) SAM Connector 利用のサンプル
11 - Multi-step workflow with Connectors       16, 14 3.11, 3.10, 3.9, 3.8, 3.7     アプリケーションフロー処理 SAM Connector 利用のサンプル
12 - GraphQLApi Hello World Example       18       インタラクティブ API AppSync を利用したサンプル
13 - Full Stack       18       動的 Web / モバイルバックエンド フロント UI 部を含む、サーバーレス Web アプリのフルスタック
14 - Lambda EFS example         3.11, 3.10, 3.9, 3.8       EFS 利用サンプル
15 - Hello World Example With Powertools         3.11     (シンプルな API)  
16 - DynamoDB Example             x (シンプルな API) Rust 実装例のシンプルな Data Put API
17 - Machine Learning         3.11, 3.10, 3.9, 3.8     (機械学習推論API)  
  • Node.js 12 は選択可能ですが、既に Node.js としてサポートが終了しています。
  • Visual Studio Code のウィザードは、SAM CLI で選択できるテンプレートの一部と同じものです。
  • Eclipse の GUI ウィザードは、最新の Eclipse では機能しません (関連Issue)。Eclipse 2021-12 では機能します。

この表から逆引きすれば、やりたいこと (ユースケース) から開発を始める最初のテンプレート (AWS Toolkit のウィザード or SAM CLI) を選択するというやり方もできます。

以降では、もっとも選択肢の多い SAM CLI によるテンプレート生成から開発を進めていく手順をご紹介します。

SAM CLI を用いたテンプレートの選択

コマンドラインから SAM CLI の以下のコマンドを実行します。

sam init

以下のように対話形式で言語やテンプレートの選択を行うことができます。ネットワークがインターネットと接続可能な環境では、より多くのテンプレートから選択できます。

以下、sam init コマンドの実行例です。

You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

Which template source would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
    1 - Hello World Example
    2 - Data processing
    3 - Hello World Example with Powertools for AWS Lambda
    4 - Multi-step workflow
    5 - Scheduled task
    6 - Standalone function
    7 - Serverless API
    8 - Infrastructure event management
    9 - Lambda Response Streaming
    10 - Serverless Connector Hello World Example
    11 - Multi-step workflow with Connectors
    12 - GraphQLApi Hello World Example
    13 - Full Stack
    14 - Lambda EFS example
    15 - Hello World Example With Powertools
    16 - DynamoDB Example
    17 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: n

Which runtime would you like to use?
    1 - aot.dotnet7 (provided.al2)
    2 - dotnet6
    3 - go1.x
    4 - go (provided.al2)
    5 - graalvm.java11 (provided.al2)
    6 - graalvm.java17 (provided.al2)
    7 - java17
    8 - java11
    9 - java8.al2
    10 - java8
    11 - nodejs18.x
    12 - nodejs16.x
    13 - nodejs14.x
    14 - python3.9
    15 - python3.8
    16 - python3.7
    17 - python3.11
    18 - python3.10
    19 - ruby3.2
    20 - ruby2.7
    21 - rust (provided.al2)
Runtime: 7

What package type would you like to use?
    1 - Zip
    2 - Image
Package type: 1

Which dependency manager would you like to use?
    1 - gradle
    2 - maven
Dependency manager: 2

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: n

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: n

Project name [sam-app]: sample-java

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sample-java
    Runtime: java17
    Architectures: x86_64
    Dependency Manager: maven
    Application Template: hello-world
    Output Directory: .
    Configuration file: sample-java/samconfig.toml
    
    Next steps can be found in the README file at ./sample-java/README.md

上記例のように Java 言語の Hello World Example テンプレートを選択した場合、指定した Project Name (上記では sample-java) のフォルダに以下のような構成が作れらます (選択した言語やテンプレートによって内容は変化します)。

sample-java
+ events
   - event.json ← イベントJSONデータのサンプル。このケースでは API イベントとして生成されています。
+ HelloWorldFunction
   - pom.xml
   + src
      + main ← メインの開発コードのフォルダ
      + test ← テスト用のコートのフォルダ
- README.md
- samconfig.toml ← SAM 設定ファイル
- template.yaml ← SAM テンプレートファイル

ローカル開発環境での開発・デバッグ・単体テスト

ここでは、各開発ツールでの代表的な手順をご紹介します。

  • Visual Studio Code
  • SAM CLI による生成テンプレートのプロジェクトの取り込みとデバッグ構成の作成

    Visual Studio Code のエクスプローラーで「フォルダーを開く」を選択し、前述の方法で生成したテンプレートを含む最上位フォルダー (前述の例では sample-java) を指定すると、フォルダー配下が識別されます。

    プロジェクト内のメインとなるソースファイル (典型的なテンプレートでは、Java言語であれば App.java、Node.js では app.js など) を開くと、AWS Toolkit によって Lambda のハンドラメソッドが検出され、該当メソッドの上部に [AWS: Add Debug Configuration | AWS: Edit Debug Configuration] というヒントが表示されます。

    クリックすると拡大します

    上記のヒントが表示されない場合、設定がオフになっている可能性があります。Visual Studio Code の設定パネルで「lens」で検索し、拡張機能 - AWS Toolkit の部分を見ると、「Samcli: Enable Code Lenses」という項目があります。こちらをオンにしてください。

    クリックすると拡大します

    Add Debug Configuration」をクリックすると、上部にこちらのような選択ダイアログが表示されます。

    クリックすると拡大します

    この例では、単独の Lambda 関数として呼び出すための構成 [template.yaml:HelloWorldFunction] と、API Gateway 経由で GET API の背後で Lambda 関数を呼び出すための構成 [template.yaml:HelloWorldFunction(API Event)] が選択可能になっていることがわかります。実行テストの対象を選択すると、その呼び出しのための構成を記述するコードエディタが開きます。ここで実行時の構成や引数を指定します。この選択オプションは template.yaml の記述から判断されています。

    • template.yaml:HelloWorldFunction : 単独で Lambda 関数を実行テストするための構成。実行時には sam local invoke が実行されます。
    • template.yaml:HelloWorldFunction(API Event) : API 経由での Lambda 関数の実行構成。実行時には sam local start-api が実行されます。

    コードエディタで実行時の構成を記述します。
    例えば、引数となるイベントデータを以下のように payload 部分に指定します。

    "lambda": {
           "payload": {
               "path": "${workspaceFolder}/events/event.json"
            },
       ...

    ここで記述する内容については、ドキュメント もご参照ください。

    クリックすると拡大します

    この情報は、launch.json または <<workspace>>.code-workspace というワークスペース定義ファイルに保存され、以降のテスト・デバッグでも有効になります。

    デバッグ構成の二度目以降の修正には、

    • [注意 1] 「Add Debug Configuration」をクリックしてエディタを表示させるたびに、新規の Configuration エントリが追加されてしまうので注意してください。
    • [注意 2] 「Edit Debug Configuration」をクリックすると編集パネルが表示されます。ただ、この編集パネルではできることが制限されていますので、エディタで記述することをお勧めします。
      Visual Studio Code の「実行とデバッグ」タブの上部にある歯車のボタンを押すと、コードエディタで編集することができます。

    クリックすると拡大します

    ローカルでのテスト実行・デバッグ

    ローカル環境で Docker Desktop が起動していることを確認します。

    Visual Studio Code の「実行とデバッグ」タブの上部から、実行する構成を選択し、「デバッグの開始」ボタンを押します。ビルドとデバッグ実行が開始され、ブレークポイントを設定していれば、そこで停止し、変数値を確認することができます。

    クリックすると拡大します

    [注意] 単独で Lambda 関数を実行テストするための構成 (デバッグ構成で target : template のケース) では sam local invoke が実行され、関数処理の終了と共にこのプロセスが消えます。一方、API 構成の実行 (デバッグ構成で target : api のケース) では sam local start-api が実行されます。この実行プロセスは、ツール上でのデバッグ作業が完了した後にも残ることに注意してください。つまり、API 構成のデバッグを何度も繰り返すと sam local start-api のプロセスが複数起動し、Visual Studio Code を終了させた後も残ることになります。これを避けるために、Visual Studio Code のプロセスエクスプローラーを開いておき (Visual Studio Code メニュー「ヘルプ」→「プロセスエクスプローラー」を開く)、API 構成のデバッグが終わるたびに、プロセスを終了させることを手順として決めておくと良いでしょう。

    クリックすると拡大します

  • Eclipse
  • [注意]

    Eclipse での手順について: Eclipse + AWS Toolkit での Java 言語での Lambda 関数の開発・テスト・デバッグ手順について記載していますが、AWS Toolkit for Eclipse が提供する機能は Gradle プロジェクトはサポートしていません (関連 Issue)。Gradle を用いる場合は、AWS Toolkit を利用せずに、SAM CLI のコマンドをターミナルから直接利用する形式になります。別の言い方をすると、Eclipse + AWS Toolkit で Java 言語での Lambda 関数の開発・テスト・デバッグをするなら Maven プロジェクトとしてテンプレート生成することが推奨になります。以降の Eclipse での手順では Maven プロジェクトを対象とした記述をしています。

    SAM CLI による生成テンプレートのプロジェクトの取り込みとデバッグ構成の作成

    Eclipse のメニューから「ファイルインポート」を選択します。生成テンプレートのタイプに応じて、既存 Maven プロジェクトを指定し、生成テンプレートのルートディレクトリ(前述の例 では sample-java) を指定します。

    クリックすると拡大します

    このウィザードでは、指定されたディレクトリ配下で Maven 定義ファイルを検出し、その検出された場所を基準としてファイルの取り込みを行います。

    SAM CLI から生成されるプロジェクトが以下のような形の場合、template.yaml や events ディレクトリが Eclipse プロジェクトに取り込まれないことになります。以降の作業のため、template.yaml および events ディレクトリをプロジェクト配下 (上記例では HelloWorldFunction ディレクトリ直下) に移動させてください。

    [元の構成]
    sample-java
    + events
    + HelloWorldFunction
       - pom.xml ← Maven 定義ファイル
       + src
    - README.md
    - template.yaml ← SAM テンプレートファイル

    [変更後]
    sample-java
    + HelloWorldFunction
       - pom.xml
       + src
       + events ← HelloWorldFunction 下に移動
       - template.yaml ← HelloWorldFunction 下に移動
    - README.md

    次に、Eclipse のメニュー「実行 デバッグ構成」を選び、左ペインの「AWS SAM Local」ツリーから新規構成を作成します。

    クリックすると拡大します

    ここではテスト実行の構成を定義します。名前を適切に設定し (下記イメージでは HelloWorld と設定)、プロジェクトとその配下のテンプレート (template.yaml) を指定します。「実行」リストの選択によって次のようになります。

    • Lambda Function を選択 : 単独で Lambda 関数を実行テストするための構成。実行時には sam local invoke が実行されます。このとき、引数として渡すイベントを指定する必要があります。
      • イベント :生成」ボタンから新しいイベントファイルを生成することができるようドキュメントに記載がありますが、本記事の執筆時点では、この部分の機能が正常に作動しません (関連 Issue)。SAM CLI による生成テンプレートでは events/event.json ファイルが付属していますので、「参照」ボタンからそれを選択します。
    • API Gateway を選択 : API 経由での Lambda 関数の実行構成。実行時には sam local start-api が実行されます。
      • このパネルの「拡張設定」部分では、AWS Toolkit が通常 AWS 環境に接続するために使用する AWS認証情報を含むプロファイルがデフォルト状態で選択されています。しかし、sam local start-api 実行時にこのプロファイル設定が利用されてしまい、デバッガプロセスが接続できない状態になります。これを避けるには次のようにします。

    Configure AWS profile」をクリックし、設定ダイアログから「プロファイルの追加」を行います。ただし、プロファイル名だけを設定し、中身は空のプロファイルとします。これを先の「拡張設定」部分で選択しておくことで、sam local start-api 実行時の認証が追加されずに、後続のデバッガプロセスが接続できるようになります。

    クリックすると拡大します

    一方、空のプロファイルを選択すると、AWS Toolkit が通常利用する AWS への接続情報も空のプロファイルを使うように切り替わってしまうため、これを再設定しておいてください。

    クリックすると拡大します

    [追加の設定作業]
    本記事の執筆時点の AWS Toolkit for Eclipse では、次項で示す Issue のため、デバッガプロセスの設定を追加で用意しておく必要があります。ここではその方法を紹介します。

    先ほど利用した「デバッグ構成」ダイアログで「リモート Java アプリケーション」を新規作成します。

    名前を設定し (イメージでは SAM Debugger としています)、ポートを「5858」とします。

    この リモート Java アプリケーション のデバッグ設定は後ほど利用します。

    クリックすると拡大します

    ローカルでのテスト実行・デバッグ

    ローカル環境で Docker Desktop が起動していることを確認します。

    Eclipse の起動構成パネルに、前述の手順で設定したデバッグ構成が表示されます。AWS SAM Local ツリーのエントリに対する右クリックメニューから「デバッグ」を選択します。

    デバッグのための準備処理が始まります。

    クリックすると拡大します

    ここには、

    1. sam local によるローカル環境での Lambda プロセスの起動
    2. 開発ツールからデバッガプロセスによる接続

    の 2 つの工程があります。

    [注意] 本記事の執筆時点では、2 つ目の工程に入る前にエラーが起きたことを示すダイアログが表示されます(関連 Issue)。ただ、このダイアログが表示されても、1 つ目の工程によってデバッグ設定された sam local コマンドの実行は行われていますので、2 つ目の工程を追加 / 手動で行うことでデバッグ作業を行うことができます。

    単独で Lambda 関数のデバッグ構成 : 

    1. Eclipse の起動構成パネルから対象の Lambda 関数の実行構成を選択してデバッグ実行し、デバッグパネルで起動してることを確認します。
    2. 起動構成パネルのデバッグ構成から、前述の「追加の設定作業」で追加した リモート Java アプリケーション構成 (SAM Debugger) の「デバッグ」を実行します。

    これによって、実行中のローカル Lambda 関数にデバッガプロセスが接続します。ブレークポイントを設定していれば、そこで一時停止し、変数値の確認などが可能です。

    クリックすると拡大します

    API 経由の Lambda 関数のデバッグ : 

    1. Eclipse の起動構成パネルから対象の Lambda 関数の実行構成を選択してデバッグ実行し、デバッグパネルで起動してることを確認します。
      これによって、実行中のローカル Lambda 関数にデバッガプロセスが接続します。ブレークポイントを設定していれば、そこで一時停止し、変数値の確認などが可能です。
    2. ターミナルから API コールを実行します (例 : curl http://127.0.0.1:3000/hello)。これで API 経由の Lambda プロセスが起動状態になり、サーバー処理の応答待ち状態になります。
    3. この状態で、Eclipse の起動構成パネルのデバッグ構成から リモート Java アプリケーションの「デバッグ」を起動します。

    これによって、実行中のローカル Lambda 関数にデバッガプロセスが接続します。ブレークポイントを設定していれば、そこで一時停止し、変数値の確認などが可能です。

    クリックすると拡大します

    [注意] API 経由の Lambda 関数のデバッグでは、開発ツールでの処理が終わった後もローカル API のプロセスが起動したままです (Eclipse のデバッグパネルにプロセスが残っていることが確認できます)。

    これを終了させようとしてもエラーが出てプロセスが残ってしまうことがあります。この場合、OS 側のプロセス管理ツールから該当プロセスを停止させてください。該当プロセスの ID は Eclipse のコンソールから確認可能です。

    クリックすると拡大します

  • IntelliJ IDEA
  • SAM CLI による生成テンプレートのプロジェクトの取り込みとデバッグ構成の作成

    IntelliJ IDEA で「開く」を選択し、前述の方法 (sam init) で生成したテンプレートを含む最上位フォルダ (前述の例では sample-java) を指定すると、フォルダ配下が識別されます。

    プロジェクト内のメインとなるソースファイル (典型的なテンプレートでは、Java 言語であれば App.java) を開きます。エディタ上部にプロジェクト JDK が定義されていない旨の警告が出ていれば、適切な JDK バージョンを選択しておきます。

    クリックすると拡大します

    テンプレート・ファイル群を取り込んだ直後では、サーバーレスアプリのローカル実行のための構成がまだ設定されていません。以降では、これを新規で追加設定する手順を記載します。

    ツール右上部から「実行構成の編集」を選択します。

    クリックすると拡大します

    開いたダイアログの「新規構成の追加」から、「AWS Lambda - Local」を選択します。

    クリックすると拡大します

    開かれたダイアログでは特定のハンドラー・メソッドを指定した実行構成を作成することもできますが、ここでは template の設定に基づく構成を作成する手順を紹介します。

    ダイアログで「From template」を選択、生成された template.yaml をその下の項目で指定します。template.yaml が解釈されて、その右のプルダウンから実行対象を選択できるようになります。

    クリックすると拡大します

    Input 部では、直にテキストで入力引数値を指定することもできますが、sam init が生成した event.json を指定(通常、<<ProjectDir>>/events/event.json として生成されています)して、そのファイル内で引数値を調整するのでも良いでしょう。

    同ダイアログの AWS Connection タブでは、AWS 環境への接続情報 (認証設定および接続リージョン) を選択しておきます。

    実際にはローカル実行・デバッグでは AWS 環境に接続しないため、この情報を使うことはないのですが、本ダイアログのチェック機能として値が設定されていないと先に進めないため、これらを設定してください。

    クリックすると拡大します

    なお、sam init によるテンプレート生成ではなく、IntelliJ IDEA のウィザードから「AWS Serverless Application」を生成した場合、自動的にローカル環境での実行・デバッグ用の実行構成が設定されています。

    クリックすると拡大します

    ただし、これには、まだ不足している情報があります。引数と AWS 環境への接続情報です。ローカル環境での実行・デバッグを行うためにはこれらの情報の設定が必要です。この手順は前述したものとまったく同じです。

    [追加の設定作業]
    以降のローカルデバッグで利用するデバッガプロセスの設定を追加で用意しておきましょう。

    先ほど利用した「実行/デバッグ構成」ダイアログで「リモート JVM デバッグ」を追加作成します。
    名前を設定し (イメージでは SAM Debugger としています)、ポートを「62839」とします。

    この リモート JVM デバッグ構成は後ほど利用します。

    クリックすると拡大します

    ローカルでのテスト実行・デバッグ

    ローカル環境で Docker Desktop が起動していることを確認します。

    ツール上部の「デバッグ」ボタンを押すと、デバッグモードの実行が開始されます。ブレークポイントを設定していれば、そこで停止し、変数値を確認することができます。

    クリックすると拡大します

    [注意]

    AWS Toolkit for IntelliJ で用意されているローカル実行/デバッグ構成では sam local invoke として起動されます。本記事の執筆時点では、sam local start-api のための構成を作ることができません (Issue)。 API としてのローカル実行・デバッグを行いたい場合は、以下の手順を行います。

    Start-API によるローカル実行

    ターミナルで template.yaml があるディレクトリから以下のコマンドでローカル実行を起動します。

    sam build
    sam local start-api

    別のターミナルから curl コマンドでAPI 呼び出しをテストします。以下はその一例です。

    curl http://127.0.0.1:3000/hello

    テスト実行を終えたら、最初のターミナルで CTRL+C を押してプロセスを止めます。

    Start-API のローカルデバッグ

    ターミナルで template.yaml があるディレクトリから以下のコマンドでローカル実行を起動します。

    sam build
    sam local start-api --debug-port 62839 

    別のターミナルから curl コマンドでAPI 呼び出しをテストします。以下はその一例です。

    sam build
    sam local start-api --debug-port 62839 
    curl http://127.0.0.1:3000/hello 

    これで API 経由の Lambda プロセスが起動状態になり、サーバー処理の応答待ち状態になります。

    この状態で、前述の 追加の設定作業 で準備した リモート JVM デバッグ を起動します。

    これによって、実行中のローカル Lambda 関数にデバッガプロセスが接続します。ブレークポイントを設定していれば、そこで一時停止し、変数値の確認などが可能です。

ローカル環境での繰り返しの実行テストにおける Tips

実際の開発では、コードを修正しては実行結果を確認する、という作業を繰り返します。ちょっとしたコード変更のたびに全体のビルドと実行をするのは時間がかかります。サーバーレスのローカルプロセスを起動したままで、コードファイルを変更・反映させることで、このサイクルを簡略化する Tips をご紹介します。

1. ローカル・プロセスの実行

まずは、ターミナルから、テスト対象としたいプロジェクトの template.yaml があるディレクトリ (前述の例では sample-java または HelloWorldFunction) に移動し、ビルドとローカルでの API 実行を行います。

実際の開発では、コードを修正しては実行結果を確認する、という作業を繰り返します。ちょっとしたコード変更のたびに全体のビルドと実行をするのは時間がかかります。サーバーレスのローカルプロセスを起動したままで、コードファイルを変更・反映させることで、このサイクルを簡略化する Tips をご紹介します。

まずは、ターミナルから、テスト対象としたいプロジェクトの template.yaml があるディレクトリ (前述の例では sample-java または HelloWorldFunction) に移動し、ビルドとローカルでの API 実行を行います。

sam build
...(中略)
sam local start-api

これで、curl コマンドなどで実行テストができるようになります (例: curl http://127.0.0.1:3000/hello)。このときに呼び出される実際の実行ファイルは .aws-sam/build/<<FunctionResourceName>> 配下に配置されています。

2. コンパイル出力先ファイルの同期化

Python や Node.js などのスクリプト言語の場合、繰り返しの修正作業は .aws-sam/build/<<FunctionResourceName>> 配下のコードファイル (app.py など) に対して直接行います。“sam local start-api“ のプロセスが動いている間、再度 curl コマンドを実行すれば、その反映を確認できます。最終的な変更はプロジェクト側の本来のファイル (hello_world/app.py など) に適用することは忘れないでください。

クリックすると拡大します

Java などのコンパイル型の言語の場合、開発ツールでコンパイルした先の出力ファイルを .aws-sam/build/<<FunctionResourceName>> に同期させるように設定します。これにより、その後のテスト実行 (例: curl http://127.0.0.1:3000/hello) で、Java コードの変更の反映をすぐに確認できます。

同期化は、具体的には、出力先フォルダをリンクさせる方法や curl コマンドの呼び出し前にファイルを都度コピーする方法などになります。

以下では、それを実行するコマンドの一例を示します。なお、出力先フォルダの位置は、ツールやプロジェクトの設定によっては異なる場合があります。

  • Mac の場合
  • # Use this script at the project root (where template.yaml exists)
    # Set appropriate FunctionResourceName
    export FunctionResourceName=HelloWorldFunction
    
    # Set auto build output directory 
    # export JavaOutputDir=$FunctionResourceName/target/classes # for Maven
    # export JavaOutputDir=$FunctionResourceName/bin/main       # for Gradle/VS Code
    # export JavaOutputDir=$FunctionResourceName/build/classes/java/main   # for Gradle
    export JavaOutputDir=$FunctionResourceName/target/classes
    
    ln -s `pwd`/.aws-sam/build/$FunctionResourceName $JavaOutputDir

    リンクさせるのではなく、ファイルコピーを行う場合は、最後の一行を以下にして、curl 実行前に都度実行するようにします。

    cp -rf $JavaOutputDir/* .aws-sam/build/$FunctionResourceName
  • Windows の場合
  • rem Use this script at the project root (where template.yaml exists)
    rem Set appropriate FunctionResourceName 
    set FunctionResourceName=HelloWorldFunction
    
    rem Set auto build output directory
    rem For Maven
    rem set JavaOutputDir=%FunctionResourceName%¥target¥classes
    rem For Gradle/VS Code
    rem set JavaOutputDir=%FunctionResourceName%¥bin¥main
    rem For Gradle
    rem set JavaOutputDir=%FunctionResourceName%¥build¥classes¥java¥main
    set JavaOutputDir=%FunctionResourceName%¥target¥classes
     
    mklink %JavaOutputDir% .aws-sam¥build¥%FunctionResourceName%

    mklink は管理者として実行することが必要です。これが難しい場合は、最後の一行を変えて、curl 実行前に都度実行するようにします。

    xcopy /e /y %JavaOutputDir%¥* .aws-sam¥build¥%FunctionResourceName%

3. 繰り返しの実行テスト

sam local start-api のプロセスを起動したままで、リンク先の Function コードの直接編集、または、変更の反映を行うことで、以降の curl コマンドによるテスト実行では変更されたコードの反映を確認できます。

この手法によって、繰り返しの sam コマンドによるビルドと起動の時間を省略しながら、コードの変更内容の確認テストを行うことができます。

Lambda / API Gateway 以外の AWS サービスを利用する場合は

サーバーレスアプリケーションは Lambda と API Gateway だけで成り立つものではありません。DB などのコンポーネントも必要になります。本ドキュメントでは詳しくは触れませんが、ローカル環境で開発・動作確認を支援する機能として以下のようなものがあります。


まとめ

代表的な開発ツールを例に、ローカル開発環境での Lambda 関数の開発とデバッグの手順を紹介しました。この作業を一定レベルまで完了したら、次はクラウドと連携したテストや本番展開です。次回 はその手順を紹介します。

この連載記事のその他の記事はこちら

選択
  • 選択
  • サーバーレスのローカル開発環境を整備する ~前編
  • サーバーレスのローカル開発環境を整備する ~中編
  • サーバーレスのローカル開発環境を整備する ~後編

builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます


筆者プロフィール

杉 達也
アマゾン ウェブ サービス ジャパン合同会社
シニア サーバーレススペシャリスト 事業開発マネージャ

Serverless Specialist / BD として AWS Japan に勤務。
サーバーやインフラのことをあまり考えたくない、気にしたくないので、サーバーレスは魅力的です。サイジングやキャパシティプランニング作業からも開放されます。
早く、サーバーレスの世界を体験してもらいたい、そう思いつつ、日々その伝え方を考えています。

さらに最新記事・デベロッパー向けイベントを検索

下記の項目で絞り込む
1

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する