2021/9/30(木) JAWS-UG CLI専門支部 #229R CloudWatch Logs入門で「AWS SAM触ってみた奮闘記」というタイトルでLTの時間をいただきました。「AWS SAMって何?」の状態から、なんとなく概要がつかめるようになるまでの奮闘記です。
本記事ではSAMの概要と、チュートリアルの簡単な手順を記載します。
1.AWS SAMとは -AWS Serverless Application Model
公式のドキュメントに説明があるが、個人的に要点をギュッとまとめると以下の通り。
- AWSのサーバレスサービスを使ったアプリケーションの構築を自動化する便利ツール
- 内部的にはCloudFormation
- SAM専用CLIで使えるもの
2.準備
Cloud9環境にはSAM CLIがインストール済みなのでそのまま使える。
今回は「Hello worldアプリケーションのデプロイ」チュートリアルを実施する。
以下のような構成図で、API GatewayがGETメソッドでLambdaを呼び出し応答を返す簡単なアプリを作成する。
SAM CLIを実行するCloud9環境のEC2インスタンスに、今回は以下AWS管理ポリシーを付与したIAMロールを関連付ける。
- API Gateway(AmazonAPIGatewayAdministrator)
- Lambda(AWSLambda_FullAccess)
- CloudFormation(AWSCloudFormationFullAccess)
- S3(AmazonS3FullAccess)
- IAM(IAMFullAccess)
3.SAM実行手順
以下3ステップを実行するだけでサンプルアプリケーションができる。
#①サンプルアプリケーションをダウンロード
sam init
#②アプリケーションをビルドする
cd sam-app
sam build
#③アプリケーションをデプロイする
sam deploy --guided
ステップ①サンプルアプリケーションをダウンロード(sam init)
sam init
コマンドを実行すると対話形式で選択が始まる。
#ステップ①サンプルアプリケーションをダウンロード
sam init
#Enter
以下のように説明文が表示され、選択肢が出る。
SAM CLI now collects telemetry to better understand customer needs.
You can OPT OUT and disable telemetry collection by setting the
environment variable SAM_CLI_TELEMETRY=0 in your shell.
Thanks for your help!
Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice:
今回は「Hello worldアプリケーションのデプロイ」チュートリアルを実施するので、「1」を入力しEnter
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
#Enter
パッケージタイプを聞かれる。「1」のZipを選択しEnter
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1
#Enter
Runtimeはなんでもいいが、今回は「9」python3.7を選択しEnter
Which runtime would you like to use?
1 - nodejs14.x
2 - python3.8
3 - ruby2.7
4 - go1.x
5 - java11
6 - dotnetcore3.1
7 - nodejs12.x
8 - nodejs10.x
9 - python3.7
10 - python3.6
11 - python2.7
12 - ruby2.5
13 - java8.al2
14 - java8
15 - dotnetcore2.1
Runtime: 9
#Enter
プロジェクト名は[sam-app]のままEnter
Project name [sam-app]:
#Enter
クイックスタートテンプレートは「1」Hello World Exampleを選択しEnter
Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates
AWS quick start application templates:
1 - Hello World Example
2 - EventBridge Hello World
3 - EventBridge App from scratch (100+ Event Schemas)
4 - Step Functions Sample App (Stock Trader)
Template selection: 1
以下のようにエラーなく終了すればOK。
(CLI最新バージョンが使えると出ているが今回は無視する)
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.7
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./sam-app/README.md
SAM CLI update available (1.31.0); (1.19.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
[ec2-user@ip-10-0-0-104%]$
「app.py」がLambda関数としてデプロイされる。
「template.yaml」はCloudFormationテンプレートで、このテンプレートを展開することによってサーバレスリソースがデプロイされる。
「app.py」の中身↓↓↓
※SAMによって自動生成されるコメント行は省略している
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
}),
}
API GatewayからのGETリクエストで"message": "hello world"
と帰ってくるLambda関数が記載されている。今回は"message": "hello CLI world"
と書き換えてみる。
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello CLI world",
}),
}
ステップ②アプリケーションをビルドする(sam build)
まずsam-appディレクトリに移動する。
cd sam-app
#Enter
続いてsam build
コマンドを実行する。
sam build
#Enter
以下のようにビルドが実行され終了する。
Building codeuri: hello_world/ runtime: python3.7 metadata: {} functions: ['HelloWorldFunction']
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
[ec2-user@ip-10-0-0-104%]$
ステップ③アプリケーションをデプロイする(sam deploy --guided)
最後にsam deploy
コマンドでデプロイする。
--guided
オプションを付けることで対話形式になる。
sam deploy --guided
#Enter
以下のようにスタック名を聞かれる。sam-appのままEnter
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
#Enter
リージョンを聞かれる。そのままでもいいが、今回は東京リージョンにしてみる。
AWS Region [us-east-1]: ap-northeast-1
#Enter
以下のようにy/n
を聞かれる。すべてy
(もしくはY
)で進める。
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y #Enter
#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 #Enter
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y #Enter
Save arguments to configuration file [Y/n]: Y #Enter
SAM configuration fileとSAM configuration environmentを聞かれる。デフォルトのままEnterで進める。
SAM configuration file [samconfig.toml]: #Enter
SAM configuration environment [default]: #Enter
Creating the required resources...
で少し待つ。
Looking for resources needed for deployment: Not found.
Creating the required resources...
成功するとSuccessfully created!
となり、先に進む。
Waiting for changeset to be created..
で少し待つ。
Successfully created!
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-huxxxxxxxxxx
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/4de18c6e8dcbeb886cc6a8xxxxxxxxxx 444598 / 444598 (100.00%)
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-huxxxxxxxxxx
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
HelloWorldFunction may not have authorization defined.
Uploading to sam-app/7ffc7fb8e4a0ab4fd99f40xxxxxxxxxx.template 1089 / 1089 (100.00%)
Waiting for changeset to be created..
Changeset created successfully.
で変更セットの作成が終わると、最後にDeploy this changeset?
(変更セットをデプロイしますか?)と聞かれるので、y
で進める。
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 ServerlessRestApiDeployment47xxxxxxxxxx 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-deployxxxxxxxxxx/3b2fxxxx-xxxx-xxxx-xxxx-1fxxxxxxxxxx
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y #Enter
以下のように、CloudFormationスタックのイベントがぬるぬる表示されていく。
2021-09-20 01:50:26 - Waiting for stack create/update to complete
CloudFormation events from changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd -
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeploymentxxxxxxxxxx -
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeploymentxxxxxxxxxx Resource creation Initiated
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd Resource creation Initiated
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeploymentxxxxxxxxxx -
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::xxxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-1KBxxxxxxxxxx
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://69xxxxxxxx.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-app-HelloWorldFunction-mzxxxxxxxxxx
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
[ec2-user@ip-10-0-0-31%]$
Successfully created/updated stack - sam-app in ap-northeast-1(←設定したリージョン)
と表示されれば、デプロイ成功。
4.デプロイの結果を確認する
CloudFormation
CloudFormationからスタックを確認すると、以下二つのスタックが作成されている。
- sam-app
- aws-sam-cli-managed-default
「sam-app」スタックの出力を見ると、作成されたAPI GatewayのエンドポイントURLリンクが表示されているので、クリックする。
ブラウザで以下のように"message": "hello world"
と表示され、無事アプリケーションが稼働していることが確認できた。
CloudFormationスタックのリソースを確認する。
「sam-app」スタックのリソースを見ると、以下のリソースが作成されている。
- Lambda
- IAMロール
- API Gateway
「aws-sam-cli-managed-default」スタックのリソースを見ると、以下S3バケットとバケットポリシーが作成されている。
マネジメントコンソールからも、それぞれのリソースが作成されていることが確認できる。
S3
IAMロール
Lambda
API Gateway
5.片付け
以下コマンドで「sam-app」スタックを削除する。
aws cloudformation delete-stack \
--stack-name sam-app \
--region ap-northeast-1 #←選択したリージョン
これで「Lambda」「IAMロール」「API Gateway」の削除が完了。
もう一つのスタック「aws-sam-cli-managed-default」にはバージョニング有効なS3バケットが含まれているため、S3内のオブジェクトを完全に削除して、S3バケットを空にしてからスタックの削除を実施する。
#S3バケットを空にしてから実行する。
aws cloudformation delete-stack \
--stack-name aws-sam-cli-managed-default \
--region ap-northeast-1 #←選択したリージョン
Cloud9環境のEC2インスタンスに「sam-app」ディレクトリが残存するので、これも不要であれば以下コマンドで削除しておく。
rm -Rf ${HOME}/environment/sam-app
CloudWatch LogsもSAM用のロググループが残存しているので不要であれば削除する。
SAM CLIを実行するCloud9環境のEC2インスタンスに紐づいたロールから、不要であれば以下AWS管理ポリシーを剥奪しておく。
- API Gateway(AmazonAPIGatewayAdministrator)
- Lambda(AWSLambda_FullAccess)
- CloudFormation(AWSCloudFormationFullAccess)
- S3(AmazonS3FullAccess)
- IAM(IAMFullAccess)
参考
AWS サーバーレスアプリケーションモデル
チュートリアル: Hello World アプリケーションのデプロイ
AWS SAMリファレンス
書籍「ポケットスタディ AWS認定 デベロッパーアソシエイト」