

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

# CodeBuild 的 Amazon ECR 範例
<a name="sample-ecr"></a>

此範例使用 Amazon Elastic Container Registry (Amazon ECR) 映像儲存庫中的 Docker 映像來建置範例 Go 專案。

**重要**  
執行此範例可能會導致 AWS 您的帳戶產生費用。這包括 AWS CodeBuild 與 Amazon S3、、 AWS KMS CloudWatch Logs 和 Amazon ECR 相關的 AWS 資源和動作的可能費用。如需詳細資訊，請參閱 [CodeBuild 定價](https://aws.amazon.com/codebuild/pricing)、[Amazon S3 定價](https://aws.amazon.com/s3/pricing)、[AWS Key Management Service 定價](https://aws.amazon.com/kms/pricing)、[Amazon CloudWatch 定價](https://aws.amazon.com/cloudwatch/pricing)和 [Amazon Elastic Container Registry 定價](https://aws.amazon.com/ecr/pricing)。

**Topics**
+ [執行 Amazon ECR 範例](#sample-ecr-running)

## 執行 Amazon ECR 範例
<a name="sample-ecr-running"></a>

使用下列指示來執行 CodeBuild 的 Amazon ECR 範例。

**如何執行此範例**

1. 若要在 Amazon ECR 中建立 Docker 映像並將其推送至映像儲存庫，請完成 [執行「發佈 Docker 映像到 Amazon ECR」範例](sample-docker.md#sample-docker-running)區段中的步驟[「將 Docker 映像發佈至 Amazon ECR」範例](sample-docker.md)。

1. 建立 Go 專案：

   1. 如本主題的 [Go 專案結構](#ecr-sample-go-project-file-structure)和 [Go 專案檔案](#sample-ecr-go-project-files)章節所述建立檔案，然後將其上傳至 S3 輸入儲存貯體或 AWS CodeCommit、GitHub 或 Bitbucket 儲存庫。
**重要**  
請勿上傳 `(root directory name)`，僅上傳 `(root directory name)` 內的檔案即可。  
如果您使用的是 S3 輸入儲存貯體，請務必建立包含這些檔案的 ZIP 檔案，然後將其上傳至輸入儲存貯體。請勿將 `(root directory name)` 新增至 ZIP 檔案，僅新增 `(root directory name)` 內的檔案即可。

   1. 建立組建專案、執行組建，以及檢視相關的組建資訊。

      如果您使用 AWS CLI 來建立建置專案，`create-project`命令的 JSON 格式輸入可能會與此類似。(以您自己的值取代預留位置。)

      ```
      {
        "name": "sample-go-project",
        "source": {
          "type": "S3",
          "location": "codebuild-region-ID-account-ID-input-bucket/GoSample.zip"
        },
        "artifacts": {
          "type": "S3",
          "location": "codebuild-region-ID-account-ID-output-bucket",
          "packaging": "ZIP",
          "name": "GoOutputArtifact.zip"
        },
        "environment": {
          "type": "LINUX_CONTAINER",
          "image": "aws/codebuild/standard:5.0",
          "computeType": "BUILD_GENERAL1_SMALL"
        },
        "serviceRole": "arn:aws:iam::account-ID:role/role-name",
        "encryptionKey": "arn:aws:kms:region-ID:account-ID:key/key-ID"
      }
      ```

   1. 若要取得建置輸出成品，請開啟您的 S3 輸出儲存貯體。

   1. 將 `GoOutputArtifact.zip` 檔案下載到您的本機電腦或執行個體，然後解壓縮檔案的內容。在已解壓縮的內容中，取得 `hello` 檔案。

1.  如果下列其中一項為 true，您必須將許可新增至 Amazon ECR 中的映像儲存庫，讓 AWS CodeBuild 可以將 Docker 映像提取至建置環境。
   +  您的專案使用 CodeBuild 登入資料來提取 Amazon ECR 映像。這個行為可由 `ProjectEnvironment` 中屬性 `imagePullCredentialsType` 的值 `CODEBUILD` 看出。
   +  您的專案使用跨帳戶 Amazon ECR 映像。在這種情況下，您的專案必須使用其服務角色來提取 Amazon ECR 映像。若要啟用這種行為，請將您 `ProjectEnvironment` 的 `imagePullCredentialsType` 屬性設定成 `SERVICE_ROLE`。

   1. 在 [https://console.aws.amazon.com/ecr/](https://console.aws.amazon.com/ecr/) 開啟 Amazon ECR 主控台。

   1. 在儲存庫名稱的清單中，選擇您建立或選取的儲存庫名稱。

   1. 從導覽窗格，依序選擇 **Permissions (許可)**、**Edit (編輯)** 和 **Add statement (新增陳述式)**。

   1. 針對 **Statement name (陳述式名稱)**，輸入識別符 (例如 **CodeBuildAccess**)。

   1. 用於**生效**時，請保留選取**允許**。這樣做表示您允許存取另一個 AWS 帳戶。

   1. 用於 **Principal (委託人)**，執行下列其中一項操作：
      + 如果您的專案使用 CodeBuild 登入資料來提取 Amazon ECR 映像，請在**服務主體**中輸入 **codebuild.amazonaws.com**。
      + 如果您的專案使用跨帳戶 Amazon ECR 映像，請在**AWS 帳戶 IDs** 中輸入IDs。 AWS 

   1. 略過 **All IAM entities (所有 IAM 實體)** 清單。

   1. 針對 **Action (動作)**，選取所有僅限提取的動作：**ecr:GetDownloadUrlForLayer**、**ecr:BatchGetImage** 和 **ecr:BatchCheckLayerAvailability**。

   1. 針對**條件**，新增下列項目：

      ```
      {
         "StringEquals":{
            "aws:SourceAccount":"<AWS-account-ID>",
            "aws:SourceArn":"arn:aws:codebuild:<region>:<AWS-account-ID>:project/<project-name>"
         }
      }
      ```

   1. 選擇**儲存**。

      此政策會顯示在 **Permissions (許可)** 中。委託人是您在此程序的步驟 3 中針對 **Principal (委託人)** 輸入的委託人：
      + 如果您的專案使用 CodeBuild 登入資料來提取 Amazon ECR 映像，則 `"codebuild.amazonaws.com"`會顯示在**服務主體**下。
      + 如果您的專案使用跨帳戶 Amazon ECR 映像，您要授予存取權 AWS 的帳戶 ID 會顯示在**AWS 帳戶 IDs**下方。

        下列範例政策同時使用 CodeBuild 登入資料和跨帳戶 Amazon ECR 映像。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "CodeBuildAccessPrincipal",
                  "Effect": "Allow",
                  "Action": [
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:BatchGetImage",
                      "ecr:BatchCheckLayerAvailability"
                  ],
                  "Resource": "*",
                  "Condition": {
                      "StringEquals": {
                          "aws:SourceArn": "arn:aws:codebuild:us-east-1:111122223333:project/MyProject",
                          "aws:SourceAccount": "111122223333"
                      }
                  }
              },
              {
                  "Sid": "CodeBuildAccessCrossAccount",
                  "Effect": "Allow",
                  "Action": [
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:BatchGetImage",
                      "ecr:BatchCheckLayerAvailability"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

------
      + 如果您的專案使用 CodeBuild 登入資料，而且您希望 CodeBuild 專案開放存取 Amazon ECR 儲存庫，您可以省略`Condition`金鑰並新增下列範例政策。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "CodeBuildAccessPrincipal",
                  "Effect": "Allow",
                  "Resource": [
                      "arn:aws:codecommit:us-east-2:111122223333:MySharedDemoRepo"
                  ],
                  "Action": [
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:BatchGetImage",
                      "ecr:BatchCheckLayerAvailability"
                  ]
              },
              {
                  "Sid": "CodeBuildAccessCrossAccount",
                  "Effect": "Allow",
                  "Resource": [
                      "arn:aws:codecommit:us-east-2:111122223333:MySharedDemoRepo"
                  ],
                  "Action": [
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:BatchGetImage",
                      "ecr:BatchCheckLayerAvailability"
                  ]
              }
          ]
      }
      ```

------

1. 建立組建專案、執行組建，以及檢視組建資訊。

   如果您使用 AWS CLI 來建立建置專案，`create-project`命令的 JSON 格式輸入可能會與此類似。(以您自己的值取代預留位置。)

   ```
   {
     "name": "amazon-ecr-sample-project",
     "source": {
       "type": "S3",
       "location": "codebuild-region-ID-account-ID-input-bucket/GoSample.zip"
     },
     "artifacts": {
       "type": "S3",
       "location": "codebuild-region-ID-account-ID-output-bucket",
       "packaging": "ZIP",
       "name": "GoOutputArtifact.zip"
     },
     "environment": {
       "type": "LINUX_CONTAINER",
       "image": "account-ID.dkr.ecr.region-ID.amazonaws.com/your-Amazon-ECR-repo-name:tag",
       "computeType": "BUILD_GENERAL1_SMALL"
     },
     "serviceRole": "arn:aws:iam::account-ID:role/role-name",
     "encryptionKey": "arn:aws:kms:region-ID:account-ID:key/key-ID"
   }
   ```

1. 若要取得建置輸出成品，請開啟您的 S3 輸出儲存貯體。

1. 將 `GoOutputArtifact.zip` 檔案下載到您的本機電腦或執行個體，然後解壓縮 `GoOutputArtifact.zip` 檔案的內容。在已解壓縮的內容中，取得 `hello` 檔案。

### Go 專案結構
<a name="ecr-sample-go-project-file-structure"></a>

此範例假設此目錄結構。

```
(root directory name)
├── buildspec.yml
└── hello.go
```

### Go 專案檔案
<a name="sample-ecr-go-project-files"></a>

此範例使用這些檔案。

`buildspec.yml` (在 `(root directory name)` 中)

```
version: 0.2

phases:
  install: 
   runtime-versions: 
     golang: 1.13 
  build:
    commands:
      - echo Build started on `date`
      - echo Compiling the Go code
      - go build hello.go 
  post_build:
    commands:
      - echo Build completed on `date`
artifacts:
  files:
    - hello
```

`hello.go` (在 `(root directory name)` 中)

```
package main
import "fmt"

func main() {
  fmt.Println("hello world")
  fmt.Println("1+1 =", 1+1)
  fmt.Println("7.0/3.0 =", 7.0/3.0)
  fmt.Println(true && false)
  fmt.Println(true || false)
  fmt.Println(!true)
}
```