概要
今回は前回紹介したAWS LambdaのAWS サーバーレスアプリケーションモデル (Serverless Application Model)、AWS SAMの続編になります。
【前回の記事】
AWS Lambda SAMとは?~Cloud9でSAM Sampleを使ってPythonのLambdaプログラムを簡単にデプロイする~
SAMの便利さは前回の記事でなんとなくわかったと思うので今回からはより実践編です。
実際にSAMを使ってAWSのサービスを連携させてみようという内容です。
第一回は、Lambda × APIGateway 編にしました。
この投稿を最後まで実行すると以下の図のようなAWSサービスで構築したWebAPI環境が、なんと2ファイル30ラインほどで完成します。
理解しやすいように最もシンプルな記載例としてファイルサンプルを作成したので実際に作ったファイルを見るとこんなに簡単なのかを思えると思います。
実はSAMリポジトリという以下のURLにサンプルアプリケーションはたくさんあるのですが、なかなか初見では理解しにくいものが多いので今回は最もシンプルな記載例に心掛けています。
想定読者
- Lambda × APIGateway でAPIサービスを作りたい人
- LambdaでSAMを使ってみたい人
- Lambdaの知識をレベルアップしたい人
作業時間
- 15分(Cloud9などSAMの環境作成除く(^^;))
参考書籍
ほぼほぼこの本を参考にさせて頂きました。
Lambdaに特化した本はあまりないので現時点で唯一の専門書と思います。
Lambdaを勉強するなら誰でもまずこの本から勉強するのではないかと思える代表的な本になっていると思います。
Lambdaの良書が増えてきたので、おすすめ本5冊を以下で紹介しています。Lambdaについて本格的に勉強したい方はぜひ読んでみてください。
目次
- SAM環境(Cloud9環境)準備
- Lambda × APIGateway テンプレートファイル作成
- Lambda ソースファイル作成
- ビルド
- デプロイ
SAM環境(Cloud9環境)準備
以前の以下の記事を参考にCloud9の環境を作ってください。
ディスク拡張を忘れず(^^;)
AWS Lambda SAMとは?~Cloud9でSAM Sampleを使ってPythonのLambdaプログラムを簡単にデプロイする~
Lambda × APIGateway テンプレートファイル作成
Cloud9環境が作成されたら実際にAWSサービス構築用のファイルを作成していきます。
作成するファイルは2つ(template.yaml/app.py)。最終的には以下のフォルダ構成になるように2ファイル作成してください。
sam-api-sample
│ template.yaml
└─hello_world
app.py
ルートフォルダはsam-api-sampleという名前にしています。こちらのフォルダ名は任意なので必要であれば変えてください。他のフォルダ名/ファイル名を変更する場合、それに伴った設定を変える必要があるので少し慣れてきてからにした方が良いと思います(^^;)
それではまずtemplate.yamlでLambda × APIGateway テンプレートファイル作成します。
ファイル内容は以下の通り。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Sample SAM Template for sam-api-sample
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
記載内容を極力シンプルにしたので定義内容もなんとなくわかると思いますが、
抜粋で記載内容を説明すると、、、
- Timeout: 3(Lambdaの処理タイムアウト3秒)
- CodeUri: hello_world/(Lambdaの実ファイルはhello_worldフォルダにあり)
- Handler: app.lambda_handler(app.pyファイルのlambda_handler関数が呼ばれる)
- Path: /hello(アクセスするときのAPIGatewayのパスは/hello)
- Method: get(HTTP GETメソッドでアクセスする)
ことを定義しています。
これらはもちろんAWSコンソールから設定できるのですが、頻繫に?画面UIが改善されるAWSコンソールをその都度迷いながら設定するよりこのファイル1つで構築できるのSAMの非常に便利なところと思っています。
加えてファイル内容について補足すると、Outputs以降は実際に作成されたLambdaやAPIのURLを出力するようにしていますが、実際にはなくても構いません。そのため、実際に構築に必要な設定は、Outputsの上までなので、なんとたったの24ラインでLambda × APIGateway環境が出来上がります!簡単ですね。
Lambda ソースファイル作成
では、次のファイルapp.pyに移ります。
app.py は、実際にAPIアクセスされたときに実行されるLambda関数になります。
今回は単純なサンプルということで処理の中身はなく、hello worldを返すだけの処理にしています。
たったの5ライン!
上で紹介したフォルダ構成でhello_worldフォルダの下に配置しましょう。
def lambda_handler(event, context):
return {
"statusCode": 200,
"body":"message: hello world",
}
最終的にCloud9環境で見えるフォルダ構成が以下のようになっていれば問題ありません。
ビルド
準備はここまでです。たった2フォルダ/2ファイルで非常に簡単ですね。
それではビルドします。
ルートフォルダsam-api-sampleに移動して、
sam build --use-container
実行しましょう。
このあたりのコマンドは前回の記事に記載しているので必要であれば以下の前回の記事を参照してください。
【前回の記事】
AWS Lambda SAMとは?~Cloud9でSAM Sampleを使ってPythonのLambdaプログラムを簡単にデプロイする~
以下に実際のコマンド実行結果を載せています。
$ cd sam-api-sample
$ sam build --use-container
Starting Build inside a container
Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended.
Building codeuri: /home/ec2-user/environment/Cloud9_SAM/sam-api-sample/hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: ['HelloWorldFunction']
Fetching public.ecr.aws/sam/build-python3.9:latest-x86_64 Docker container image............................................................................................................................................................................................................................................................................................................
Mounting /home/ec2-user/environment/Cloud9_SAM/sam-api-sample/hello_world as /tmp/samcli/source:ro,delegated inside runtime container
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided
requirements.txt file not found. Continuing the build without dependencies.
Running PythonPipBuilder:CopySource
$
ディスク容量が問題なければ無事にビルドできると思います(^^;)
くどいようですが、ディスク容量でエラー(RuntimeError: Container does not exist. Cannot get logs for this container)が出たら前回の記事を参照してください。
【前回の記事】
AWS Lambda SAMとは?~Cloud9でSAM Sampleを使ってPythonのLambdaプログラムを簡単にデプロイする~
デプロイ
続いてデプロイです。
sam deploy --guided --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND
実行しましょう。
$ sam deploy --guided --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: sam-api-sample
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]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: y
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-bncdmvrv3w3n
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-api-sample/1948bce135b64124xd47a657530b44f58 178 / 178 (100.00%)
Deploying with following values
===============================
Stack name : sam-api-sample
Region : ap-northeast-1
Confirm changeset : True
Disable rollback : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-bncxdmvrv3w3n
Capabilities : ["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-api-sample/e7b773fc9b0c22cdxc3f859f9f36ed735.template 1182 / 1182 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add HelloWorldFunctionHelloWorldPermissio AWS::Lambda::Permission N/A
nProd
+ 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:XXXXXXXXXXXX:changeSet/samcli-deployx1657935682/b46c7900-abb9x-4ec1-a2df-1fd2159251ea
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2022-07-16 01:41:37 - Waiting for stack create/update to complete
CloudFormation events from stack operations
-------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole -
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::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissio -
nProd
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissio Resource creation Initiated
nProd
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 HelloWorldFunctionHelloWorldPermissio -
nProd
CREATE_COMPLETE AWS::CloudFormation::Stack sam-api-sample -
-------------------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Key HelloWorldFunctionIamRole
Description Implicit IAM Role created for Hello World function
Value arn:aws:iam::XXXXXXXXXXXX:role/sam-api-sample-HelloWorldFunctionRole-1XVQC0GREGPQ7X
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:sam-api-sample-HelloWorldFunction-1JRYV5PA3BbB
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-api-sample in ap-northeast-1
$
対話型のやり取りになるので以下のように求められた内容に対し回答を入力します。
[] 内に記載されたデフォルトで良ければそのままEnterで大丈夫です。
- Stack Name [sam-app]: sam-api-sample
- AWS Region [ap-northeast-1]:
- Confirm changes before deploy [y/N]: y
- Allow SAM CLI IAM role creation [Y/n]: y
- Disable rollback [y/N]: y
- HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
- Save arguments to configuration file [Y/n]: y
- SAM configuration file [samconfig.toml]:
- SAM configuration environment [default]:
- Deploy this changeset? [y/N]: y
このやり取りは、SAM configuration file [samconfig.toml] に保存されるので、
次回はsam deployというオプション無しの簡単なコマンド実行で大丈夫です。
それではデプロイが問題なく完了したら構築されたAPIGatewayのURLにブラウザでアクセスして動作確認してみます。
アクセス先はデプロイコマンドの最後に出力されている以下のアクセスURLになります。(template.yamlでOutputsに指定した内容になります)
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
問題なく構築出来ていれば、以下の内容がブラウザに表示されるはずです。(app.pyの処理結果です)
以上!非常に簡単だったのではないでしょうか。
これでAWSコンソールの画面UIが変わるたびに設定内容に迷う必要がなくなりました(^^)
まとめ
お疲れ様でした!
今回はLambdaでsamを使ってLambda × APIGatewayの環境を構築してみました。環境設定を template.yml に実処理をapp.pyに記載できて、後はコマンド実行で完了するので、再現性が高く、ファイル群はGitなどで履歴管理できるので非常に便利になると思います。
samを使ってプログラム集中出来るサーバーレスLambdaがもっと便利になって、開発者はより業務ロジックに集中出来る世の中になれば良いなと思います(^^)
本投稿が少しでも皆さんの良いサーバーレスライフの助けになればと思います(_ _)
資格取得に向けてAWSサービスを実際に利用してみるシリーズの投稿一覧
とりあえず30分でAWS利用料金の高額請求に備える~予算アラート設定・MFA・料金確認~
AWS ECSでDocker環境を試してみる
Amazon Cognitoを使ってシンプルなログイン画面を作ってみる
AWS NATゲートウェイを使ってプライベートサブネットからインターネットにアクセスする
API GatewayをPrivateで作成してみる
AWSのAI(Rekognition/Polly/Transcribe/Comprehend/Translate/Textract)サービスを試してみる
AWS Lambda 同時実行数、エイリアス、環境変数とか実際の現場で使える機能を勉強してみる
AWS Lambda SAMとは?~Cloud9でSAM Sampleを使ってPythonのLambdaプログラムを簡単にデプロイする~
AWS SAMを使って最もシンプルにLambda × APIGatewayのWebAPIを構築する(本記事)
AWS SAMを使って最もシンプルにLambda × S3 のS3イベント駆動プログラムを構築する