

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

# 使用 AWS CodePipeline 建立 CI/CD 管道來驗證 Terraform 組態
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline"></a>

*Aromal Raj Jayarajan 和 Vijesh Vijayakumaran Nair，Amazon Web Services*

## 總結
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-summary"></a>

此模式示範如何使用 AWS CodePipeline 部署的持續整合和持續交付 (CI/CD) 管道來測試 HashiCorp Terraform 組態。

Terraform 是一種命令列界面應用程式，可協助您使用程式碼來佈建和管理雲端基礎設施和資源。此模式中提供的解決方案會建立 CI/CD 管道，協助您執行五個 [CodePipeline 階段](https://docs.aws.amazon.com/codepipeline/latest/userguide/concepts.html#concepts-stages)來驗證 Terraform 組態的完整性：

1. `"checkout"` 會從 AWS CodeCommit 儲存庫提取您正在測試的 Terraform 組態。

1. `"validate"` 會以程式碼 (IaC) 驗證工具的形式執行基礎設施，包括 [tfsec](https://github.com/aquasecurity/tfsec)、[TFLint](https://github.com/terraform-linters/tflint) 和 [checkov](https://www.checkov.io/)。階段也會執行下列 Terraform IaC 驗證命令： `terraform validate`和 `terraform fmt`。

1. `"plan"` 顯示如果套用 Terraform 組態，將套用哪些變更到基礎設施。

1. `"apply"` 使用產生的計劃在測試環境中佈建所需的基礎設施。

1. `"destroy"` 會移除在`"apply"`階段期間建立的測試基礎設施。

## 先決條件和限制
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-prereqs"></a>

**先決條件**
+ 作用中的 AWS 帳戶
+ AWS Command Line Interface (AWS CLI)，[已安裝](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)並[設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)
+ 在本機電腦上安裝和設定的 [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
+ 本機電腦上安裝和設定的 [Terraform](https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS)

**限制**
+ 此模式的方法只會將 AWS CodePipeline 部署到一個 AWS 帳戶和 AWS 區域。多帳戶和多區域部署需要變更組態。
+ 此模式佈建的 AWS Identity and Access Management (IAM) 角色 (**codepipeline\_iam\_role**) 遵循最低權限原則。此 IAM 角色的許可必須根據管道需要建立的特定資源進行更新。****

**產品版本**
+ AWS CLI 2.9.15 版或更新版本
+ Terraform 1.3.7 版或更新版本

## Architecture
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-architecture"></a>

**目標技術堆疊**
+ AWS CodePipeline
+ AWS CodeBuild
+ AWS CodeCommit
+ AWS IAM
+ Amazon Simple Storage Service (Amazon S3)
+ AWS Key Management Service (AWS KMS)
+ Terraform

**目標架構**

下圖顯示在 CodePipeline 中測試 Terraform 組態的範例 CI/CD 管道工作流程。

![使用 AWS CI/CD 管道測試 Terraform 組態的架構。](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/4df7b1f8-8eef-4d85-a971-a7f158be9691/images/90b931c8-e745-4b52-92de-a367fb0f1f51.png)


該圖顯示以下工作流程：

1. 在 CodePipeline 中，AWS 使用者透過在 AWS CLI 中執行 `terraform apply`命令，啟動 Terraform 計劃中提議的動作。

1. AWS CodePipeline 擔任 IAM 服務角色，其中包含存取 CodeCommit、CodeBuild、AWS KMS 和 Amazon S3 所需的政策。

1. CodePipeline 會執行`"checkout"`管道階段，從 AWS CodeCommit 儲存庫提取 Terraform 組態以供測試。

1. CodePipeline 會在 CodeBuild 專案中執行 IaC 驗證工具和執行 Terraform IaC 驗證命令，以執行`"validate"`階段來測試 Terraform 組態。

1. CodePipeline 會執行 `"plan"`階段，根據 Terraform 組態在 CodeBuild 專案中建立計畫。AWS 使用者可以在將變更套用至測試環境之前檢閱此計畫。

1. Code Pipeline 會執行`"apply"`階段來實作計畫，方法是使用 CodeBuild 專案在測試環境中佈建所需的基礎設施。

1. CodePipeline 會執行`"destroy"`階段，使用 CodeBuild 移除`"apply"`階段期間建立的測試基礎設施。

1. Amazon S3 儲存貯體會存放管道成品，這些成品會使用 AWS KMS [客戶受管金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk)進行加密和解密。

## 工具
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-tools"></a>

**工具**

*AWS 服務*
+ [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html) 可協助您快速建模和設定軟體版本的不同階段，並自動化持續發行軟體變更所需的步驟。
+ [AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) 是一種全受管的建置服務，可協助您編譯原始程式碼、執行單元測試，並產生準備好部署的成品。
+ [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html) 是一種版本控制服務，可協助您私下存放和管理 Git 儲存庫，而無需管理您自己的來源控制系統。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 可透過控制已驗證並獲授權使用的人員，協助您安全地管理對 AWS 資源的存取。
+ [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) 可協助您建立和控制密碼編譯金鑰，以協助保護您的資料。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) 是一種雲端型物件儲存服務，可協助您儲存、保護和擷取任何數量的資料。

*其他服務*
+ [HashiCorp Terraform](https://www.terraform.io/docs) 是一種命令列界面應用程式，可協助您使用程式碼來佈建和管理雲端基礎設施和資源。

**Code**

此模式的程式碼可在 GitHub [aws-codepipeline-terraform-cicdsamples](https://github.com/aws-samples/aws-codepipeline-terraform-cicd-samples) 儲存庫中使用。儲存庫包含建立此模式中概述之目標架構所需的 Terraform 組態。

## 史詩
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-epics"></a>

### 佈建解決方案元件
<a name="provision-the-solution-components"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 複製 GitHub 儲存庫。 | 在終端機視窗中執行下列命令，複製 GitHub[aws-codepipeline-terraform-cicdsamples](https://github.com/aws-samples/aws-codepipeline-terraform-cicd-samples)：<pre>git clone https://github.com/aws-samples/aws-codepipeline-terraform-cicd-samples.git</pre><br />如需詳細資訊，請參閱 GitHub 文件中的[複製儲存庫](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository)。 | DevOps 工程師 | 
| 建立 Terraform 變數定義檔案。 | 根據您的使用案例需求建立`terraform.tfvars`檔案。您可以更新複製儲存庫中`examples/terraform.tfvars`檔案中的變數。<br />如需詳細資訊，請參閱 Terraform 文件中的[將值指派給根模組變數](https://developer.hashicorp.com/terraform/language/values/variables#assigning-values-to-root-module-variables)。儲存庫的 `Readme.md` 檔案包含所需變數的詳細資訊。 | DevOps 工程師 | 
| 將 AWS 設定為 Terraform 提供者。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html)如需詳細資訊，請參閱 Terraform 文件中的 [AWS 提供者](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)。 | DevOps 工程師 | 
| 更新用於建立 Amazon S3 複寫儲存貯體的 Terraform 提供者組態。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html)複寫會在 Amazon S3 儲存貯體中啟用物件的自動非同步複製。 | DevOps 工程師 | 
| 初始化 Terraform 組態。 | 若要初始化包含 Terraform 組態檔案的工作目錄，請在複製的儲存庫根資料夾中執行下列命令：<pre>terraform init</pre> | DevOps 工程師 | 
| 建立 Terraform 計劃。 | 若要建立 Terraform 計劃，請在複製的儲存庫根資料夾中執行下列命令：<pre>terraform plan --var-file=terraform.tfvars -out=tfplan</pre>Terraform 會評估組態檔案，以判斷宣告資源的目標狀態。然後，它會比較目標狀態與目前狀態，並建立計劃。 | DevOps 工程師 | 
| 驗證 Terraform 計劃。 | 檢閱 Terraform 計劃，並確認它在您的目標 AWS 帳戶中設定所需的架構。 | DevOps 工程師 | 
| 部署解決方案。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html)Terraform 會建立、更新或銷毀基礎設施，以達到組態檔案中宣告的目標狀態。 | DevOps 工程師 | 

### 執行管道來驗證 Terraform 組態
<a name="validate-terraform-configurations-by-running-the-pipeline"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 設定原始程式碼儲存庫。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html) | DevOps 工程師 | 
| 驗證管道階段。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html)如需詳細資訊，請參閱《*AWS CodePipeline 使用者指南*》中的[檢視管道詳細資訊和歷史記錄 （主控台）](https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-view-console.html)。將變更遞交至來源儲存庫的主分支時，會自動啟用測試管道。 | DevOps 工程師 | 
| 驗證報告輸出。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html)`<project_name>-validate` CodeBuild 專案會在`"validate"`階段期間為您的程式碼產生漏洞報告。 | DevOps 工程師 | 

### 清除您的資源
<a name="clean-up-your-resources"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 清除管道和相關聯的資源。 | 若要從您的 AWS 帳戶刪除測試資源，請在複製的儲存庫根資料夾中執行下列命令：<pre>terraform destroy --var-file=terraform.tfvars</pre> | DevOps 工程師 | 

## 疑難排解
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-troubleshooting"></a>


| 問題 | 解決方案 | 
| --- | --- | 
| 您在`"apply"`階段期間收到 **AccessDenied **錯誤。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline.html) | 

## 相關資源
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-resources"></a>
+ [模組區塊](https://developer.hashicorp.com/terraform/language/modules/syntax) (Terraform 文件）
+ [如何使用 CI/CD 透過 Terraform 部署和設定 AWS 安全服務](https://aws.amazon.com/blogs/security/how-use-ci-cd-deploy-configure-aws-security-services-terraform/) (AWS 部落格文章）
+ [使用服務連結角色 ](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html)(IAM 文件）
+ [create-pipeline](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/codepipeline/create-pipeline.html) (AWS CLI 文件）
+ [針對存放在 Amazon S3 for CodePipeline 中的成品設定伺服器端加密](https://docs.aws.amazon.com/codepipeline/latest/userguide/S3-artifact-encryption.html) (AWS CodePipeline 文件）
+ [AWS CodeBuild 配額](https://docs.aws.amazon.com/codebuild/latest/userguide/limits.html) (AWS CodeBuild 文件）
+ [AWS CodePipeline 中的資料保護](https://docs.aws.amazon.com/codepipeline/latest/userguide/data-protection.html) (AWS CodePipeline 文件）

## 其他資訊
<a name="create-a-ci-cd-pipeline-to-validate-terraform-configurations-by-using-aws-codepipeline-additional"></a>

**自訂 Terraform 模組**

以下是在此模式中使用的自訂 Terraform 模組清單：
+ `codebuild_terraform` 會建立構成管道每個階段的 CodeBuild 專案。
+ `codecommit_infrastructure_source_repo` 會擷取並建立來源 CodeCommit 儲存庫。
+ `codepipeline_iam_role` 會為管道建立所需的 IAM 角色。
+ `codepipeline_kms` 會建立 Amazon S3 物件加密和解密所需的 AWS KMS 金鑰。
+ `codepipeline_terraform` 會為來源 CodeCommit 儲存庫建立測試管道。
+ `s3_artifacts_bucket` 會建立 Amazon S3 儲存貯體來管理管道成品。

**建置規格檔案**

以下是組建規格 (buildspec) 檔案的清單，此模式用於執行每個管道階段：
+ `buildspec_validate.yml` 會執行`"validate"`階段。
+ `buildspec_plan.yml` 會執行`"plan"`階段。
+ `buildspec_apply.yml` 會執行`"apply"`階段。
+ `buildspec_destroy.yml` 會執行`"destroy"`階段。

*建置規格檔案變數*

每個 buildspec 檔案使用以下變數來啟用不同的組建特定設定：


| 
| 
| 變數 | 預設值 | Description | 
| --- |--- |--- |
| `CODE_SRC_DIR` | "." | 定義來源 CodeCommit 目錄 | 
| `TF_VERSION` | "1.3.7" | 定義建置環境的 Terraform 版本 | 

`buildspec_validate.yml` 檔案也支援下列變數，以啟用不同的建置特定設定：


| 
| 
| 變數 | 預設值 | Description | 
| --- |--- |--- |
| `SCRIPT_DIR` | "./templates/scripts" | 定義指令碼目錄 | 
| `ENVIRONMENT` | 「開發」 | 定義環境名稱 | 
| `SKIPVALIDATIONFAILURE` | 「Y」 | 略過失敗的驗證 | 
| `ENABLE_TFVALIDATE` | 「Y」 | 啟用 Terraform 驗證  | 
| `ENABLE_TFFORMAT` | 「Y」 | 啟用 Terraform 格式 | 
| `ENABLE_TFCHECKOV` | 「Y」 | 啟用檢查掃描 | 
| `ENABLE_TFSEC` | 「Y」 | 啟用 tfsec 掃描 | 
| `TFSEC_VERSION` | 「v1.28.1」 | 定義 tfsec 版本 | 