

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

# 安全最佳實務
<a name="security"></a>

正確管理身分驗證、存取控制和安全性對於 Terraform AWS 提供者的安全使用至關重要。本節概述以下方面的最佳實務：
+ 最低權限存取的 IAM 角色和許可
+ 保護登入資料，以協助防止未經授權存取 AWS 帳戶和資源
+ 遠端狀態加密，以協助保護敏感資料
+ 基礎設施和原始程式碼掃描以識別組態錯誤
+ 遠端狀態儲存的存取控制
+ 實作控管護欄的 Sentinel 政策強制執行

當您使用 Terraform 管理 AWS 基礎設施時，遵循這些最佳實務有助於強化您的安全狀態。

## 遵循最低權限原則
<a name="least-privilege"></a>

[最低權限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)是基本安全原則，是指僅授予使用者、程序或系統執行其預期功能所需的最低許可。這是存取控制的核心概念，也是防止未經授權的存取和潛在資料外洩的預防措施。

本節多次強調最低權限原則，因為它直接與 Terraform 對雲端提供者進行身分驗證和執行動作的方式相關，例如 AWS。

當您使用 Terraform 佈建和管理 AWS 資源時，它會代表需要適當許可才能進行 API 呼叫的實體 （使用者或角色）。未遵循最低權限會開啟主要安全風險：
+ 如果 Terraform 具有超出所需範圍的過多許可，意外的錯誤組態可能會進行不必要的變更或刪除。
+ 如果 Terraform 狀態檔案或登入資料遭到入侵，過度寬鬆的存取授權會增加影響範圍。
+ 未遵循最低權限會違反安全最佳實務和法規合規要求，以授予最低必要存取權。

## 使用 IAM 角色
<a name="iam-roles"></a>

盡可能使用 IAM 角色而非 IAM 使用者來增強 Terraform AWS 提供者的安全性。IAM 角色提供可自動輪換的臨時安全登入資料，因此無需管理長期存取金鑰。角色也透過 IAM 政策提供精確的存取控制。

### 使用 IAM 政策授予最低權限存取
<a name="iam-policies"></a>

仔細建構 IAM 政策，以確保角色和使用者只有工作負載所需的最低許可集。從空白政策開始，並反覆新增允許的服務和動作。若要完成此操作：
+ 啟用 [IAM Access Analyzer](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-policy-generation.html#access-analyzer-policy-generation-console) 以評估政策，並反白可移除的未使用許可。
+ 手動檢閱政策，以移除對角色的預期責任不重要的任何功能。
+ 使用 [IAM 政策變數和標籤](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html)來簡化許可管理。

建構良好的政策只授予足夠的存取權，以履行工作負載的責任，而且沒有其他任何功能。在操作層級定義動作，並僅允許呼叫特定資源上所需的 APIs。

遵循此最佳實務可減少影響範圍，並遵循職責分離和最低權限存取的基本安全原則。視需要逐漸開始嚴格且開放的存取，而不是開始開放並稍後嘗試限制存取。

### 擔任本機身分驗證的 IAM 角色
<a name="local-authorization"></a>

當您在本機執行 Terraform 時，請避免設定靜態存取金鑰。反之，請使用 [IAM 角色暫時授予特殊權限存取](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)，而不會暴露長期憑證。

首先，建立具有必要最低許可的 IAM 角色，並新增[信任關係](https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/)，以允許您的使用者帳戶或聯合身分擔任 IAM 角色。這會授權暫時使用 角色。

信任關係政策範例：

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/terraform-execution"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

然後，執行 AWS CLI 命令 **aws sts assume-role** 來擷取角色的短期登入資料。這些登入資料通常有效一小時。

AWS CLI 命令範例：

```
aws sts assume-role --role-arn arn:aws:iam::111122223333:role/terraform-execution --role-session-name terraform-session-example
```

命令的輸出包含存取金鑰、私密金鑰和工作階段字符，可用於驗證 AWS：

```
{
    "AssumedRoleUser": {
        "AssumedRoleId": "AROA3XFRBF535PLBIFPI4:terraform-session-example",
        "Arn": "arn:aws:sts::111122223333:assumed-role/terraform-execution/terraform-session-example"
    },
    "Credentials": {
        "SecretAccessKey": " wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
        "SessionToken": " AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE",
        "Expiration": "2024-03-15T00:05:07Z",
        "AccessKeyId": "ASIAIOSFODNN7EXAMPLE"
    }
}
```

 AWS 提供者也可以自動處理[擔任該角色](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#assuming-an-iam-role)。

擔任 IAM 角色的提供者組態範例：

```
provider "aws" {
  assume_role {
    role_arn     = "arn:aws:iam::111122223333:role/terraform-execution"
    session_name = "terraform-session-example"
  }
}
```

這會在 Terraform 工作階段的持續時間嚴格授予更高的權限。臨時金鑰無法洩漏，因為它們會在工作階段的最長持續時間之後自動過期。

相較於長期存取金鑰，此最佳實務的主要優點包括改善安全性、以最低權限對角色進行精細存取控制，以及透過修改角色的許可輕鬆撤銷存取權。透過使用 IAM 角色，您也可以避免將秘密直接儲存在本機的指令碼或磁碟上，這可協助您在團隊之間安全地共用 Terraform 組態。

### 使用 IAM 角色進行 Amazon EC2 身分驗證
<a name="ec2-authentication"></a>

當您從 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體執行 Terraform 時，請避免在本機存放長期憑證。反之，請使用 IAM 角色和[執行個體描述](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)檔自動授予最低權限許可。

首先，建立具有最低許可的 IAM 角色，並將該角色指派給執行個體描述檔。執行個體描述檔允許 EC2 執行個體繼承角色中定義的許可。然後，透過指定執行個體描述檔來啟動執行個體。執行個體將透過連接的 角色進行身分驗證。

執行任何 Terraform 操作之前，請確認[執行個體中繼資料](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html)中存在該角色，以確認登入資料已成功繼承。

```
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
```

此方法可避免將永久 AWS 金鑰硬式編碼為執行個體內的指令碼或 Terraform 組態。臨時登入資料會透過執行個體角色和設定檔，以透明方式提供給 Terraform。

此最佳實務的主要優點包括改善長期憑證的安全性、降低憑證管理開銷，以及開發、測試和生產環境之間的一致性。IAM 角色身分驗證可簡化從 EC2 執行個體執行的 Terraform，同時強制執行最低權限存取。

### 針對 HCP Terraform 工作區使用動態登入資料
<a name="dynamic-credentials"></a>

HCP Terraform 是由 HashiCorp 提供的受管服務，可協助團隊使用 Terraform 跨多個專案和環境佈建和管理基礎設施。當您在 HCP Terraform 中執行 Terraform 時，請使用[動態登入](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/aws-configuration)資料來簡化和保護 AWS 身分驗證。Terraform 會在每次執行時自動交換臨時登入資料，而不需要擔任 IAM 角色。

優點包括更輕鬆的秘密輪換、跨工作區的集中式憑證管理、最低權限許可，以及消除硬式編碼金鑰。相較於長期存取金鑰，依賴雜湊暫時性金鑰可增強安全性。

### 在 中使用 IAM 角色 AWS CodeBuild
<a name="codebuild"></a>

在 中 AWS CodeBuild，使用[指派給 CodeBuild 專案的 IAM 角色](https://docs.aws.amazon.com/codebuild/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html)來執行您的組建。這可讓每個組建自動從角色繼承臨時登入資料，而不是使用長期金鑰。

### 在 HCP Terraform 上遠端執行 GitHub 動作
<a name="github-actions"></a>

設定 GitHub 動作工作流程以在 HCP Terraform 工作區上遠端執行 Terraform。依賴動態登入資料和遠端狀態鎖定，而不是 GitHub 秘密管理。

### 搭配 OIDC 使用 GitHub 動作並設定 AWS 登入資料動作
<a name="oidc"></a>

使用 [OpenID Connect (OIDC) 標準透過 IAM 聯合 GitHub Actions 身分](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)。使用[設定 AWS 登入資料動作](https://github.com/aws-actions/configure-aws-credentials)，將 GitHub 字符交換為臨時 AWS 登入資料，而不需要長期存取金鑰。

### 搭配 OIDC 和 使用 GitLab AWS CLI
<a name="gitlab"></a>

使用 [OIDC 標準透過 IAM 聯合 GitLab 身分](https://docs.gitlab.com/ee/ci/cloud_services/aws/)以進行暫時存取。透過依賴 OIDC，您可以避免在 GitLab 中直接管理長期 AWS 存取金鑰。登入資料會just-in-time交換，以改善安全性。使用者也會根據 IAM 角色中的許可取得最低權限存取。

## 搭配舊版自動化工具使用唯一的 IAM 使用者
<a name="legacy-automation-tools"></a>

如果您有自動化工具和指令碼，缺乏使用 IAM 角色的原生支援，您可以建立個別 IAM 使用者來授予程式設計存取權。最低權限原則仍然適用。將政策許可降至最低，並依賴每個管道或指令碼的個別角色。當您遷移到更現代化的工具或指令碼時，請開始原生支援角色，並逐漸轉換到這些角色。

**警告**  
IAM 使用者具有長期登入資料，這會造成安全風險。為了協助降低此風險，建議您只為這些使用者提供執行任務所需的許可，並在不再需要這些使用者時將其移除。

### 使用 Jenkins AWS 登入資料外掛程式
<a name="jenkins"></a>

使用 Jenkins 中的[AWS 登入資料外掛程式](https://plugins.jenkins.io/aws-credentials/)，以動態方式將 AWS 登入資料集中設定和插入組建。這可避免將秘密檢查為來源控制。

## 持續監控、驗證和最佳化最低權限
<a name="continuous-monitoring"></a>

隨著時間的推移，可能會授予可能超過所需最低政策的額外許可。持續分析存取權，以識別和移除任何不必要的權利。

### 持續監控存取金鑰用量
<a name="access-key"></a>

如果您無法避免使用存取金鑰，請使用 [IAM 憑證報告](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html)來尋找超過 90 天的未使用存取金鑰，以及撤銷使用者帳戶和機器角色的非作用中金鑰。提醒管理員手動確認移除作用中員工和系統的金鑰。

監控金鑰用量可協助您最佳化許可，因為您可以識別和移除未使用的權利。當您遵循此最佳實務進行[存取金鑰輪換](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_RotateAccessKey)時，會限制登入資料生命週期並強制執行最低權限存取。

AWS 提供數種服務和功能，您可以用來設定管理員的提醒和通知。以下是一些選項：
+ [AWS Config](https://aws.amazon.com/config/)：您可以使用 AWS Config 規則來評估 AWS 資源的組態設定，包括 IAM 存取金鑰。您可以建立自訂規則來檢查特定條件，例如早於特定天數的未使用存取金鑰。違反規則時， AWS Config 可以開始評估修補或傳送通知到 Amazon Simple Notification Service (Amazon SNS) 主題。
+ [AWS Security Hub CSPM](https://aws.amazon.com/security-hub/)：Security Hub CSPM 提供 AWS 帳戶安全狀態的完整檢視，並可協助偵測和通知您潛在的安全問題，包括未使用或非作用中的 IAM 存取金鑰。Security Hub CSPM 可以在聊天應用程式中與 Amazon EventBridge 和 Amazon SNS 或 Amazon Q Developer 整合，以傳送通知給管理員。
+ [AWS Lambda](https://aws.amazon.com/lambda/)：Lambda 函數可以由各種事件呼叫，包括 Amazon CloudWatch Events 或 AWS Config 規則。您可以在聊天應用程式中使用 Amazon SNS 或 Amazon Q Developer 等服務，撰寫自訂 Lambda 函數來評估 IAM 存取金鑰用量、執行其他檢查和傳送通知。

### 持續驗證 IAM 政策
<a name="iam-policies"></a>

使用 [IAM Access Analyzer](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-policy-generation.html#access-analyzer-policy-generation-console) 評估連接到角色的政策，並識別任何未使用的服務或授予的多餘動作。實作定期存取檢閱，以手動驗證政策是否符合目前的需求。

比較現有政策與 IAM Access Analyzer 產生的政策，並移除任何不必要的許可。您也應該向使用者提供報告，並在寬限期後自動撤銷未使用的許可。這有助於確保最少的政策保持有效。

主動且頻繁地撤銷過時的存取，可將違規期間可能面臨風險的登入資料降至最低。自動化提供永續、長期的憑證衛生和許可最佳化。遵循此最佳實務會主動強制執行 AWS 身分和資源的最低權限，以限制影響範圍。

## 安全的遠端狀態儲存
<a name="remote-state-storage"></a>

[遠端狀態儲存](https://developer.hashicorp.com/terraform/language/state/remote)是指遠端儲存 Terraform 狀態檔案，而不是在執行 Terraform 的機器上本機儲存。狀態檔案至關重要，因為它會追蹤 Terraform 佈建的資源及其中繼資料。

無法保護遠端狀態可能會導致嚴重問題，例如遺失狀態資料、無法管理基礎設施、意外刪除資源，以及暴露狀態檔案中可能存在的敏感資訊。因此，保護遠端狀態儲存對於生產級 Terraform 使用至關重要。

### 啟用加密和存取控制
<a name="encryption"></a>

使用 Amazon Simple Storage Service (Amazon S3)[ 伺服器端加密 (SSE)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html) 加密靜態遠端狀態。

### 限制對協作工作流程的直接存取
<a name="collaborative-workflows"></a>
+ 在 HCP Terraform 中或在 Git 儲存庫中的 CI/CD 管道中建構協作工作流程，以限制直接狀態存取。
+ 依賴提取請求、執行核准、政策檢查和通知來協調變更。

遵循這些準則有助於保護敏感資源屬性，並避免與團隊成員的變更發生衝突。加密和嚴格的存取保護有助於減少攻擊面，協作工作流程可實現生產力。

## 使用 AWS Secrets Manager
<a name="secrets"></a>

Terraform 中有許多資源和資料來源，可將純文字中的秘密值存放在狀態檔案中。避免將秘密存放在 狀態 ― 請[AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)改用 。

不嘗試[手動加密敏感值](https://developer.hashicorp.com/terraform/plugin/best-practices/sensitive-state)，而是依賴 Terraform 內建的敏感狀態管理支援。匯出敏感值至輸出時，請確定這些值標示為[敏感](https://www.terraform.io/docs/configuration/outputs.html#sensitive-suppressing-values-in-cli-output)值。

## 持續掃描基礎設施和原始程式碼
<a name="iac-code"></a>

主動持續掃描基礎設施和原始程式碼，以找出暴露的登入資料或設定錯誤等風險，以強化您的安全狀態。重新設定或修補資源，以快速解決問題清單。

### 使用 AWS 服務進行動態掃描
<a name="dynamic-scanning"></a>

使用 AWS [Amazon Inspector](https://aws.amazon.com/inspector/)、[AWS Security Hub CSPM](https://aws.amazon.com/security-hub/)、[Amazon Detective](https://aws.amazon.com/detective/) 和 [Amazon GuardDuty](https://aws.amazon.com/guardduty/) 等原生工具來監控跨帳戶和區域的佈建基礎設施。在 Security Hub CSPM 中排程重複掃描，以追蹤部署和組態偏離。掃描 EC2 執行個體、Lambda 函數、容器、S3 儲存貯體和其他資源。

### 執行靜態分析
<a name="static-analysis"></a>

將 [Checkov](https://www.checkov.io/) 等靜態分析器直接嵌入 CI/CD 管道，以掃描 Terraform 組態碼 (HCL)，並在部署之前先識別風險。這會將安全檢查移至開發程序的較早時間點 （稱為*向左轉移*)，並防止基礎設施設定錯誤。

### 確保提示修復
<a name="remediation"></a>

對於所有掃描問題清單，請視需要更新 Terraform 組態、套用修補程式或手動重新設定資源，以確保立即修復。解決根本原因以降低風險等級。

使用基礎設施掃描和程式碼掃描，可跨 Terraform 組態、佈建的資源和應用程式程式碼提供分層洞見。這可透過預防性、偵測性和反應性控制來最大化風險與合規的涵蓋範圍，同時更早地將安全性嵌入軟體開發生命週期 (SDLC)。

## 強制執行政策檢查
<a name="policy-checks"></a>

使用 [HashiCorp Sentinel 政策](https://developer.hashicorp.com/terraform/tutorials/policy)等程式碼架構，提供控管防護機制和標準化範本，以使用 Terraform 進行基礎設施佈建。

Sentinel 政策可以定義 Terraform 組態的要求或限制，以符合組織標準和最佳實務。例如，您可以使用 Sentinel 政策來：
+ 需要所有資源上的標籤。
+ 將執行個體類型限制為核准清單。
+ 強制執行強制性變數。
+ 防止銷毀生產資源。

將政策檢查嵌入 Terraform 組態生命週期中，可主動強制執行標準和架構準則。Sentinel 提供共用政策邏輯，有助於加速開發，同時防止未經核准的實務。