iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
Cloud Native

AWS AI交易室實戰系列 第 12

Day 12 - SAM 開發流程介紹

  • 分享至 

  • xImage
  •  

AWS Serverless Application Model(AWS SAM) 是改善開發人員在 AWS上建置和執行無伺服器應用程式的體驗的工具組。 是由 CloudFormation 延伸出來,專門為應用程式開發者訂做的一套工具。
AWS SAM由兩個主要部分組成:

  1. AWS SAM 範本規格 — 可用來定義無伺服器應用程式基礎結構的開放原始碼架構。AWS
  2. AWS SAM 命令列介面 (AWS SAMCLI) — 命令列工具,可搭配 AWS SAM 範本和支援的第三方整合使用,以建置和執行無伺服器應用程式。
    ~ by AWS ~

SAM 對於以下五個 AWS 無伺服器相關的服務 & Global Section 提供了更簡潔的語法:

AWS::Serverless::Function(Lambda函數)

創建Lambda函數、IAM執行角色和触發函數的事件源映射。由於普通的CloudFormation模板需要為每個資源分別創建資源塊,因此使用AWS SAM更容易定義Lambda函數。

AWS::Serverless::Api(API Gateway)

創建一組Amazon API Gateway資源和可以通過HTTPS端點調用的方法。建議與Swagger一起使用以定義和文檔API Gateway,因為它提供對底層資源更多的控制。此類型的資源是從AWS::Serverless::Function塊中指定的API事件觸發器的並集中隱式創建的,這些觸發器不引用任何AWS::Serverless::Api。

AWS::Serverless::Application(嵌套堆棧)

將來自AWS Serverless Application存儲庫或Amazon S3存儲桶的無服務器應用程序嵌入為嵌套應用程序。嵌套應用程序部署為嵌套堆棧,可以包含多個其他資源,包括其他AWS::Serverless::Application資源。您可以使用這個或跨堆棧引用來提供無服務器應用程序不同部分的邏輯分離。

AWS::Serverless::SimpleTable(DynamoDB表)

創建一個帶有單個屬性主鍵的DynamoDB表。大多數表設計都具有更複雜的設計,在這種情況下,可以使用AWS::DynamoDB::Table資源。

AWS::Serverless::LayerVersion(Lambda層)

創建一個包含Lambda函數所需的庫或運行時代碼的Lambda LayerVersion。 SAM確保在轉換階段通過更改邏輯ID時不會刪除舊版本的Lambda Layer。

Global屬性:

單個模板中的資源可以具有多個具有相同值的常見屬性,例如Runtime、Cors等。全局部分可用於定義此類共享屬性,有助於減少資源的重複。

# Step 1 - Download a sample application
$ sam init -r python3.7 
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 - Hello World Example with Powertools for AWS Lambda
        3 - Infrastructure event management
        4 - Multi-step workflow
        5 - Serverless Connector Hello World Example
        6 - 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.

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

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]: N

Project name [sam-app]: marathon-sam

# print file directory tree
$ tree -I 'tree -I '*pyc*'
.
└── marathon-sam
    ├── README.md
    ├── __init__.py
    ├── events
    │   └── event.json
    ├── hello_world
    │   ├── __init__.py
    │   ├── app.py
    │   └── requirements.txt
    ├── samconfig.toml
    ├── template.yaml
    └── tests
        ├── __init__.py
        └── unit
            ├── __init__.py
            └── test_handler.py

可以看到

# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  marathon-sam
Globals:
  Function:
    Timeout: 3
    MemorySize: 128

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7
      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

這個檔案有幾個重要的部分:

Transform: AWS::Serverless-2016-10-31:# 表示這是一個 SAM template

Globals Section:定義了 Function 的 Timeout (3 seconds) & MemorySize (128 MB),這個 template 如果有定義其他的 Function 都會使用此設定

API Gateway 很低調地定義在 HelloWorldFunction 的 Events 中

Lambda 函數的 IAM 角色是隱式創建的,執行此 template 的 user 必須要有創建角色的權限

接著我們封裝 docker image 準備上傳部署:(這裡 ‘Function1’ 是固定值)

# package using container
$ sam build \
--use-container \
--build-image Function1=amazon/aws-sam-cli-build-image-python3.7

# deploy
$ sam deploy \
--stack-name marathon-sam \
--s3-bucket <s3-bucket-name> \
--region ap-northeast-1 \
--capabilities CAPABILITY_IAM

使用 sam deploy —guided 部署

然後就可以測試囉:

$ aws cloudformation describe-stacks \
--stack-name marathon-sam \
--query "Stacks[].Outputs"
...
{
  "OutputKey": "HelloWorldApi",
  "OutputValue": "https://359hpbnh7k.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/",
  "Description": "API Gateway endpoint URL for Prod stage for Hello World function"
},
...
$ curl https://359hpbnh7k.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world"}%

我們會發現 deploy 時間有點久,如果只是修改程式,可以利用 sam local start-api 在本機端啟動服務:

$ sam local start-api
...
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
...
# in a new console
$ curl http://127.0.0.1:3000/hello

# in a new console
$ sam local invoke "HelloWorldFunction" -e events/event.json

這個 event.json 的產生方式,個人覺得只是拿來開發參考用,這個指令還可以用來產生 S3 Event、SQS Event、SNS Notification 的 sample 算是個工具

$ sam local generate-event apigateway aws-proxy \
--body "" \
--path "hello" \
--method GET > event-get.json

# local invoke
$ sam local invoke "HelloWorldFunction" -e event-get.json

最後別忘了清理:

$ aws cloudformation delete-stack --stack-name marathon-sam

參考資料:

https://medium.com/@devops_83824/developing-serverless-applications-on-aws-using-aws-serverless-application-model-sam-cdcf3bda59bd
https://docs.aws.amazon.com/zh_tw/serverless-application-model/latest/developerguide/what-is-sam.html


上一篇
Day 11 - AWS Lambda with Container Image
下一篇
Day 13 - AWS Lambda Extension 介紹
系列文
AWS AI交易室實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言