sam cliにHello worldした時の備忘録です。
sam(serverless Application Model)はcloudformationの一部でサーバレスに特化して、cloudformationより簡単に記述しやすくなっています。今回はcloud shellでsam cliを操作してHello worldをAWSにデプロイしたため、簡単にご紹介します。
※cloud shellではコンテナを動かせない為、デプロイ前のローカルテストは出来ません!一般的にはcloud9を利用したほうが幸せです。
では早速!
cloud shellでsam cliの基本操作
cloudshellでもsam cliは動かすことが出来ます。
$sam --version
SAM CLI, version 1.52.0
※cloudshellはdockerが使えないため、dockerを利用する「sam local start-api」等が実施できない制約はありますが、sam cliの雰囲気はつかめます。
sam init
cloudshellにログイン後、samテンプレートを構築します。
- hello worldテンプレートを利用
※api-gateway, lamdaが構築する内容です。 - python3.7を指定
※現時点(2022年8月)のcloudshellのpython3は3.7である。
$ 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 - 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 - python3.6
17 - ruby2.7
18 - rust (provided.al2)
Runtime: 15
What package type would you like to use?
1 - Zip
2 - Image
Package type: 1
Based on your selections, the only dependency manager available is pip.
We will proceed copying the template using pip.
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: n
Project name [sam-app]:
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.7
Architectures: x86_64
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./sam-app/README.md
Commands you can use next
=========================
[*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
[*] Validate SAM template: sam validate
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
無事に構築出来たようです。
sam-appフォルダに移動し、以下の中身を確認してみます。
- samテンプレート(template.yaml)
- lambda関数(app.py)
$cd sam-app/
$cat template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.7
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
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
$cat hello_world/app.py
import json
# import requests
def lambda_handler(event, context):
"""Sample pure Lambda function
Parameters
----------
event: dict, required
API Gateway Lambda Proxy Input Format
Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
context: object, required
Lambda Context runtime methods and attributes
Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
Returns
------
API Gateway Lambda Proxy Output Format: dict
Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
"""
# try:
# ip = requests.get("http://checkip.amazonaws.com/")
# except requests.RequestException as e:
# # Send some context about this error to Lambda Logs
# print(e)
# raise e
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
# "location": ip.text.replace("\n", "")
}),
}
api-gatewayのurlにアクセスするとlambda関数がコールされ、「hello world」を返してくれるコードとなっています
・・・ざっくりと理解したつもり。
sam build
続いてtemplate.yamlが存在するフォルダ「sam-app」でビルド(デプロイ前の依存関係解決など準備)を行います。
$sam build
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/cloudshell-user/sam-app/hello_world runtime: python3.7 metadata: {} architecture: x86_64 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
=========================
[*] 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
無事に成功しました。
もしここでpythonのバージョン不一致など問題があると、ビルドが失敗します。
sam deploy
実際にAWS環境にデプロイ(構築)します。
※初回は「–guided」オプションを付けます。
$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]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: n
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-xxxxxxxxx
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/a749410668d0b70bdxxxxxxx 465116 / 465116 (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-xxxxxxxxxx
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app/03ec28a1387579cb1axxxxxxxxx.template 1144 / 1144 (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 ServerlessRestApiDeployment47xxxxxxxx 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-deploy16xxxx/ee71499b-xxxx-42d4-bfec-xxxxxxx
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2022-08-23 02:23:55 - 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::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 ServerlessRestApiDeployment47fcxxxxxxxxx -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd Resource creation Initiated
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fxxxxxxxx Resource creation Initiated
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fxxxxxxxxx -
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::xxxxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-UMXXXXXXXX
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://swxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxxxx:function:sam-app-HelloWorldFunction-jimSNxxxx
------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
※一部文字はxxxで伏せています。
無事にデプロイが完了したため、ブラウザでapi-gatewayのURLにアクセスすると、無事に以下が返ってきました。Hello-worldのURLは制限がかかっていないため注意しましょう。
{
message: "hello world"
}
内容を変更して再度デプロイする場合は、
- sam build
- sam deploy
※2回目以降は–guidedオプションは不要です。
を実行してあげればOKです。変更分だけアップロードされます。
sam delete
samプロジェクトフォルダ(sam-app)でsam deleteを実行すれば、
- lambda関数
- api-gateway
- role
- s3
などを全部綺麗に削除してくれます。
$sam delete
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/599d1e96fc75b648a6bfd472db8f9051
- Deleting S3 object with key sam-app/03ec28a1387579cb1ab12fee97d73b28.template
- Deleting S3 object with key sam-app/1d02fc33fa3aeb45f5a86f73e8e83b33.template
- Deleting S3 object with key sam-app/a749410668d0b70bd0c12c169aec16b3
- Deleting Cloudformation stack sam-app
Deleted successfully
まとめ
今回はaws資格のDAVに備えて色々と勉強する中で、sam cliにcloudshellで少しだけ触れました。
sam cliで記述することで、デプロイは確実に行え、簡単にサーバレスアプリケーションを構築することが出来ます。ただ、サーバレスアプリケーションの構成要素であるLambda、API Gateway、及びその連携をある程度理解しないと、sam cliのtemplate内容の理解はドキュメントを見ても難しいかなって思います。ある程度理解した後に、サーバレステンプレートの雛形として開発メンバに配ったりすると開発が加速出来そうです。
(メイン記事では触れていませんが)cloud9にはdockerが入っているため、ローカルテストも簡単に行うことが出来ます。ただし、dynamoDB等の他サービスとローカルで連携するにはdynamoDBのdockerを自前で準備したりするなど、まだ使いにくいと感じます。
コメント