AWS SAMでAPI Gateway+Lambdaの環境を構築

2023/02/03に公開

AWS SAMとは❓

  • AWS SAM とは Lambda や API Gateway などの AWS リソースをデプロイするツールです。
  • AWS SAM は AWS が公式で提供しています。
  • AWS SAM は AWS Serverless Application Model の略です。
  • AWS SAM の公式製品サイトはこちらです。
  • AWS SAM の公式開発者ドキュメントはこちらです。

インストール

AWS SAM を利用するために以下を準備します。

AWS CLIのインストール

AWS CLI を brew でインストールします。

コマンド
$ brew install awscli

実行結果
実行結果
==> Fetching awscli
==> Downloading https://ghcr.io/v2/homebrew/core/awscli/manifests/2.9.19
==> Downloading https://ghcr.io/v2/homebrew/core/awscli/blobs/sha256:1988ece041f54c082c1b46a2a7afbbd08e099213648d6e01b0735a2c943fac21
==> Pouring awscli--2.9.19.monterey.bottle.tar.gz
==> Caveats
The "examples" directory has been installed to:
  /usr/local/share/awscli/examples

zsh completions and functions have been installed to:
  /usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/awscli/2.9.19: 13,169 files, 114.7MB
==> Running `brew cleanup awscli`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

インストール後にバージョン確認で動作を確認します。

コマンド
$ aws --version

実行結果
実行結果
aws-cli/2.9.19 Python/3.11.1 Darwin/21.6.0 source/x86_64 prompt/off

Dockerのインストール

Docker をインストールするには、Docker Desktop をインストールする必要があります。
こちらのサイトでインストールしてください。

インストール後にバージョン確認で動作を確認します。

コマンド
$ docker --version

実行結果
実行結果
Docker version 20.10.14, build a224086

SAMのインストール

SAM をインストールするには、AWS CLI をインストールする必要があります。

コマンド
$ brew install aws-sam-cli

バージョンの確認します。

コマンド
$ sam --version

実行結果
実行結果
SAM CLI, version 1.71.0

SAMプロジェクトの作成

sam init コマンドを使用して、AWS SAM プロジェクトを作成します。

コマンド
$ sam init --runtime nodejs16.x --dependency-manager npm --name sam-apigateway-lambda

実行結果
実行結果
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 - Standalone function
	4 - Scheduled task
	5 - Data processing
	6 - Serverless API
	7 - Serverless Connector Hello World Example
	8 - Multi-step workflow with Connectors
Template: 1

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Select your starter template
	1 - Hello World Example
	2 - Hello World Example TypeScript
	3 - Hello World Example TypeScript w/ Lambda Powertools
Template: 2

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/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]:

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

    -----------------------
    Generating application:
    -----------------------
    Name: sam-apigateway-lambda
    Runtime: nodejs16.x
    Architectures: x86_64
    Dependency Manager: npm
    Application Template: hello-world-typescript
    Output Directory: .

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


Commands you can use next
=========================
[*] Create pipeline: cd sam-apigateway-lambda && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-apigateway-lambda && sam validate
[*] Test Function in the Cloud: cd sam-apigateway-lambda && sam sync --stack-name {stack-name} --watch

生成されたディレクトリ構成を確認してみます。

コマンド
$ cd sam-apigateway-lambda
$ tree -a

実行結果
実行結果
.
├── .gitignore
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── .eslintignore
│   ├── .eslintrc.js
│   ├── .npmignore
│   ├── .prettierrc.js
│   ├── app.ts
│   ├── jest.config.ts
│   ├── package.json
│   ├── tests
│   │   └── unit
│   │       └── test-handler.test.ts
│   └── tsconfig.json
└── template.yaml

5 directories, 13 files

ビルド

yarn コマンドで依存関係をインストールします。

コマンド
$ cd hello-world
$ yarn
  • sam build コマンドを実行することで、サーバーレスアプリケーションを構築します。
  • sam build によるビルドは、アプリケーションのローカルテスト、または AWS へのデプロイを行うための事前準備として行います。
コマンド
$ cd ..
$ sam build

実行結果
実行結果
Building codeuri: /Users/hayato94087/Work/sam-apigateway-lambda/hello-world runtime: nodejs16.x metadata: {'BuildMethod': 'esbuild', 'BuildProperties': {'Minify': True, 'Target': 'es2020', 'EntryPoints': ['app.ts']}} architecture: x86_64 functions: HelloWorldFunction
Running NodejsNpmEsbuildBuilder:CopySource
Running NodejsNpmEsbuildBuilder:NpmInstall
Running NodejsNpmEsbuildBuilder:EsbuildBundle

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided

テンプレートの検証

SAM のテンプレート(template.yaml)の検証します。

コマンド
$ sam validate

実行結果
実行結果
2023-02-03 14:58:56 Loading policies from IAM...
2023-02-03 14:59:03 Finished loading policies from IAM.
/Users/hayato94087/Work/sam-apigateway-lambda/template.yaml is a valid SAM Template. This is according to basic SAM Validation, for additional validation, please run with "--lint" option

Lambda関数のローカル実行

lambda 関数をローカルで実行します。

コマンド
$ sam local invoke

実行結果
実行結果
Invoking app.lambdaHandler (nodejs16.x)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/nodejs:16-rapid-x86_64.

Mounting /Users/hayato94087/Work/sam-apigateway-lambda/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
END RequestId: 50c5f12f-5df5-45a8-bfe0-3a8be684b326
REPORT RequestId: 50c5f12f-5df5-45a8-bfe0-3a8be684b326	Init Duration: 0.16 ms	Duration: 104.29 ms	Billed Duration: 105 ms	Memory Size: 128 MB	Max Memory Used: 128 MB
{"statusCode":200,"body":"{\"message\":\"hello world\"}"}%

API Gatewayのローカル実行

SAM のテンプレート(template.yaml)に記載された API Gateway のローカル実行します。

コマンド
$ sam local start-api

実行結果
実行結果
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
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. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
2023-02-03 14:59:46  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

動作の確認します。

コマンド
$ curl http://127.0.0.1:3000/hello

実行結果
実行結果
{"message":"hello world"}%

AWSへのデプロイ

sam deploy を実行し、AWS へのデプロイを行います。

コマンド
$ 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]: y
	#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]:
	#Preserves the state of previously provisioned resources when an operation fails
	Disable rollback [y/N]:
	HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
	Save arguments to configuration file [Y/n]:
	SAM configuration file [samconfig.toml]:
	SAM configuration environment [default]:

	Looking for resources needed for deployment:
	 Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1krw7zbmgxk32
	 A different default S3 bucket can be set in samconfig.toml

	Saved arguments to config file
	Running 'sam deploy' for future deployments will use the parameters saved above.
	The above parameters can be changed by modifying samconfig.toml
	Learn more about samconfig.toml syntax at
	https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

Uploading to sam-app/7b33e513850748d9482c8e504aacefb2  533 / 533  (100.00%)

	Deploying with following values
	===============================
	Stack name                   : sam-app
	Region                       : ap-northeast-1
	Confirm changeset            : True
	Disable rollback             : False
	Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-1krw7zbmgxk32
	Capabilities                 : ["CAPABILITY_IAM"]
	Parameter overrides          : {}
	Signing Profiles             : {}

Initiating deployment
=====================
Uploading to sam-app/a6f0b3d35a576c63403af6c9d8e4c9f9.template  1378 / 1378  (100.00%)

Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                                     LogicalResourceId                             ResourceType                                  Replacement
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                         HelloWorldFunctionHelloWorldPermissionProd    AWS::Lambda::Permission                       N/A
+ Add                                         HelloWorldFunctionRole                        AWS::IAM::Role                                N/A
+ Add                                         HelloWorldFunction                            AWS::Lambda::Function                         N/A
+ Add                                         ServerlessRestApiDeployment47fc2d5f9d         AWS::ApiGateway::Deployment                   N/A
+ Add                                         ServerlessRestApiProdStage                    AWS::ApiGateway::Stage                        N/A
+ Add                                         ServerlessRestApi                             AWS::ApiGateway::RestApi                      N/A
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/samcli-deploy1675404184/2b7ca802-d201-4af8-a3de-d7021b981f4c


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2023-02-03 15:03:19 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 0.5 seconds)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                                ResourceType                                  LogicalResourceId                             ResourceStatusReason
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                            AWS::CloudFormation::Stack                    sam-app                                       User Initiated
CREATE_IN_PROGRESS                            AWS::IAM::Role                                HelloWorldFunctionRole                        -
CREATE_IN_PROGRESS                            AWS::IAM::Role                                HelloWorldFunctionRole                        Did not have IAM permissions to process
                                                                                                                                          tags on AWS::IAM::Role resource.
CREATE_IN_PROGRESS                            AWS::IAM::Role                                HelloWorldFunctionRole                        Resource creation Initiated
CREATE_COMPLETE                               AWS::IAM::Role                                HelloWorldFunctionRole                        -
CREATE_IN_PROGRESS                            AWS::Lambda::Function                         HelloWorldFunction                            -
CREATE_IN_PROGRESS                            AWS::Lambda::Function                         HelloWorldFunction                            Resource creation Initiated
CREATE_COMPLETE                               AWS::Lambda::Function                         HelloWorldFunction                            -
CREATE_IN_PROGRESS                            AWS::ApiGateway::RestApi                      ServerlessRestApi                             -
CREATE_IN_PROGRESS                            AWS::ApiGateway::RestApi                      ServerlessRestApi                             Resource creation Initiated
CREATE_COMPLETE                               AWS::ApiGateway::RestApi                      ServerlessRestApi                             -
CREATE_IN_PROGRESS                            AWS::Lambda::Permission                       HelloWorldFunctionHelloWorldPermissionProd    -
CREATE_IN_PROGRESS                            AWS::ApiGateway::Deployment                   ServerlessRestApiDeployment47fc2d5f9d         -
CREATE_IN_PROGRESS                            AWS::Lambda::Permission                       HelloWorldFunctionHelloWorldPermissionProd    Resource creation Initiated
CREATE_IN_PROGRESS                            AWS::ApiGateway::Deployment                   ServerlessRestApiDeployment47fc2d5f9d         Resource creation Initiated
CREATE_COMPLETE                               AWS::ApiGateway::Deployment                   ServerlessRestApiDeployment47fc2d5f9d         -
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                       HelloWorldFunctionHelloWorldPermissionProd    -
CREATE_COMPLETE                               AWS::CloudFormation::Stack                    sam-app                                       -
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::123456789012:role/sam-app-HelloWorldFunctionRole-5U9LENUAJGAD

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://w23jo0zice.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:123456789012:function:sam-app-HelloWorldFunction-sCsyqvNmWpVl
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

動作の確認をします。

コマンド
$ curl https://w23jo0zice.execute-api.ap-northeast-1.amazonaws.com/Prod/hello

実行結果
実行結果
{"message":"hello world"}%

削除

  • AWS CloudFormation に作成された Stack を削除し、AWS リソースを一括削除します。
  • Amazon S3 に保存されたアーティファクトを削除します。
コマンド
$ sam delete --stack-name sam-app

実行結果
実行結果
	Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y
	Are you sure you want to delete the folder sam-app in S3 which contains the artifacts? [y/N]: y
	- Deleting S3 object with key sam-app/7b33e513850748d9482c8e504aacefb2
	- Deleting S3 object with key sam-app/a6f0b3d35a576c63403af6c9d8e4c9f9.template
	- Deleting Cloudformation stack sam-app

Deleted successfully

ヘルプ

ヘルプを表示する。

コマンド
$ sam --help

実行結果
実行結果
Usage: sam [OPTIONS] COMMAND [ARGS]...

  AWS Serverless Application Model (SAM) CLI

  The AWS Serverless Application Model extends AWS CloudFormation to provide a
  simplified way of defining the Amazon API Gateway APIs, AWS Lambda
  functions, and Amazon DynamoDB tables needed by your serverless application.
  You can find more in-depth guide about the SAM specification here:
  https://github.com/awslabs/serverless-application-model.

Options:
  --debug     Turn on debug logging to print debug message generated by SAM
              CLI and display timestamps.
  --version   Show the version and exit.
  --info
  -h, --help  Show this message and exit.

Commands:
  init      Init an AWS SAM application.
  validate  Validate an AWS SAM template.
  build     Build your Lambda function code
  local     Run your Serverless application locally for quick development...
  package   Package an AWS SAM application.
  deploy    Deploy an AWS SAM application.
  delete    Delete an AWS SAM application and the artifacts created by sam
            deploy.
  logs      Fetch logs for a function
  publish   Publish a packaged AWS SAM template to the AWS Serverless
            Application Repository.
  traces    Fetch AWS X-Ray traces
  sync      Sync a project to AWS

Discussion