

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

# 使用 Terraform 在 AWS Organizations 中集中管理 IAM 存取金鑰
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform"></a>

*Pradip kumar Pandey 和 Pratap Kumar Nanda，Amazon Web Services*

## 摘要
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-summary"></a>

強制執行金鑰和密碼的安全規則是每個組織** **的必要任務。其中一個 重要規則是定期輪換 AWS Identity and Access Management (IAM) 金鑰，以強制執行安全性。當團隊想要從 AWS 命令列界面** **(AWS CLI) 或從 AWS 外部應用程式存取 AWS 時，通常會在本機建立和設定 AWS 存取金鑰。若要在整個組織中維持強大的安全性，必須在滿足需求後或定期變更或刪除舊的安全金鑰。管理組織中多個帳戶間金鑰輪換的程序既耗時又繁瑣。此模式使用 Account Factory for Terraform (AFT) 和 AWS 服務，協助您自動化輪換程序。

模式提供以下優點：
+ 從中央位置管理組織中所有帳戶的存取金鑰 IDs 和私密存取金鑰。
+ 自動輪換 `AWS_ACCESS_KEY_ID`和 `AWS_SECRET_ACCESS_KEY`環境變數。
+ 如果使用者登入資料洩露，則強制執行續約。

模式使用 Terraform 來部署 AWS Lambda 函數、Amazon EventBridge 規則和 IAM 角色。EventBridge 規則會定期執行，並呼叫 Lambda 函數，根據其建立時間列出所有使用者存取金鑰。如果先前的金鑰早於您定義的輪換期間 （例如 45 天），其他 Lambda 函數會建立新的存取金鑰 ID 和私密存取金鑰，並使用 Amazon Simple Notification Service (Amazon SNS) 和 Amazon Simple Email Service (Amazon SES) 通知安全管理員。秘密是在該使用者的 AWS Secrets Manager 中建立的，舊的秘密存取金鑰儲存在 Secrets Manager 中，並設定存取舊金鑰的許可。為了確保不再使用舊的存取金鑰，會在非作用中期間 （例如 60 天，也就是在我們的範例中輪換金鑰後 15 天） 之後停用。在非作用中緩衝期間 （例如，在我們的範例中輪換金鑰後 90 天或 45 天） 之後，舊的存取金鑰會從 AWS Secrets Manager 中刪除。如需詳細的架構和工作流程，請參閱[架構](#centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-architecture)一節。

## 先決條件和限制
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-prereqs"></a>
+ 使用 [AWS Control Tower ](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html)(3.1 版或更新版本） 為組織建置的登陸區域
+  使用三個[帳戶設定的 Account Factory for Terraform (AFT)](https://catalog.workshops.aws/control-tower/en-US/customization/aft)：
  + [組織管理帳戶](https://catalog.workshops.aws/control-tower/en-US/customization/aft/repositories/global-customizations)會從中央位置管理整個組織。
  + [AFT 管理帳戶](https://catalog.workshops.aws/control-tower/en-US/customization/aft/repositories/account-customizations) 託管 Terraform 管道，並將基礎設施部署到部署帳戶中。
  + [部署帳戶](https://catalog.workshops.aws/control-tower/en-US/customization/aft/repositories/provisioning-customizations)會部署此完整的解決方案，並從中央位置管理 IAM 金鑰。
+ Terraform 0.15.0 版或更新版本， 用於在部署帳戶中佈建基礎設施。
+ 在 [Amazon Simple Email Service (Amazon SES](https://aws.amazon.com/ses/)中設定的電子郵件地址。
+ （建議） 若要增強安全性，請在[虛擬](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest)[私有雲端 (VPC) 內的私有子網路](https://docs.aws.amazon.com/vpc/latest/userguide/create-subnets.html) （部署帳戶） 內部署此解決方案。您可以在自訂變數時提供 VPC 和子網路的詳細資訊 （請參閱 [Epics](#centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-epics) 區段中的*程式碼管道自訂參數*)。

## Architecture
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-architecture"></a>

**AFT 儲存庫**

此模式使用 Account Factory for Terraform (AFT) 建立所有必要的 AWS 資源和程式碼管道，以在部署帳戶中部署資源。程式碼管道在兩個儲存庫中執行：
+ **全域自訂**包含 Terraform 程式碼，該程式碼將在向 AFT 註冊的所有帳戶中執行。
+ **帳戶自訂**包含將在部署帳戶中執行的 Terraform 程式碼。

**資源詳細資訊**

AWS CodePipeline 任務會在部署帳戶中建立下列資源：
+ AWS EventBridge 規則和設定的規則
+ `account-inventory` Lambda 函數
+ `IAM-access-key-rotation` Lambda 函數
+ `Notification` Lambda 函數
+ 包含電子郵件範本的 Amazon Simple Storage Service (Amazon S3) 儲存貯體
+ 必要的 IAM 政策

**架構**

![在 AWS Organizations 中集中 IAM 存取金鑰管理的架構](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/0217275c-cb4c-4bdf-b105-ad9abfd4fded/images/844512f0-67b3-4d41-aaaa-fbd9e341c438.png)


此圖展示了以下要點：

1. EventBridge 規則每 24 小時呼叫 `account-inventory` Lambda 函數。

1. `account-inventory` Lambda 函數會查詢 AWS Organizations，以取得所有 AWS 帳戶 IDs、帳戶名稱和帳戶電子郵件的清單。 

1. `account-inventory` Lambda 函數會為每個 AWS 帳戶啟動 `IAM-access-key-auto-rotation` Lambda 函數，並將中繼資料傳遞給它以進行其他處理。

1. `IAM-access-key-auto-rotation` Lambda 函數使用擔任的 IAM 角色來存取 AWS 帳戶。Lambda 指令碼會對帳戶中的所有使用者及其 IAM 存取金鑰執行稽核。

1. 部署 `IAM-access-key-auto-rotation` Lambda 函數時，IAM 金鑰輪換閾值 （輪換期間） 會設定為環境變數。如果修改輪換期間，則會使用更新的環境變數重新部署 `IAM-access-key-auto-rotation` Lambda 函數。您可以設定參數來設定輪換期間、舊金鑰的非作用中期間，以及刪除舊金鑰之後的非作用中緩衝區 （請參閱 [Epics](#centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-epics) 區段中的*程式碼管道自訂參數*)。

1. `IAM-access-key-auto-rotation` Lambda 函數會根據存取金鑰的組態來驗證存取金鑰的存留期。如果 IAM 存取金鑰的存留期未超過您定義的輪換期間，Lambda 函數不會採取進一步動作。

1. 如果 IAM 存取金鑰的存留期已超過您定義的輪換期間，`IAM-access-key-auto-rotation`Lambda 函數會建立新的金鑰並輪換現有的金鑰。

1. Lambda 函數會將舊金鑰儲存在 Secrets Manager 中，並將許可限制為存取金鑰偏離安全標準的使用者。Lambda 函數也會建立資源型政策，僅允許指定的 IAM 主體存取和擷取秘密。

1. `IAM-access-key-rotation` Lambda 函數會呼叫 `Notification` Lambda 函數。

1. `Notification` Lambda 函數會查詢電子郵件範本的 S3 儲存貯體，並動態產生具有相關活動中繼資料的電子郵件訊息。

1. `Notification` Lambda 函數會呼叫 Amazon SES 以進行進一步的動作。

1.  Amazon SES 會傳送電子郵件到帳戶擁有者的電子郵件地址，其中包含相關資訊。

## 工具
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-tools"></a>

**AWS 服務**
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 可透過控制已驗證並獲授權使用的人員，協助您安全地管理對 AWS 資源的存取。此模式需要 IAM 角色和許可。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一種運算服務，可協助您執行程式碼，而無需佈建或管理伺服器。它只會在需要時執行程式碼並自動擴展，因此您只需按使用的運算時間付費。
+ [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 可協助您以 API 呼叫 Secrets Manager，以程式設計方式擷取秘密，取代程式碼中的硬式編碼登入資料，包括密碼。
+ [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/ses/latest/dg/Welcome.html) 可協助您使用自己的電子郵件地址和網域來傳送和接收電子郵件。

**其他工具**
+ [Terraform](https://www.terraform.io/) 是 HashiCorp 的基礎設施即程式碼 (IaC) 工具，可協助您建立和管理雲端和內部部署資源。

**程式碼儲存庫**

此模式的說明和程式碼可在 GitHub [IAM 存取金鑰輪換](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform.git)儲存庫中取得。您可以在 AWS Control Tower 中央部署帳戶中部署程式碼，從中央位置管理金鑰輪換。

## 最佳實務
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-best-practices"></a>
+ 對於 IAM，請參閱 IAM 文件中的[安全最佳實務](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。
+ 如需金鑰輪換，請參閱 IAM 文件中的[更新存取金鑰準則](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials)。

## 史詩
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-epics"></a>

### 設定來源檔案
<a name="set-up-source-files"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 複製儲存庫。 | 1. 複製 [IAM 存取金鑰輪換](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform.git) GitHub 儲存庫：<pre>$ git clone https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform.git</pre><br />2. 確認儲存庫的本機副本包含三個資料夾：<pre>$ cd Iam-Access-keys-Rotation<br />$ ls<br />org-account-customization<br />global-account-customization<br />account-customization</pre> | DevOps 工程師 | 

### 設定帳號
<a name="configure-accounts"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 設定引導帳戶。 | 作為 [AFT 引導](https://catalog.workshops.aws/control-tower/en-US/customization/aft/deploy)程序的一部分，您應該在本機電腦上有一個名為 `aft-bootstrap`的資料夾。1. 手動將所有 Terraform 檔案從本機 GitHub [org-account-customization](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform/tree/main/org-account-customization) 資料夾複製到您的`aft-bootstrap`資料夾。<br />2. 執行 Terraform 命令以在 AWS Control Tower 管理帳戶中設定全域跨帳戶角色：<pre>$ cd aft-bootstrap<br />$ terraform init<br />$ terraform apply —auto-approve</pre> | DevOps 工程師 | 
| 設定全域自訂。 | 作為 [AFT 資料夾](https://catalog.workshops.aws/control-tower/en-US/customization/aft/repositories/global-customizations)設定的一部分，您應該在本機電腦上有一個名為 `aft-global-customizations`的資料夾。1. 手動將所有 Terraform 檔案從本機 GitHub [global-account-customization](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform/tree/main/global-account-customization) 資料夾複製到您的`aft-global-customizations/terraform`資料夾。<br />2. 將程式碼推送至 AWS CodeCommit：<pre>$ git add *<br />$ git commit -m "message"<br />$ git push</pre> | DevOps 工程師 | 
| 設定帳戶自訂。 | 作為 [AFT 資料夾設定](https://catalog.workshops.aws/control-tower/en-US/customization/aft/repositories/account-customizations)的一部分，您在本機電腦上有一個名為 `aft-account-customizations`的資料夾。1. 使用您提供的帳號建立資料夾。<br />2. 手動將所有 Terraform 檔案從本機 GitHub [帳戶自訂](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform/tree/main/account-customization)資料夾複製到您的`aft-account-customizations/<vended account>/terraform`資料夾。<br />3. 將程式碼推送至 AWS CodeCommit：<pre>$ git add *<br />$ git commit -m "message"<br />$ git push</pre> | DevOps 工程師 | 

### 自訂程式碼管道的參數
<a name="customize-parameters-for-the-code-pipeline"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 為所有帳戶自訂非 Terraform 程式碼管道參數。 | 在 `aft-global-customizations/terraform/` 資料夾中建立名為 `input.auto.tfvars` 的檔案，並提供所需的輸入資料。如需預設值[，請參閱 GitHub 儲存庫中的 檔案](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform/blob/main/global-account-customization/input.auto.tfvars)。 | DevOps 工程師 | 
| 自訂部署帳戶的程式碼管道參數。 | 在 `aft-account-customizations/<AccountName>/terraform/` 資料夾中建立名為 `input.auto.tfvars` 的檔案，並將程式碼推送至 AWS CodeCommit。將程式碼推送至 AWS CodeCommit 會自動啟動程式碼管道。<br />根據組織的需求指定參數的值，包括下列項目 （請參閱 [Github 儲存庫中的 檔案](https://github.com/aws-samples/centralized-iam-key-management-aws-organizations-terraform/blob/main/account-customization/input.auto.tfvars)以取得預設值）：+ `s3_bucket_name` – 電子郵件範本的唯一儲存貯體名稱。<br />+ `s3_bucket_prefix` – S3 儲存貯體內的資料夾名稱。<br />+ `admin_email_address` – 應接收通知之管理員的電子郵件地址。<br />+ `org_list_account` – 管理帳戶的帳號。<br />+ `rotation_period` – 金鑰應該從作用中輪換到非作用中的天數。<br />+ `inactive_period` – 輪換金鑰應停用的天數。此值必須大於 的值`rotation_period`。<br />+ `inactive_buffer` – 輪換與停用金鑰之間的寬限期。<br />+ `recovery_grace_period` – 停用和刪除金鑰之間的寬限期。<br />+ `dry_run_flag` – 如果您想要將通知傳送給管理員進行測試，而不輪換金鑰，請將 設為 **true**。<br />+ `store_secrets_in_central_account` – 如果您想要將秘密存放在部署帳戶中，請將 設為 **true**。如果變數設定為 **false** （預設），則秘密會存放在成員帳戶中。<br />+ `credential_replication_region` – 您要部署 Lambda 函數的 AWS 區域，以及電子郵件範本的 S3 儲存貯體。<br />+ `run_lambda_in_vpc` – 設為 **true** 以在 VPC 內執行 Lambda 函數。<br />+ `vpc_id` – 部署帳戶的 VPC ID，如果您想要在 VPC 內執行 Lambda 函數。<br />+ `vpc_cidr` – 部署帳戶的 CIDR 範圍。<br />+ `subnet_id` – 部署帳戶的子網路 IDs。<br />+ `create_smtp_endpoint` – 如果您想要啟用電子郵件端點，請將 設定為 **true**。 | DevOps 工程師 | 

### 驗證金鑰輪換
<a name="validate-key-rotation"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 驗證解決方案。 | 1. 從 AWS 管理主控台登入部署帳戶。<br />2. 開啟 [IAM 主控台](https://console.aws.amazon.com/iam/)，並檢查使用者登入資料 （存取金鑰 IDs和私密金鑰） 是否依指定輪換。<br />3. 輪換 IAM 金鑰之後，請確認下列事項：舊值會儲存在 AWS Secrets Manager 中。秘密名稱的格式為 `Account_<account ID>_User_<username>_AccessKey`。您在 `admin_email_address` 參數中指定的使用者會收到有關金鑰輪換的電子郵件通知。 | DevOps 工程師 | 

### 擴展解決方案
<a name="extend-the-solution"></a>


| 任務 | 說明 | 所需的技能 | 
| --- | --- | --- | 
| 自訂電子郵件通知日期。 | 如果您想要在停用存取金鑰之前的特定日期傳送電子郵件通知，您可以使用這些變更來更新 `IAM-access-key-auto-rotation` Lambda 函數：1. 定義名為 的變數`notify-period`。<br />2. 在 中新增`if`條件，`main.py`再停用金鑰：<pre>If (keyage>rotation-period-notify-period){<br />  send_to_notifier(context, aws_account_id, account_name, resource_owner,<br />resource_actions[resource_owner], dryrun, config.emailTemplateAudit)<br />}</pre> | DevOps 工程師 | 

## 疑難排解
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-troubleshooting"></a>


| 問題 | 解決方案 | 
| --- | --- | 
| `account-inventory` Lambda 任務在列出帳戶`AccessDenied`時失敗。 | 如果您遇到此問題，您必須驗證許可：1. 登入新付費帳戶，開啟 [Amazon CloudWatch 主控台](https://console.aws.amazon.com/cloudwatch/)，然後檢視 CloudWatch 日誌群組 `/aws/lambda/account-inventory-lambda`。<br />2. 在最新的 CloudWatch 日誌中，識別導致存取遭拒問題的帳號。<br />3. 登入 AWS Control Tower 管理帳戶並確認`allow-list-account`已建立角色。<br />4. 如果角色不存在，請使用 `terraform apply`命令重新執行 Terraform 程式碼。<br />5. 選擇**信任的帳戶**索引標籤，並驗證相同的帳戶是否受信任。 | 

## 相關資源
<a name="centralize-iam-access-key-management-in-aws-organizations-by-using-terraform-resources"></a>
+ [Terraform 建議實務](https://developer.hashicorp.com/terraform/cloud-docs/recommended-practices) (Terraform 文件）
+ [IAM 中的安全最佳實務 ](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)(IAM 文件）
+ [金鑰輪換的最佳實務 ](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials)(IAM 文件）