🐡

AWS SAMを使ってみる(nodejs TypeScript版)

2022/03/12に公開

概要

AWS のサーバレスアプリケーション開発ツールである SAM(AWS Serverless Application Model)を導入して使用してみます。
公式手順などでは、ランタイム環境は Python となっていますが、Node.js の TypeScript(パブリックプレビュー中)プロジェクトを作成してみます。

AWS SAM インストール

AWS SAM のインストールは、公式手順を参照して行ってください。
AWS の CLI を使うための IAM で必要な設定が必要になります。また、ローカル環境で動作確認する場合、オプションで Docker のインストールを行います。
既に AWS CLI や Docker を使用している場合は、SAM のインストールのみで大丈夫です。
基本的には、AWS 公式の手順どおり操作する形で問題ないかと思います。

Linux 版インストール手順(公式)

Windows 版インストール手順(公式)

MacOS 版インストール手順(公式)

AWS CLI の認証情報設定

AWS CLI の認証情報が未設定の場合は、設定します。

AWS CLI 認証情報設定手順(公式)

AWS CLI の認証情報が未設定だと、sam buildで失敗しますので注意してください。

SAM プロジェクトの作成

SAM プロジェクトを作成します。今回はホームディレクトリ直下に作成します。
sam init中にプロジェクト名を聞かれ、それがフォルダ名になりますので、ホームディレクトリ上で実行します。

shell
cd ~
sam init --runtime nodejs14.x

今回は--runtime nodejs14.xで node.js の 14 をオプションで選択しています。
使用できるランタイムオプションは、以下から確認が出来ます。

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-init.html

対話方式で聞かれるので順に答えて行きます。

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

今回は、1 - AWS Quick Start Templatesを選択します。

shell
Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - Multi-step workflow
	3 - Standalone function
	4 - Scheduled task
	5 - Data processing
	6 - Serverless API

Quick Start application templateに出てくる内容はランタイムによって変わるようです。
今回は、1 - Hello World Exampleを選択します。

shell
Select your starter template
	1 - Hello World Example
	2 - Hello World Example TypeScript

Node.jsを選択した場合、TypeScript を使用したテンプレートにするかを聞かれます。
今回は、2 - Hello World Example TypeScriptを選択してみます。

shell
Project name [sam-app]:

プロジェクト名を設定します。今回はデフォルトのsam-appで作成します。
以上で、次のような形でプロジェクトフォルダが展開されます。

.
|-- .gitignore
|-- README.md
|-- events
|   `-- event.json
|-- hello-world
|   |-- .eslintignore
|   |-- .eslintrc.js
|   |-- .npmignore
|   |-- .prettierrc.js
|   |-- app.ts  : Lambda handlerのロジックが含まれます。
|   |-- jest.config.ts
|   |-- package.json  :アプリケーションの依存ライブラリが定義されています。sam buildで使用されます。
|   |-- tests
|   |   `-- unit
|   |       `-- test-handler.test.ts
|   `-- tsconfig.json
`-- template.yaml  : AWSリソースに関する定義が含まれます。

テストコードの配置構成などディレクトリ構成はランタイムによって異なります。

ビルドの実行

以下のコマンドでビルドを実行します。

shell
sam build

パブリックプレビュー中なので以下のように聞かれます。

shell
You can also enable this beta feature with 'sam build --beta-features'. [y/N]:

yを選択して次に進むとビルドが実行されます。
ビルドを実行すると次のようなパスにファイルが生成されます。

.
|-- .aws-sam
|   |-- build
|   |   |-- HelloWorldFunction
|   |   |   |-- app.js
|   |   |   `-- app.js.map
|   |   `-- template.yaml
|   `-- build.toml

ローカル環境での開発環境準備

関数が配置されているディレクトリ配下に依存モジュールを定義したファイル(例:hello-world/package.json)が生成されていますが、このままだと依存ライブラリが存在せず、IDE で参照エラーになるなど、問題がありますので、関数のディレクトリ配下でnpm installを実行し、依存モジュールをインストールしておきます。

shell
cd hello-world
npm install

ローカル環境での動作確認(関数)

関数をローカル環境で確認する場合、以下のコマンドを実行します。

shell
sam local invoke

実行すると Docker で実行環境イメージ呼び出され、関数が実行されます。

関数実行結果

{ "statusCode": 200, "body": "{\"message\":\"hello world\"}" }

この際に、デフォルトではeventの中身がない状態で関数が呼び出されますが、以下のように、event オブジェクトを定義した json ファイルを-eオプションで指定することで、テストデータなどを指定して関数が実行できます。

shell
sam local invoke -e events/event.json

ローカル環境での動作確認(APIGateway)

APIGateway 経由での動作をローカル環境で確認する場合、以下のコマンドでローカルで API を起動できます。

shell
sam local start-api

以下のような URL にアクセスすることで、動作を確認できます。

shell
http://127.0.0.1:3000/hello

確認を終了したら、Ctrl+Cなどで停止します。

デプロイの実行

次のコマンドを実行しデプロイを開始します。

shell
sam deploy --guided

対話式で聞かれるので、回答していきます。

shell
Stack Name [sam-app]:

CloudFormationスタックの名前を指定します。
デフォルトのプロジェクト名と同名のままEnterでよいかと思います。

shell
AWS Region [ap-northeast-1]:

リージョンを聞かれます。AWSCLI の認証情報で設定しているリージョンがデフォルトになっています。今回はデフォルトのままEnterします。

shell
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]:

yを入力し Enterします。

shell
#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]:

実行用の IAM ロールを作成するか聞かれます。
Yを入力し Enterします。

shell
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]:

リソースのプロビジョニングに失敗した場合、元の状態にロールバックするか聞かれます。
yを入力し Enterします。

shell
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]:

認証が設定されていない機能だけれど問題ないかを聞かれます。(パブリックからアクセスが可能となるため)
yを入力し Enterします。

shell
Save arguments to configuration file [Y/n]:

今回入力した値を設定ファイルに保存するかを聞かれます。
Yを入力し Enterします。

shell
SAM configuration file [samconfig.toml]:

保存する設定ファイル名を入力します。デフォルトはsamconfig.tomlとなります。
今回はそのままEnterを押下します。

shell
SAM configuration environment [default]:

SAM の設定については、環境ごとに分けて設定できるようになっていて、この設定に応じて、samconfig.tomlに、[default.deploy.parameters]text.deploy.parameters]のようにパラメータを分けて設定されます。

deploy を実行するときに、--config-envオプションを指定することでdefault以外の deploy が実行できます。また、--config-fileオプションで、使用する toml ファイルを切り替えることができます。

今回は、default のままEnterを押下します。

shell
Deploy this changeset? [y/N]:

yを入力し Enterします。
リソースのプロビジョニング及び、関数のデプロイが実行されます。

コンソールに、Outputsで配置されたリソースが表示されます。

CloudFormation outputs from deployed stack
-------------------------------------------------------------------------------------------------------------------------------
Outputs
-------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::<ACCOUNT ID>role/sam-app-HelloWorldFunctionRole-UZPLZBVT71MY

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:<ACCOUNT ID>:function:sam-app-HelloWorldFunction-xxxxxxxxxx
-------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

SAM の Deploy を実行することで以下のようなリソースが AWS 上に作成されました。

  • IAM Role : 関数の実行ロール。sam-app-HelloWorldFunctionRole-xxxxxxxxのような名前で作成されます。xxxxxxxxの部分には、自動生成されたハッシュ値が設定されます。
  • API Gateway : 関数を呼び出す APIGateway。sam-appの名称で作成されている。
  • Lambda 関数:sam-app-HelloWorldFunction-xxxxxxxxのような名前で lambda 関数が作成されます。xxxxxxxxの部分には、自動生成されたハッシュ値が設定されます。
  • CloudFormation スタック:構築したリソースを管理しているスタック。Stack Name [sam-app]:で設定した名前で作成されます。削除すると作成したリソース類も削除されます。

なお、2 回目以降のデプロイは、--guidedオプションなしで実行できます。

shell
sam deploy

動作確認

SAM の deploy 時にコンソールに表示された、API Gateway endpoint URLvalue値を確認するか、AWS コンソールから、作成された APIGateway の URL を確認し、ブラウザでアクセスします。

作成される URL の例

https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello

レスポンス

{ "message": "hello world" }

正常に API がデプロイできたことが確認できました。

リソースの削除

AWS へのデプロイおよび動作確認までできたので最後にリソースを削除します。
AWS SAM でのリソース作成は CloudFormation スタックで作成されているため、スタックを削除することで紐づくリソースを削除することができますが、SAM でプロジェクトフォルダで以下を実行することで、リソースを削除することができます。

sam delete

IAM ロール、API Gateway、Lambda 関数が削除されます。

まとめ

AWS SAM を用いることで、ローカル環境/コマンドラインからの操作で、関数の作成、ローカル環境での動作確認、AWS 環境へのデプロイなどを、シンプルな操作で行うことができます。

サーバレス開発の生産性を高めながらプロジェクトを進めていく上では、必要な技術になってくるかと思います。

次回、ローカル DynamoDB と連携した開発環境なども試してみたいと思います。

株式会社トッカシステムズ

Discussion