

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 步驟 1：設定您的基礎設施
<a name="tutorial-lambda-sam-setup-infrastructure"></a>

 本主題說明如何使用 AWS SAM 為您的 AWS SAM 範本和 Lambda 函數建立檔案。然後，您可以使用 AWS SAM `package`和 `deploy`命令來產生基礎設施中的元件。當您的基礎設施準備就緒時，您會有一個 CodeDeploy 應用程式和部署群組、要更新和部署的 Lambda 函數，以及兩個包含部署 Lambda 函數時執行之驗證測試的 Lambda 函數。完成後，您可以使用 在 Lambda 主控台或 中 CloudFormation 檢視元件， AWS CLI 以測試 Lambda 函數。

**Topics**
+ [建立您的檔案](tutorial-lambda-create-files.md)
+ [封裝 AWS SAM 應用程式](tutorial-lambda-sam-package.md)
+ [部署 AWS SAM 應用程式](tutorial-lambda-sam-deploy.md)
+ [（選用） 檢查和測試您的基礎設施](tutorial-lambda-sam-confirm-components.md)

# 建立您的檔案
<a name="tutorial-lambda-create-files"></a>

 若要建立您的基礎設施，您必須建立以下檔案：
+ `template.yml`
+ `myDateTimeFunction.js`
+ `beforeAllowTraffic.js`
+ `afterAllowTraffic.js`

**Topics**
+ [建立您的 AWS SAM 範本](tutorial-lambda-sam-template.md)
+ [為您的 Lambda 函數建立檔案](tutorial-lambda-sam-create-lambda-function.md)
+ [為您的 BeforeAllowTraffic Lambda 函數建立檔案](tutorial-lambda-sam-create-lambda-before-traffic.md)
+ [為您的 AfterAllowTraffic Lambda 函數建立檔案](tutorial-lambda-sam-create-lambda-after-traffic.md)

# 建立您的 AWS SAM 範本
<a name="tutorial-lambda-sam-template"></a>

建立 AWS SAM 範本檔案，指定基礎設施中的元件。

**建立您的 AWS SAM 範本**

1.  建立名為 `SAM-Tutorial` 的目錄。

1.  在 `SAM-Tutorial` 目錄中，建立名為 `template.yml` 的檔案。

1.  將下列 YAML 程式碼複製到 `template.yml` 中。這是您的 AWS SAM 範本。

   ```
   AWSTemplateFormatVersion : '2010-09-09'
   Transform: AWS::Serverless-2016-10-31
   Description: A sample SAM template for deploying Lambda functions.
   
   Resources:
   # Details about the myDateTimeFunction Lambda function
     myDateTimeFunction:
       Type: AWS::Serverless::Function
       Properties:
         Handler: myDateTimeFunction.handler
         Runtime: nodejs18.x
   # Instructs your myDateTimeFunction is published to an alias named "live".      
         AutoPublishAlias: live
   # Grants this function permission to call lambda:InvokeFunction
         Policies:
           - Version: "2012-10-17"		 	 	 
             Statement: 
             - Effect: "Allow"
               Action: 
                 - "lambda:InvokeFunction"
               Resource: '*'
         DeploymentPreference:
   # Specifies the deployment configuration      
             Type: Linear10PercentEvery1Minute
   # Specifies Lambda functions for deployment lifecycle hooks
             Hooks:
               PreTraffic: !Ref beforeAllowTraffic
               PostTraffic: !Ref afterAllowTraffic
               
   # Specifies the BeforeAllowTraffic lifecycle hook Lambda function
     beforeAllowTraffic:
       Type: AWS::Serverless::Function
       Properties:
         Handler: beforeAllowTraffic.handler
         Policies:
           - Version: "2012-10-17"		 	 	 
   # Grants this function permission to call codedeploy:PutLifecycleEventHookExecutionStatus        
             Statement: 
             - Effect: "Allow"
               Action: 
                 - "codedeploy:PutLifecycleEventHookExecutionStatus"
               Resource:
                 !Sub 'arn:aws:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
           - Version: "2012-10-17"		 	 	 
   # Grants this function permission to call lambda:InvokeFunction        
             Statement: 
             - Effect: "Allow"
               Action: 
                 - "lambda:InvokeFunction"
               Resource: !Ref myDateTimeFunction.Version
         Runtime: nodejs18.x
   # Specifies the name of the Lambda hook function      
         FunctionName: 'CodeDeployHook_beforeAllowTraffic'
         DeploymentPreference:
           Enabled: false
         Timeout: 5
         Environment:
           Variables:
             NewVersion: !Ref myDateTimeFunction.Version
             
   # Specifies the AfterAllowTraffic lifecycle hook Lambda function
     afterAllowTraffic:
       Type: AWS::Serverless::Function
       Properties:
         Handler: afterAllowTraffic.handler
         Policies:
           - Version: "2012-10-17"		 	 	 
             Statement: 
   # Grants this function permission to call codedeploy:PutLifecycleEventHookExecutionStatus         
             - Effect: "Allow"
               Action: 
                 - "codedeploy:PutLifecycleEventHookExecutionStatus"
               Resource:
                 !Sub 'arn:aws:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
           - Version: "2012-10-17"		 	 	 
             Statement: 
   # Grants this function permission to call lambda:InvokeFunction          
             - Effect: "Allow"
               Action: 
                 - "lambda:InvokeFunction"
               Resource: !Ref myDateTimeFunction.Version
         Runtime: nodejs18.x
   # Specifies the name of the Lambda hook function      
         FunctionName: 'CodeDeployHook_afterAllowTraffic'
         DeploymentPreference:
           Enabled: false
         Timeout: 5
         Environment:
           Variables:
             NewVersion: !Ref myDateTimeFunction.Version
   ```

此範本指定下列項目。如需詳細資訊，請參閱[AWS SAM 範本概念](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-basics.html)。

**稱為 的 Lambda 函數 `myDateTimeFunction`**  
 發佈此 Lambda 函數時，範本中的`AutoPublishAlias`行會將其連結至名為 的別名`live`。在本教學課程稍後，此函數的更新會透過 觸發部署 AWS CodeDeploy ，逐步將生產流量從原始版本轉移到更新版本。

**兩個 Lambda 部署驗證函數**  
 下列 Lambda 函數會在 CodeDeploy 生命週期關聯期間執行。函數中的程式碼會驗證已更新的 `myDateTimeFunction` 是否部署完成。驗證測試的結果會使用其 `PutLifecycleEventHookExecutionStatus` API 方法傳遞至 CodeDeploy。如果驗證測試失敗，部署會失敗並轉返。  
+  `CodeDeployHook_beforeAllowTraffic` 會在 `BeforeAllowTraffic` 勾點期間執行。
+  `CodeDeployHook_afterAllowTraffic` 會在 `AfterAllowTraffic` 勾點期間執行。
兩個函數的名稱以 `CodeDeployHook_` 開頭。此`CodeDeployRoleForLambda`角色僅允許在名稱開頭為此字首的 Lambda 函數中呼叫 Lambda `invoke`方法。如需詳細資訊，請參閱 *CodeDeploy API 參考*中的 [AWS Lambda 部署的 AppSpec 'hooks' 區段](reference-appspec-file-structure-hooks.md#appspec-hooks-lambda)和 [PutLifecycleEventHookExecutionStatus](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_PutLifecycleEventHookExecutionStatus.html)。

**自動偵測更新的 Lambda 函數**  
 `AutoPublishAlias` 一詞告知框架偵測 `myDateTimeFunction` 函數何時變更，然後使用 `live` 別名部署此函數。

**部署組態**  
 部署組態會決定 CodeDeploy 應用程式將流量從 Lambda 函數的原始版本轉移到新版本的速率。此範本指定預先定義的部署組態 `Linear10PercentEvery1Minute`。  
 您無法在 AWS SAM 範本中指定自訂部署組態。如需詳細資訊，請參閱[使用 CodeDeploy 建立部署組態](deployment-configurations-create.md)。

**部署生命週期勾點函數**  
 `Hooks` 區段指定在生命週期事件勾點期間執行的函數。`PreTraffic` 指定在 `BeforeAllowTraffic` 勾點期間執行的函數。`PostTraffic` 指定在 `AfterAllowTraffic` 勾點期間執行的函數。

**Lambda 叫用另一個 Lambda 函數的許可**  
 指定的`lambda:InvokeFunction`許可會授予 SAM 應用程式用來叫用 Lambda AWS 函數的 角色許可。當 `CodeDeployHook_beforeAllowTraffic`和 `CodeDeployHook_afterAllowTraffic`函數在驗證測試期間調用部署的 Lambda 函數時，這是必要的。

# 為您的 Lambda 函數建立檔案
<a name="tutorial-lambda-sam-create-lambda-function"></a>

為您稍後在此教學課程中更新和部署的函數建立檔案。

**注意**  
 Lambda 函數可以使用 支援的任何執行時間 AWS Lambda。如需詳細資訊，請參閱 [AWS Lambda 執行時間](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)。

**建立 Lambda 函數**

1.  建立文字檔案，並在 `SAM-Tutorial` 目錄中儲存為 `myDateTimeFunction.js`。

1.  將下列 Node.js 程式碼複製到 `myDateTimeFunction.js` 中。

   

   ```
   'use strict';
       
       exports.handler = function(event, context, callback) {
       
         if (event.body) {
           event = JSON.parse(event.body);
         }
       
         var sc; // Status code
         var result = ""; // Response payload
       
         switch(event.option) {
           case "date": 
             switch(event.period) {
               case "yesterday":
                 result = setDateResult("yesterday");
                 sc = 200;
                 break;
               case "today":
                 result = setDateResult();
                 sc = 200;
                 break;
               case "tomorrow":
                 result = setDateResult("tomorrow");
                 sc = 200;
                 break;
               default:
                 result = {
                   "error": "Must specify 'yesterday', 'today', or 'tomorrow'."
                 };
                 sc = 400;
                 break;
             }
             break;
             
       /*      Later in this tutorial, you update this function by uncommenting 
               this section. The framework created by AWS SAM detects the update 
               and triggers a deployment by CodeDeploy. The deployment shifts 
               production traffic to the updated version of this function.
               
               case "time":
               var d = new Date();
               var h = d.getHours();
               var mi = d.getMinutes();
               var s = d.getSeconds();
       
               result = {
                 "hour": h,
                 "minute": mi,
                 "second": s
               };
               sc = 200;
               break;
       */
             default:
               result = {
                 "error": "Must specify 'date' or 'time'."
               };
               sc = 400;
             break;
         }
       
         const response = {
           statusCode: sc,
           headers: { "Content-type": "application/json" },
           body: JSON.stringify( result )
         };
       
         callback(null, response);
       
         function setDateResult(option) {
       
           var d = new Date(); // Today
           var mo; // Month
           var da; // Day
           var y; // Year
       
           switch(option) {
             case "yesterday":
               d.setDate(d.getDate() - 1);
               break;
             case "tomorrow":
               d.setDate(d.getDate() + 1);
             default:
              break;
           }
       
           mo = d.getMonth() + 1; // Months are zero offset (0-11)
           da = d.getDate();
           y = d.getFullYear();
       
           result = {
             "month": mo,
             "day": da,
             "year": y
           };
       
           return result;
         }
       };
   ```

Lambda 函數會傳回昨天、今天或明天的日、月和年。稍後在本教學課程中，您會取消註解程式碼，以更新函數來傳回您所指定的日期或時間的相關資訊 (例如，年、月、日，或目前的時、分、秒)。建立的架構會 AWS SAM 偵測並部署函數的更新版本。

**注意**  
 此 Lambda 函數也用於 AWS Cloud9 教學課程。 AWS Cloud9 是雲端型整合開發環境。如需有關如何在 中建立、執行、更新和偵錯此函數的資訊 AWS Cloud9，請參閱 [AWS Lambda 教學課程 AWS Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/tutorial-lambda.html)。

# 為您的 BeforeAllowTraffic Lambda 函數建立檔案
<a name="tutorial-lambda-sam-create-lambda-before-traffic"></a>

為您的`beforeAllowTraffic`勾點 Lambda 函數建立 檔案。

1.  建立文字檔案，並在 `SAM-Tutorial` 目錄中儲存為 `beforeAllowTraffic.js`。

1.  將下列 Node.js 程式碼複製到 `beforeAllowTraffic.js` 中。此函數會在您的部署 `BeforeAllowTraffic` 勾點期間執行。

   ```
   'use strict';
       
       const AWS = require('aws-sdk'); 
       const codedeploy = new AWS.CodeDeploy({apiVersion: '2014-10-06'});
       var lambda = new AWS.Lambda();
       
       exports.handler = (event, context, callback) => {
       
       	console.log("Entering PreTraffic Hook!");
       	
       	// Read the DeploymentId and LifecycleEventHookExecutionId from the event payload
         var deploymentId = event.DeploymentId;
       	var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;
       
       	var functionToTest = process.env.NewVersion;
       	console.log("BeforeAllowTraffic hook tests started");
       	console.log("Testing new function version: " + functionToTest);
       
       	// Create parameters to pass to the updated Lambda function that
       	// include the newly added "time" option. If the function did not
       	// update, then the "time" option is invalid and function returns
       	// a statusCode of 400 indicating it failed.
       	var lambdaParams = {
       		FunctionName: functionToTest,    
       		Payload: "{\"option\": \"time\"}", 
       		InvocationType: "RequestResponse"
       	};
       
       	var lambdaResult = "Failed";
       	// Invoke the updated Lambda function.
       	lambda.invoke(lambdaParams, function(err, data) {
       		if (err){	// an error occurred
       			console.log(err, err.stack);
       			lambdaResult = "Failed";
       		}
       		else{	// successful response
       			var result = JSON.parse(data.Payload);
       			console.log("Result: " +  JSON.stringify(result));
             console.log("statusCode: " + result.statusCode);
             
             // Check if the status code returned by the updated
             // function is 400. If it is, then it failed. If 
             // is not, then it succeeded.
       			if (result.statusCode != "400"){
               console.log("Validation succeeded");
       				lambdaResult = "Succeeded";
             }
             else {
               console.log("Validation failed");
             }
       
       			// Complete the PreTraffic Hook by sending CodeDeploy the validation status
       			var params = {
       				deploymentId: deploymentId,
       				lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
       				status: lambdaResult // status can be 'Succeeded' or 'Failed'
       			};
       			
       			// Pass CodeDeploy the prepared validation test results.
       			codedeploy.putLifecycleEventHookExecutionStatus(params, function(err, data) {
       				if (err) {
       					// Validation failed.
       					console.log("CodeDeploy Status update failed");
       					console.log(err, err.stack);
       					callback("CodeDeploy Status update failed");
       				} else {
       					// Validation succeeded.
       					console.log("CodeDeploy status updated successfully");
       					callback(null, "CodeDeploy status updated successfully");
       				}
       			});
       		}  
       	});
       }
   ```

# 為您的 AfterAllowTraffic Lambda 函數建立檔案
<a name="tutorial-lambda-sam-create-lambda-after-traffic"></a>

為您的`afterAllowTraffic`勾點 Lambda 函數建立 檔案。

1.  建立文字檔案，並在 `SAM-Tutorial` 目錄中儲存為 `afterAllowTraffic.js`。

1.  將下列 Node.js 程式碼複製到 `afterAllowTraffic.js` 中。此函數會在您的部署 `AfterAllowTraffic` 勾點期間執行。

   ```
   'use strict';
       
       const AWS = require('aws-sdk');
       const codedeploy = new AWS.CodeDeploy({apiVersion: '2014-10-06'});
       var lambda = new AWS.Lambda();
       
       exports.handler = (event, context, callback) => {
       
       	console.log("Entering PostTraffic Hook!");
       	
       	// Read the DeploymentId and LifecycleEventHookExecutionId from the event payload
         var deploymentId = event.DeploymentId;
       	var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;
       
       	var functionToTest = process.env.NewVersion;
       	console.log("AfterAllowTraffic hook tests started");
       	console.log("Testing new function version: " + functionToTest);
       
       	// Create parameters to pass to the updated Lambda function that
       	// include the original "date" parameter. If the function did not 
       	// update as expected, then the "date" option might be invalid. If 
       	// the parameter is invalid, the function returns
       	// a statusCode of 400 indicating it failed.
       	var lambdaParams = {
       		FunctionName: functionToTest,    
       		Payload: "{\"option\": \"date\", \"period\": \"today\"}", 
       		InvocationType: "RequestResponse"
       	};
       
       	var lambdaResult = "Failed";
       	// Invoke the updated Lambda function.
       	lambda.invoke(lambdaParams, function(err, data) {
       		if (err){	// an error occurred
       			console.log(err, err.stack);
       			lambdaResult = "Failed";
       		}
       		else{	// successful response
       			var result = JSON.parse(data.Payload);
       			console.log("Result: " +  JSON.stringify(result));
             console.log("statusCode: " + result.statusCode);
             
             // Check if the status code returned by the updated
             // function is 400. If it is, then it failed. If 
             // is not, then it succeeded.
       			if (result.statusCode != "400"){
               console.log("Validation of time parameter succeeded");
       				lambdaResult = "Succeeded";
             }
             else {
               console.log("Validation failed");
             }
       
       			// Complete the PostTraffic Hook by sending CodeDeploy the validation status
       			var params = {
       				deploymentId: deploymentId,
       				lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
       				status: lambdaResult // status can be 'Succeeded' or 'Failed'
       			};
       			
       			// Pass CodeDeploy the prepared validation test results.
       			codedeploy.putLifecycleEventHookExecutionStatus(params, function(err, data) {
       				if (err) {
       					// Validation failed.
       					console.log("CodeDeploy Status update failed");
       					console.log(err, err.stack);
       					callback("CodeDeploy Status update failed");
       				} else {
       					// Validation succeeded.
       					console.log("CodeDeploy status updated successfully");
       					callback(null, "CodeDeploy status updated successfully");
       				}
       			});
       		}  
       	});
       }
   ```

# 封裝 AWS SAM 應用程式
<a name="tutorial-lambda-sam-package"></a>

 您的 `SAM-Tutorial` 目錄現在應該有四個檔案：
+ `beforeAllowTraffic.js`
+ `afterAllowTraffic.js`
+ `myDateTimeFunction.js`
+ `template.yml`

 您現在可以使用 AWS SAM **sam package**命令為您的 Lambda 函數和 CodeDeploy 應用程式建立和封裝成品。成品會上傳至 S3 儲存貯體。命令的輸出是名為 `package.yml` 的新檔案。SAM AWS **sam deploy**命令會在下一個步驟中使用此檔案。

**注意**  
 如需 **sam package**命令的詳細資訊，請參閱《 *AWS Serverless Application Model 開發人員指南*》中的 [AWS SAM CLI 命令參考](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html)。

 在 `SAM-Tutorial` 目錄中執行下列命令。

```
sam package \
  --template-file template.yml \
  --output-template-file package.yml \
  --s3-bucket amzn-s3-demo-bucket
```

針對 `s3-bucket` 參數，指定您建立的 Amazon S3 儲存貯體，做為本教學課程的先決條件。`output-template-file` 指定 SAM AWS **sam deploy**命令使用的新檔案名稱。

# 部署 AWS SAM 應用程式
<a name="tutorial-lambda-sam-deploy"></a>

 使用 AWS SAM **sam deploy**命令搭配 `package.yml` 檔案，使用 建立 Lambda 函數和 CodeDeploy 應用程式和部署群組 CloudFormation。

**注意**  
如需 **sam deploy**命令的詳細資訊，請參閱《 *AWS Serverless Application Model 開發人員指南*》中的 [AWS SAM CLI 命令參考](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html)。

 在 `SAM-Tutorial` 目錄中執行下列命令。

```
sam deploy \
  --template-file package.yml \
  --stack-name my-date-time-app \
  --capabilities CAPABILITY_IAM
```

 需要 `--capabilities CAPABILITY_IAM` 參數才能授權 CloudFormation 建立 IAM 角色。

# （選用） 檢查和測試您的基礎設施
<a name="tutorial-lambda-sam-confirm-components"></a>

 本主題說明如何檢視基礎設施元件並測試 Lambda 函數。

**在執行 `sam deploy` 後查看堆疊的結果**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1.  在導覽窗格中，選擇 **Stacks (堆疊)**。`my-date-time-app` 堆疊會顯示在頂端。

1.  選擇 **Events (事件)** 標籤，以查看已完成的事件。您可以在堆疊建立進行時檢視事件。堆疊建立完成時，您可以查看所有堆疊建立事件。

1.  選取堆疊後，選擇 **Resources (資源)**。在**類型**欄中，您可以看到 Lambda 函數、`CodeDeployHook_beforeAllowTraffic`、 `myDateTimeFunction`和 `CodeDeployHook_afterAllowTraffic`。每個 Lambda 函數的**實體 ID** 欄都包含一個連結，可在 Lambda 主控台中檢視函數。
**注意**  
 `myDateTimeFunction` Lambda 函數的名稱前面加上 CloudFormation 堆疊的名稱，並新增了識別符，因此看起來像 `my-date-time-app-myDateTimeFunction-123456ABCDEF`。

1. 前往 [https://console.aws.amazon.com/codedeploy/](https://console.aws.amazon.com/codedeploy/) 開啟 CodeDeploy 主控台。

1.  在導覽窗格中，展開 **Deploy (部署)**，然後選擇 **Applications (應用程式)**。

1.  您應該會看到由 建立且名稱開頭 CloudFormation 為 的新 CodeDeploy 應用程式`my-date-time-app-ServerlessDeploymentApplication`。選擇此應用程式。

1.  您應該會看到名稱開頭為 `my-date-time-app-myDateTimeFunctionDeploymentGroup` 的部署群組。選擇此部署群組。

    在 **Deployment configuration (部署組態)** 下，您應該會看到 **CodeDeployDefault.LambdaLinear10PercentEvery1Minute**。

**（選用） 以測試您的函數 （主控台）**

1. 在 https：//[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) 開啟 AWS Lambda 主控台。

1.  從導覽窗格中，選擇您的 `my-date-time-app-myDateTimeFunction` 函數。在主控台中，其名稱包含識別符，因此看起來像 `my-date-time-app-myDateTimeFunction-123456ABCDEF`。

1.  選擇**測試**。

1.  在 **Event name (事件名稱)** 中，輸入測試事件的名稱。

1.  為您的測試事件輸入下列內容，然後選擇 **Create (建立)**。

   ```
   {
     "option": "date",
     "period": "today"
   }
   ```

1.  選擇**測試**。您在測試事件清單中應該只會看到您的測試事件。

    對於 **Execution result (執行結果)**，您應該會看到 **succeeded (成功)**。

1.  在 **Execution result (執行結果)** 下，展開 **Details (詳細資訊)** 以查看結果。您應該會看到目前的年、月、日。

**（選用） 以測試您的函數 (AWS CLI)**

1.  尋找 Lambda 函數的 ARN。當您檢視函數時，它會出現在 Lambda 主控台的頂端。

1.  執行下列命令。將 *your-function-arn* 換成函數 ARN。

   ```
   aws lambda invoke \
   --function your-function-arn \
   --cli-binary-format raw-in-base64-out \
   --payload "{\"option\": \"date\", \"period\": \"today\"}" out.txt
   ```

1.  開啟 `out.txt` 以確認結果包含目前的年、月、日。