

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

# Lambda 輪換函數
<a name="rotate-secrets_lambda-functions"></a>

在 中[由 Lambda 函式輪換](rotate-secrets_lambda.md)， AWS Lambda 函數會輪換秘密。 AWS Secrets Manager 會在輪換期間使用[預備標籤](whats-in-a-secret.md)來識別秘密版本。

如果 AWS Secrets Manager 未為您的秘密類型提供[輪換函數範本](reference_available-rotation-templates.md)，您可以建立自訂輪換函數。撰寫輪換函數時，請遵循下列準則：

**自訂輪換函數的最佳實務**
+ 使用[一般輪換範本](reference_available-rotation-templates.md#OTHER_rotation_templates)做為起點。
+ 請小心偵錯或記錄陳述式。他們可以將資訊寫入 Amazon CloudWatch Logs。確保日誌不包含敏感資訊。

  如需日誌陳述式範例，請參閱[AWS Secrets Manager 輪換函數範本](reference_available-rotation-templates.md)原始程式碼。
+ 為了安全起見， AWS Secrets Manager 只允許 Lambda 輪換函數直接輪換秘密。輪換函數無法呼叫另一個 Lambda 函數來輪換秘密。
+ 如需偵錯指引，請參閱[測試和偵錯無伺服器應用程式](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-test-and-debug.html)。
+ 如果您使用外部二進位檔和程式庫，例如連接到資源，則需負責修補和更新它們。
+ 將您的輪換函數和任何相依性封裝在 ZIP 檔案中，例如 *my-function.zip*。

**警告**  
將佈建並行參數設定為低於 10 的值，可能會導致因為 Lambda 函數的執行執行緒不足而導致限流。如需詳細資訊，請參閱《 AWS Lambda 開發人員指南》中的 AWS Lambda [了解預留並行和佈建並行](https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html#reserved-and-provisioned)。

## 輪換函數中的四個步驟
<a name="rotate-secrets_lambda-functions-code"></a>

**Topics**
+ [`createSecret`：建立新的秘密版本](#w2aac21c11c29c11b5)
+ [**setSecret**：變更資料庫或服務中的登入資料](#w2aac21c11c29c11b7)
+ [**testSecret**：測試新的秘密版本](#w2aac21c11c29c11b9)
+ [**finishSecret**：完成輪換](#w2aac21c11c29c11c11)

### `createSecret`：建立新的秘密版本
<a name="w2aac21c11c29c11b5"></a>

方法`createSecret`會先透過[https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_secret_value](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_secret_value)使用傳入 呼叫 來檢查秘密是否存在`ClientRequestToken`。如果沒有秘密，它會使用 建立新的秘密，[https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.create_secret](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.create_secret)並將字符作為 `VersionId`。然後，它會使用 產生新的秘密值[https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_random_password](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.get_random_password)。接下來，它會呼叫 [https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.put_secret_value](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.put_secret_value)，將其與預備標籤 一起存放`AWSPENDING`。將新的秘密值儲存在 `AWSPENDING` 中，有助於確保等冪性。如果輪換因任何原因而失敗，您可以在後續呼叫中參考該秘密值。請參閱 [How do I make my Lambda function idempotent](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/) (如何讓 Lambda 函數等冪)。

**撰寫您自己的輪換函數的提示**
+ 確保新的秘密值僅包含對資料庫或服務有效的字元。使用 `ExcludeCharacters` 參數排除字元。
+ 當您測試函數時，請使用 AWS CLI 查看版本階段：呼叫 [https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/describe-secret.html](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/describe-secret.html)並查看 `VersionIdsToStages`。
+ 對於 Amazon RDS MySQL，在交替使用者輪換時，Secrets Manager 會建立名稱不超過 16 個字元的複製使用者。您可以修改旋轉功能以允許更長的用戶名。MySQL 版本 5.7 及更高版本支持用戶名最多 32 個字符，但是 Secrets Manager 附加「\$1clone」（六個字符）到用戶名的末尾，所以你必須保持用戶名最多 26 個字符。

### **setSecret**：變更資料庫或服務中的登入資料
<a name="w2aac21c11c29c11b7"></a>

方法會`setSecret`變更資料庫或服務中的登入資料，以符合秘密`AWSPENDING`版本中的新秘密值。

**撰寫您自己的輪換函數的提示**
+ 如果您將陳述式傳遞給解譯陳述式的服務，例如資料庫，請使用查詢參數化。如需詳細資訊，請參閱 *OWASP 網站上的*[查詢參數摘要](https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html)。
+ 輪換函數是具有特殊權限的代理人，有權存取和修改 Secrets Manager 秘密和目標資源中的客戶憑證。為了防止潛在的[混淆代理人攻擊](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)，您必須確保攻擊者無法使用該函數存取其他資源。在您更新憑證之前：
  + 查看 `AWSCURRENT` 版本秘密中的憑證是否有效。如果 `AWSCURRENT` 憑證無效，請放棄輪換嘗試。
  + 查看 `AWSCURRENT` 和 `AWSPENDING` 秘密值是否針對相同的資源。對於使用者名稱和密碼，請查看 `AWSCURRENT` 和 `AWSPENDING` 使用者名稱是否相同。
  + 檢查目的地服務資源是否相同。對於資料庫，請查看 `AWSCURRENT` 和 `AWSPENDING` 主機名稱是否相同。
+ 在極少數情況下，您可能想要自訂資料庫的現有輪換函數。例如，使用者交替輪換時，Secrets Manager 會複製第一個使用者的[執行期組態參數](https://www.postgresql.org/docs/8.0/runtime-config.html)來建立複製的使用者。如果您想要包含更多屬性，或變更哪些屬性以授予複製的使用者，則需要更新 `set_secret` 函數中的程式碼。

### **testSecret**：測試新的秘密版本
<a name="w2aac21c11c29c11b9"></a>

接下來，Lambda 輪換函數會使用 `AWSPENDING` 版本的秘密存取資料庫或服務，以進行測試。根據 [輪換函數範本](reference_available-rotation-templates.md) 建立的輪換函數會使用讀取權限測試新的秘密。

### **finishSecret**：完成輪換
<a name="w2aac21c11c29c11c11"></a>

最後，Lambda 輪換函數會將標籤 `AWSCURRENT` 從先前的秘密版本移至此版本，這也會移除相同 API 呼叫中的 `AWSPENDING` 標籤。Secrets Manager 會將 `AWSPREVIOUS` 預備標籤新增至先前版本，以便您保留上一個已知良好的秘密版本。

方法**finish\$1secret**使用 將預備標籤`AWSCURRENT`從先前的秘密版本[https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.update_secret_version_stage](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.update_secret_version_stage)移至新的秘密版本。Secrets Manager 會自動將 `AWSPREVIOUS` 預備標籤新增至先前版本，以便您保留上一個已知良好的秘密版本。

**撰寫您自己的輪換函數的提示**
+ 在此`AWSPENDING`之前，請勿移除 ，也不要使用單獨的 API 呼叫來移除它，因為這可能會向 Secrets Manager 指出輪換未成功完成。Secrets Manager 會將 `AWSPREVIOUS` 預備標籤新增至先前版本，以便您保留上一個已知良好的秘密版本。

輪換成功時，`AWSPENDING` 預備標籤可能會連接至與 `AWSCURRENT` 版本相同的版本，或者可能未連接至任何版本。如果 `AWSPENDING` 預備標籤存在，但未連接至與 `AWSCURRENT` 相同的版本，則任何以後的輪換調用都會假定之前的輪換請求仍在進行中並傳回錯誤。輪換不成功時，`AWSPENDING` 預備標籤可能會連接至空的機密版本。如需詳細資訊，請參閱[輪換疑難排解](troubleshoot_rotation.md)。