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

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

Author : 杉 達也

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

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

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

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

各開発ツール環境 (Visual Studio Code や Eclipse) で上記設定が完了していれば、ツール上のメニューから SAM アプリケーションの開発をスタートできます。

Visual Studio Code の場合

Eclipse の場合

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

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

Template Java .NET Go Node.js Python Ruby Rust サーバーレスパターンの関連するケース コメント
VS Code SAM CLI テンプレートの一部と同じ。コメント部の appTemplate で判別可能。
SAM Hello World 11, 8 6, 3.1 1.x 16, 14, 12 3.9, 3.8, 3.7     (シンプルな API) hello-world
SAM CLI -1 と同じ
EventBridge Hello World     1.x   3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント eventbridge-hello-app
SAM CLI -7 のうちの一つ
EventBridge App From Scracth     1.x   3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント eventbridge-scheme-app
SAM CLI -7 のうちの一つ
Step Functions Sample 11, 8 6, 3.1 1.x 16, 14, 12 3.9, 3.8, 3.7     アプリケーションフロー処理 step-functions-sample-app
SAM CLI -2 と同じ
App Backend using TypeScript       12         quick-start-typescript-app
Eclipse 注: Eclipse 2021-12 以前でのみ機能します
article x             動的 Web / モバイルバックエンド  
hello-world x             (単独のLambda関数)  
recognition x             画像処理 / シンプルなデータ加工  
SAM CLI useCaseName で判別可能。
1 - Hello World Example 17, 11, 8 7, 6, 5, 3.1 1.x 18, 16, 14, 12 3.9, 3.8, 3.7 2.7 x (シンプルな API)  
2 - Multi-step workflow 11, 8 6, 3.1 1.x 18, 16, 14, 12 3.9, 3.8, 3.7 2.7   アプリケーションフロー処理  
3 - Serverless API   6, 3.1   18, 16, 14, 12       動的 Web / モバイルバックエンド  
4 - Scheduled task   6, 3.1   18, 16, 14, 12       スケジュール・ジョブ  
5 - Standalone function   6, 3.1   18, 16, 14, 12       (単独のLambda関数)  
6 - Data processing   6, 3.1   18, 16, 14, 12       シンプルなデータ加工、イベント駆動の業務処理連携  
7 - Infrastructure event management 11, 8   1.x   3.9, 3.8, 3.7     スケジュール・ジョブ/SaaSイベント  
8 - Serverless Connector Hello World Example       16, 14, 12 3.9, 3.8, 3.7       SAM Connector 利用のサンプル
9 - Multi-step workflow with Connectors       16, 14, 12 3.9, 3.8, 3.7       SAM Connector 利用のサンプル
10 - Lambda EFS example         3.9, 3.8       EFS 利用サンプル
11 - Machine Learning         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 - Multi-step workflow
    3 - Serverless API
    4 - Scheduled task
    5 - Standalone function
    6 - Data processing
    7 - Infrastructure event management
    8 - Serverless Connector Hello World Example
    9 - Multi-step workflow with Connectors
    10 - Lambda EFS example
    11 - 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 - dotnet6
    2 - dotnet5.0
    3 - dotnetcore3.1
    4 - go1.x
    5 - graalvm.java11 (provided.al2)
    6 - graalvm.java17 (provided.al2)
    7 - java11
    8 - java8.al2
    9 - java8
    10 - nodejs16.x
    11 - nodejs14.x
    12 - nodejs12.x
    13 - python3.9
    14 - python3.8
    15 - python3.7
    16 - ruby2.7
    17 - 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

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: java11
    Architectures: x86_64
    Dependency Manager: maven
    Application Template: hello-world
    Output Directory: .
    
    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
- template.yaml ← SAM テンプレートファイル

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

ここでは、Visual Studio Code および 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 プロジェクトを対象とした記述をしています。

  • 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 部分に指定します。

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

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

    この情報は、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
  • 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 関数のデバッグ構成 : Eclipse のデバッグパネルで対象の Lambda 関数が起動してることを確認したら、起動構成パネルのデバッグ構成から、前述の「追加の設定作業」で追加した リモート Java アプリケーション構成 (SAM Debugger) の「デバッグ」を実行します。

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

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

    API 経由の Lambda 関数のデバッグ : Eclipse のデバッグパネルで対象の Lambda 関数が起動してることを確認したら、ターミナルから API コールを行います (例 : curl http://127.0.0.1:3000/hello)。これで API 経由の Lambda プロセスが起動状態になります。

    ターミナルではレスポンス待ちの状態になりますが、この状態で、Eclipse の起動構成パネルのデバッグ構成から リモート Java アプリケーションの「デバッグ」を実行します。これによって、実行中のローカル Lambda 関数にデバッガプロセスが接続します。ブレークポイントを設定していれば、そこで一時停止し、変数値の確認などが可能です。

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

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

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

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

ローカル環境での繰り返しの実行テスト

実際の開発では、コードを修正しては実行結果を確認する、という作業を繰り返します。ちょっとしたコード変更のたびにビルドと実行をするのは時間がかかります。これを簡略化するやり方をご紹介します。

まずは、ターミナルから、テスト対象としたいプロジェクトの 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>> 配下に配置されています。

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

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

Java などのコンパイル型の言語の場合、開発ツールがコンパイルする先の出力ディレクトリを .aws-sam/build/<<FunctionResourceName>> にリンクにします。

  • Mac の場合
  • export FuncitonResourceName=HelloWorldFunction
    echo set appropriate FolderName. FolderName=., or something
    export FolderName=HelloWorldFunction
    
    mv -f $FolderName/target/classes $FolderName/target/classes_bak
    ln -s `pwd`/.aws-sam/build/$FuncitonResourceName $FolderName/target/classes
  • Windows の場合
  • mklink は管理者として実行することが必要です。

    set FuncitonResourceName=HelloWorldFunction
    echo set appropriate FolderName. FolderName=., or something
    set FolderName=HelloWorldFuncton
     
    rename %FolderName%¥target¥classes %FolderName%¥target¥classes_bak
    mklink %FolderName%¥target¥classes .aws-sam¥build¥%FuncitonResourceName%

これにより、開発ツールでの編集内容がそのまま実行時のコンパイル済ファイルとして利用されることになるため、以降の curl コマンドのテスト実行結果に反映されます。

一連の編集とテストを終えたら、リンクを解除して元に戻しておくことをお勧めします。

  • Mac の場合
  • set FuncitonResourceName=HelloWorldFunction
    echo set appropriate FolderName. FolderName=., or something
    set FolderName=HelloWorldFuncton
     
    rename %FolderName%¥target¥classes %FolderName%¥target¥classes_bak
    mklink %FolderName%¥target¥classes .aws-sam¥build¥%FuncitonResourceName%
    export FolderName=HelloWorldFunction
    unlink $FolderName/target/classes
  • Windows の場合
  • set FolderName=HelloWorldFunction
    rmdir %FolderName%¥target¥classes

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

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


まとめ

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

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

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

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


筆者プロフィール

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

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

AWS のベストプラクティスを毎月無料でお試しいただけます

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

下記の項目で絞り込む
1

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

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