

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

# 教學課程：搭配 Lambda 叫用動作使用變數
<a name="tutorials-lambda-variables"></a>

Lambda 調用動作可以使用來自另一個動作的變數作為其輸入的一部分，並隨其輸出傳回新變數。如需 CodePipeline 中動作變數的相關資訊，請參閱 [變數參考](reference-variables.md)。

**重要**  
在建立管道的過程中，CodePipeline 將使用客戶提供的 S3 成品儲存貯體來製作成品。（這與用於 S3 來源動作的 儲存貯體不同。) 如果 S3 成品儲存貯體位於與管道帳戶不同的帳戶中，請確定 S3 成品儲存貯體由 所擁有 AWS 帳戶 ，安全且可靠。

在本教學結束時，您將擁有：
+ Lambda 叫用動作：
  + 使用 CodeCommit 來源動作中的`CommitId`變數
  + 輸出三個新變數：`dateTime`、`testRunId` 和 `region`
+ 使用 Lambda 調用動作中新變數的手動核准動作，以提供測試 URL 和測試執行 ID
+ 以新動作更新的管道

**Topics**
+ [

## 先決條件
](#lambda-variables-prereqs)
+ [

## 步驟 1：建立 Lambda 函式
](#lambda-variables-function)
+ [

## 步驟 2：將 Lambda 調用動作和手動核准動作新增至您的管道
](#lambda-variables-pipeline)

## 先決條件
<a name="lambda-variables-prereqs"></a>

開始之前，您必須準備好以下項目：
+ 您可以在 中建立或使用管道搭配 CodeCommit 來源[教學課程：建立簡單的管道 (CodeCommit 儲存庫）](tutorials-simple-codecommit.md)。
+ 編輯現有的管道，讓 CodeCommit 來源動作具有命名空間。將命名空間指派 `SourceVariables` 給動作。

## 步驟 1：建立 Lambda 函式
<a name="lambda-variables-function"></a>

使用下列步驟來建立 Lambda 函數和 Lambda 執行角色。建立 Lambda 函數後，您可以將 Lambda 動作新增至管道。

**建立 Lambda 函數和執行角色**

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

1. 選擇**建立函數**。將 **Author from scratch (從頭開始編寫)** 維持在選取狀態。

1. 在 **Function name (函數名稱)** 中，輸入您函數的名稱 (例如 **myInvokeFunction**)。在 **Runtime (執行時間)** 中，將預設選項維持在選取狀態。

1. 展開 **Choose or create an execution role (選擇或建立執行角色)**。選擇 **Create a new role with basic Lambda permissions (建立具備基本 Lambda 許可的新角色)**。

1. 選擇**建立函數**。

1. 若要透過另一個動作使用變數，則必須將其傳遞給 Lambda 呼叫動作組態中的 `UserParameters`。您將在稍後教學中在我們的管道中設定動作，但您將新增程式碼，此程式碼會假設此變數將傳遞。

   若要產生新變數，請將輸入上名為 `outputVariables` 的屬性設定為 `putJobSuccessResult`。請注意，您無法產生變數作為 `putJobFailureResult` 的一部分。

   ```
    const putJobSuccess = async (message) => {
           const params = {
               jobId: jobId,
               outputVariables: {
                   testRunId: Math.floor(Math.random() * 1000).toString(),
                   dateTime: Date(Date.now()).toString(),
                   region: lambdaRegion
               }
           };
   ```

   在新函數的**程式碼**索引標籤上，將下列範例程式碼貼到 下`index.mjs`。

   ```
   import { CodePipeline } from '@aws-sdk/client-codepipeline';
   
   export const handler = async (event, context) => {
       const codepipeline = new CodePipeline({});
       
       // Retrieve the Job ID from the Lambda action
       const jobId = event["CodePipeline.job"].id;
       
       // Retrieve UserParameters
       const params = event["CodePipeline.job"].data.actionConfiguration.configuration.UserParameters;
       
       // The region from where the lambda function is being executed
       const lambdaRegion = process.env.AWS_REGION;
       
       // Notify CodePipeline of a successful job
       const putJobSuccess = async (message) => {
           const params = {
               jobId: jobId,
               outputVariables: {
                   testRunId: Math.floor(Math.random() * 1000).toString(),
                   dateTime: Date(Date.now()).toString(),
                   region: lambdaRegion
               }
           };
           
           try {
               await codepipeline.putJobSuccessResult(params);
               return message;
           } catch (err) {
               throw err;
           }
       };
       
       // Notify CodePipeline of a failed job
       const putJobFailure = async (message) => {
           const params = {
               jobId: jobId,
               failureDetails: {
                   message: JSON.stringify(message),
                   type: 'JobFailed',
                   externalExecutionId: context.invokeid
               }
           };
           
           try {
               await codepipeline.putJobFailureResult(params);
               throw message;
           } catch (err) {
               throw err;
           }
       };
       
       try {
           console.log("Testing commit - " + params);
           
           // Your tests here
           
           // Succeed the job
           return await putJobSuccess("Tests passed.");
       } catch (ex) {
           // If any of the assertions failed then fail the job
           return await putJobFailure(ex);
       }
   };
   ```

1. 允許函數自動儲存。

1. 複製畫面頂端**函數 ARN** 欄位中包含的 Amazon Resource Name (ARN)。

1. 最後一個步驟是開啟位於 https：//[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 的 AWS Identity and Access Management (IAM) 主控台。修改 Lambda 執行角色以新增以下政策：[AWSCodePipelineCustomActionAccess](https://console.aws.amazon.com/iam/home?region=us-west-2#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAWSCodePipelineCustomActionAccess)。如需建立 Lambda 執行角色或修改角色政策的步驟，請參閱 [步驟 2：建立 Lambda 函數](actions-invoke-lambda-function.md#actions-invoke-lambda-function-create-function)。

## 步驟 2：將 Lambda 調用動作和手動核准動作新增至您的管道
<a name="lambda-variables-pipeline"></a>

在此步驟中，您會將 Lambda 調用動作新增至管道。您會新增名為 **Test (測試)** 的動作，做為階段的一部分。動作類型是呼叫動作。您接著會在呼叫動作之後新增手動核准動作。

**將 Lambda 動作和手動核准動作新增至管道**

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

   與 AWS 您的帳戶相關聯的所有管道名稱都會顯示。選擇您要新增動作的管道。

1. 將 Lambda 測試動作新增至您的管道。

   1. 若要編輯管道，請選擇 **Edit (編輯)**。在現有管道中於來源動作之後新增階段。輸入階段的名稱，例如 **Test**。

   1. 在新階段中，選擇**新增動作群組**以新增動作。在 **Action name (動作名稱)** 中，輸入呼叫動作的名稱，例如 **Test\$1Commit**。

   1. 在**動作提供者**中，選擇 **AWS Lambda**。

   1. 在 **Input artifacts (輸入成品)** 中，選擇您來源動作輸出成品的名稱，例如 `SourceArtifact`。

   1. 在 **FunctionName** 中，新增您建立之 Lambda 函數的 ARN。

   1. 在 **Variable namespace (變數命名空間)** 中，新增命名空間名稱，例如 **TestVariables**。

   1. 在**輸出成品**中，新增輸出成品名稱，例如 **LambdaArtifact**。

   1. 選擇**完成**。

1. 將手動核准動作新增到您的管道。

   1. 在您的管道仍處於編輯模式中時，於呼叫動作之後新增階段。輸入階段的名稱，例如 **Approval**。

   1. 在新階段中，選擇新增動作的圖示。在 **Action name (動作名稱)** 中，輸入核准動作的名稱，例如 **Change\$1Approval**。

   1. 在 **Action provider (動作提供者)** 中，選擇 **Manual approval (手動核准)**。

   1. 在 **URL for review (檢閱 URL)** 中，透過新增 `region` 變數和 `CommitId` 變數的變數語法來建構 URL。請確定您使用的是指派給提供輸出變數動作的命名空間。

      在此範例中，CodeCommit 動作具有變數語法的 URL 具有預設命名空間 `SourceVariables`。Lambda 區域輸出變數具備 `TestVariables` 命名空間。URL 看起來如下。

      ```
      https://#{TestVariables.region}.console.aws.amazon.com/codesuite/codecommit/repositories/MyDemoRepo/commit/#{SourceVariables.CommitId}
      ```

      在 **Comments (註解)** 中，透過新增 `testRunId` 變數的變數語法來建構核准訊息文字。針對此範例，擁有 Lambda `testRunId` 輸出變數變數語法的 URL 具備 `TestVariables` 命名空間。輸入以下訊息。

      ```
      Make sure to review the code before approving this action. Test Run ID: #{TestVariables.testRunId}
      ```

1. 選擇 **Done (完成)** 來關閉動作的編輯畫面，然後選擇 **Done (完成)** 來關閉階段的編輯畫面。如要儲存管道，請選擇 **Done (完成)**。已完成的管道現在包含結構，其中包含來源、測試、核准和部署階段。

   選擇 **Release change (發行變更)** 來透過管道結構執行最新的變更。

1. 管道到達手動核准階段時，請選擇 **Review (檢閱)**。已解析的變數會做為遞交 ID 的 URL 出現。您的核准者可以選擇 URL 來檢閱遞交。

1. 管道成功執行後，您也可以在 action execution history (動作執行歷史記錄) 頁面上檢視變數值。