CodePipeline を利用した Fargate の ローリングデプロイ

# はじめに
ECSのローリングデプロイの手順をまとめました。


# 流れ
①CodeBuild作成
②CodeBuildで作成されたIAMロールに、ECRの権限付与
③buildspec.ymlの作成
④CodePipeline作成
⑤CodePipeline実行時のエラー集

# デプロイまでのイメージ図
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/8c05e6e2-9603-97e6-de83-e6a048473aef.png">

# 前提
- 下記の記事でFargateを作成済み
（記事を参考にしなくても、ECSが作成されていればよい。Fargateタイプ,EC2タイプどちらでも可）
[Fargate＋WordPress構築 ①](https://qiita.com/holdout0521/items/bde67b8334f3362c8009)~[Fargate＋WordPress構築 ③](https://qiita.com/holdout0521/items/b83f931e16e680e46391)
- GitHubにリポジトリ作成済み

- もしくは、Laravelをfargateで構築した記事も参考になるかと思います。

https://qiita.com/holdout0521/items/241df305a90af3ccf973

# CodeBuild作成
`ビルドプロジェクトを作成する`をクリックします。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/840de44a-ef41-befd-bad2-e123e3828e35.png">
### プロジェクトの設定
プロジェクト名のみ記入
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/5e53c93f-1c4d-a030-3d4b-f3094a1468d1.png">
### ソース

ソースプロバイダ:`GitHub`
リポジトリ：`OAuth　を使用して接続する`
`GitHubに接続`をクリックします

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/88c0d3d1-6a2d-400e-3cef-03f288fb54d9.png">
`Authorize aws-codesuite`をクリックします。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/36d16fba-60be-4c4b-2e17-037d7bc5f855.png">
`確認`をクリックします。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/293da18d-8363-e828-50a1-9346969dac96.png">

リポジトリの URL:`[GitHubのURL]`

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/59e88756-df64-7862-d169-e532a1ec63d9.png">





### 環境
- 環境イメージ：`マネージド型イメージ`
- オペレーティングシステム：`Amazon Linux 2`
- ランタイム：`Standard`
- イメージ：`最新のバージョン`
- イメージのバージョン：`最新のバージョン`
- 特権付与：`チェックする！`
- 環境タイプ： `linux`
- サービスロール：`新しいサービスロール`
ロールは後で、修正します。



<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4e30d0b7-2d97-3fa3-8ad2-867a1c48cb58.png">

:::note warn
サービスロールは、すでに設定済みの場合、新しくサービスロールを必要はありません。
下記のように`既存のサービスロール`を選択、`AWS CodeBuild にこのサービスロールの編集を許可...`のチェックマークを外すだけです。

![スクリーンショット 2022-04-07 11.51.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0824e1b0-d83a-761a-1592-7a91a4473dc3.png)
:::
<details>
<summary>サービスロールのIAM</summary>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:InitiateLayerUpload",
                "ecr:PutImage",
                "ecr:UploadLayerPart"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:ap-northeast-1:xxxxxxxxxx:log-group:/aws/codebuild/*:*",
                "arn:aws:logs:ap-northeast-1:xxxxxxxxxx:log-group:/aws/codebuild/*:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::codepipeline-ap-northeast-1-*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages"
            ],
            "Resource": [
                "arn:aws:codebuild:ap-northeast-1:xxxxxxxxxx:report-group/*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "ssm:GetParameters",
            "Resource": "arn:aws:ssm:*:xxxxxxxxxx:parameter/*"
        }
    ]
}

```

</details>


### 追加設定

#### 環境変数(コンテナ1つの場合)
環境変数を５つ設定します。
![スクリーンショット 2022-04-05 12.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/8b1561e3-feef-65a0-276a-e8dce174166d.png)

| 名前 | 値 | 意味 |
|:-:|:-:|:-:|
|  AWS_DEFAULT_REGION | ap-northeast-1  |  awsリージョン |
| IMAGE_REPO_NAME  |  wordpress | ECRのリポジトリ名  |
|  CONTAINER_NAME | sample-wordpress  | タスク定義で設定したコンテナ名  |
|  IMAGE_TAG |  prod |  ECRに保管されたイメージタグ |
| AWS_ACCOUNT_ID  |  12345678 | AWSアカウントID  |


#### 環境変数(コンテナ2つの場合)

下記は、Laravelをfargateで構築した記事になります。　

https://qiita.com/holdout0521/items/241df305a90af3ccf973

:::note warn
タスク定義で設定したコンテナが2つの場合、 下記のように`IMAGE_REPO_NAME`と`CONTAINER_NAME`をそれぞれ2つ設定します。
:::
1つのタスクにコンテナが2つある場合があるかと思います。
例えば、Laravelの場合、php-fpmのコンテナとnginxのコンテナを使用します。


| 名前 | 値 | 意味 |
|:-:|:-:|:-:|
|  AWS_DEFAULT_REGION | ap-northeast-1  |  awsリージョン |
| IMAGE_REPO_NAME_1  |  laravel-php | ECRのリポジトリ名  |
|  CONTAINER_NAME_1 | app  | タスク定義で設定したコンテナ名  |
| IMAGE_REPO_NAME_2  |  laravel-nginx | ECRのリポジトリ名  |
|  CONTAINER_NAME_2 | nginx  | タスク定義で設定したコンテナ名  |
|  IMAGE_TAG |  prod |  ECRに保管されたイメージタグ |
| AWS_ACCOUNT_ID  |  12345678 | AWSアカウントID  |

### Buildspec
ビルド仕様：`buildspec ファイルを使用する`
`builspec.yml`ファイルは、後ほど作成して、GitHubにプッシュします。


### バッチ設定
デフォルトのまま
チェックしません
![スクリーンショット 2021-10-30 22.26.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/19a52c13-b472-367c-f7bb-e4663d282b7d.png)


### アーティファクト
`アーティファクトなし`
Docker イメージを Amazon ECR にプッシュする場合は、[アーティファクトなし] を選択できます。
`キャッシュタイプ`：`ローカル`
`DockerLayerCache`：`チェックする`
`SourceCache`：`チェックする`

## ローカルキャッシュについて
### 概要
DockerイメージのレイヤやGitのメタデータをCodeBuildの実行ホスト環境内にキャッシュする事で実行時間短縮が期待できます。
CodeBuildのローカルキャッシュには以下3つの種類が存在します。

- DockerLayerCache
Buildフェーズなどで実行するDockerイメージのbuild/pull時の各レイヤをキャッシュしてイメージのビルドやDLを高速化します。
Dockerイメージのbuildやpullは主にBuildフェーズなどで行う内容の為、実行時間が短縮されるフェーズも同様です。

- SourceCache
ビルドに使用するソースコードを保存してあるGitリポジトリからDLしたメタデータをキャッシュして、次回以降のDLに前回DL時からの差分のみをDLできるようになります。
GitリポジトリからDLしたメタデータをキャッシュするので、DOWNLOAD_SOURCEフェーズの実行時間が短縮されます。

- CustomCache
buidspec.ymlのcache/pathsで指定したディレクトリ配下のパスに存在するファイル群がキャッシュされるようになります。

キャッシュについて、詳しくはこちら↓

https://masakimisawa.com/reduce_codebuild_build_time/

### ログ
CloudWatch Logsがチェックされていますので、そのままにします。
ビルド出力ログが CloudWatch にアップロードされます。


![スクリーンショット 2021-10-30 22.26.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0469234c-e44d-44a0-d198-bbee08b60ec3.png)


`ビルドプロジェクトを作成`をクリックします。


# CodeBuildで作成されたIAMロールに、ECRの権限付与
CodeBuildを実行する際、ロールにECRを操作する権限が必要になります。
IAMのロールから、codebuildで検索すると、先程名付けたプロジェクト名のポリシーが見つかります。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/8fc1fc8a-737a-16c1-63fa-3cbd9fd7ed53.png">

ECRの実行権限を追加します。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/55403a42-8fed-5a6e-7847-e7c858cd2ae3.png">
**上記の画像の`ここに加える！！`の位置に以下のコードを追加します。**

```
        {
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:InitiateLayerUpload",
                "ecr:PutImage",
                "ecr:UploadLayerPart"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },

```

下記の画像のように追加できているとOKです。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/91ce57ab-4641-8ca9-8325-70c300901615.png">


# buildspec.ymlの作成

GitHubにプッシュするファイルは以下の2つです。
- `Dockerfile`
- `buildspec.yml`

ファイルの置き場所は全てルートディレクトリ配下です。

```
./
├── Dockerfile
└── buildspec.yml
```
CodeBuildで必須ファイルは、以下の2つになります。
- `buildspec.yml`

## buildspec.ymlの作成

buildspec.ymlは、以下をコピペし、一部編集します。
buildspec.ymlファイルは、ソースコードのトップディレクトリに設置しておくことで、CodeBuildがbuildspec.ymlの内容を読み込み実行します。

### DockerHubのアカウント作成

その前に、DockerHubのアカウント作成する必要があります。理由を含めて下記の記事を見てください

https://qiita.com/holdout0521/items/9c7907fdb387e08375f4

### コンテナが1つの場合

```buildspec.yml
version: 0.2

env:
  parameter-store:
    DOCKER_USER: DOCKER_HUB_ID
    DOCKER_PASSWORD: DOCKER_HUB_PASSWORD

phases:
  pre_build:
    commands:
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
  build:
    commands:
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
  post_build:
    commands:
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - printf '[{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG  > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
```

### imagedefinitions.jsonについて
CodeBuildステージで、ビルド情報が`imagedefinitions.json`に記載され、デプロイステージで、その情報を元にタスク定義の新しいリビジョンを作成し、タスク定義を反映したタスクがデプロイされます

詳細はこちら↓


https://docs.aws.amazon.com/ja_jp/ja_jp/codepipeline/latest/userguide/file-reference.html

### コンテナが2つの場合

```diff_yaml:buildspec.yml
version: 0.2

env:
  parameter-store:
    DOCKER_USER: DOCKER_HUB_ID
    DOCKER_PASSWORD: DOCKER_HUB_PASSWORD

phases:
  pre_build:
    commands:
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
  build:
    commands:
      - docker build -t $IMAGE_REPO_NAME_1:$IMAGE_TAG -f docker/php/Dockerfile .
      - docker build -t $IMAGE_REPO_NAME_2:$IMAGE_TAG -f docker/nginx/Dockerfile .
      - docker tag $IMAGE_REPO_NAME_1:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_1:$IMAGE_TAG
      - docker tag $IMAGE_REPO_NAME_2:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_2:$IMAGE_TAG
  post_build:
    commands:
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_1:$IMAGE_TAG
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_2:$IMAGE_TAG
      - printf '[{"name":"%s","imageUri":"%s"},{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME_1 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_1:$IMAGE_TAG $CONTAINER_NAME_2 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_2:$IMAGE_TAG > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
```

### buildspec.ymlのコマンド集

|設定  |意味|備考  |
|---|---|---|
|version  |ビルドスペックのバージョン  |現時点2021/10/1の最新バージョンは0.2です。  |
|phases  |ビルドの各フェーズでどういったコマンドを実行するか定義する大本のキー  |設定可能なフェーズは install / pre_build / build / post_build の4つです。  |
|install |インストールフェーズで実行するコマンドを定義  |ビルドする前に必要なライブラリなどをここで用意します。  |
|pre_build  |ビルド前に実行するコマンドを定義  |設定ファイルを書き換えたりといったビルド前に実施するちょっとした処理内容を記述する箇所です。  |
|build  |ビルドする際に実行するコマンドを定義|dockerのイメージをビルドしたり、タグ付けします。 |
|post_build  |ビルド後に実行するコマンドを定義|例えばGitHubリリースへアップロードするといったビルド後の処理を記述します。  |
|artifacts  |ビルド後に生成した成果物(アーティファクト)の設置場所|type はzipのみ指定可能。 files でCodeBuildでビルドしたアーティファクトのパスを指定します。ワイルドカードも可能です。 |






そしてGitHubにプッシュしましょう。


# CodePipeline作成
CodePipeline作成をクリックします。

### パイプラインの設定

- パイプライン名：`適切に`
- サービスロール：`新しいサービスロール`
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/47d9531b-56b2-b8da-64ef-fe8d06710cbc.png">


### ソースステージを追加する
- ソースプロバイダー：`GitHub(バージョン2)`
- 接続：`GitHubに接続する`をクリック
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/1fb9f494-d9d5-825e-ded9-fce769d759b8.png">

- 接続名:`リポジトリ名`
　`GitHubに接続する`をクリック

　`Authorize AWS Connector for GitHub`をクリックすると前の画面に戻る
- GitHubアプリの`新しいアプリをインストールする`をクリックします
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4a00b5fc-5dc4-beb5-809f-52bb17e797bf.png">
 `Only select repositories`を選択し、`リポジトリを選択し`、installをクリックします

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/89adf69a-d2c1-41ef-2e18-c84bd338a3c9.png">

 `接続`をクリックします

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4fcdb92e-5952-d1fb-8a2c-97b1bcdacbb4.png">

- リポジトリ名：`選択肢として表示されます`
- ブランチ名：`選択肢として表示されます`

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/1852043e-da8c-bc12-f967-7fea357992da.png">

### ビルドステージを追加する
- プロバイダーを構築する：`AWS CodeBuild`
- プロジェクト名：`先程作成したCodeBuild名`
- 環境変数：`無記入`
- ビルドタイプ：`単一ビルド`
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/f876b07a-a89d-8ed4-a894-9865c47d0325.png">

### デプロイステージを追加する
- デプロイプロバイダ：`Amazon ECS`
- クラスター名：`ECSで作成済みのクラスター`
- サービス：`ECSで作成済みのサービス`
- イメージ定義ファイル - オプショナル：`無記入`
イメージ定義ファイル（image definitions file）は、CodeBuildする時に作成されるので、書かなくても大丈夫です。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/dd488bf5-e3dc-cad2-b1be-dcc515ef367c.png">

次に進み問題なければ、`パイプライン作成する`をクリックします。

CodePipelineが動きます。

# CodePipeline実行時のエラー


## Code Buildステージエラー①

```
Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command:
 aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 
xxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com. Reason: exit status 1
```
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/426e0b19-1ab8-7b68-e5db-d22a84760bf8.png">

原因は、`ビルドを実行するロールにECRを操作する権限がない`ことが考えられます。
先程説明した手順通り、権限が付与されているか確認しましょう。

そして、ECRの実行権限のポリシーを追加する必要があります。



`CodePipelineを再実行`してみましょう。
CodePipelineの`変更をリリースする`をクリックすると、再実行されます。

それでもだめなら、アクセスキーとシークレットキーが正しく設定されているか確認します

```
$ cat ~/.aws/credentials 
```

## Code Buildステージエラー②

```
Phase context status code: YAML_FILE_ERROR Message: YAML file does not exist
```

`buildspec.yml`がないと言われていますので、`buildspec.yml`を加え、GitHubにプッシュすると解決します。

## Code Buildステージエラー③

```
Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker push xxxxxxxxx.dkr.ecr.p-northeast-1.amazonaws.com/wordpress:latest. Reason: exit status 1
```
`p-northeast-1`となっております。正しくは、`ap-northeast-1`です。


## ECS Deployステージエラー①

```
The AWS ECS container wordpres does not exist
```
コンテナ名が間違えている可能性が大です。この場合、正しくは`wordpress`です。


## ECS Deployステージエラー②
`imagedefinitions.json`が無効なフォーマットになっています。

```
The image definition file imagedefinitions.json contains invalid JSON format
```
`buildspec.yml`に以下の記載がない場合に、このエラーになります。
[こちらの工程ですね](https://qiita.com/holdout0521/items/3aeeb9c9f9e663778ed7#buildspecyml%E3%81%AE%E4%BD%9C%E6%88%90)

コンテナが１つの場合
```
printf '[{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG  > imagedefinitions.json
```

コンテナが2つの場合
```
printf '[{"name":"%s","imageUri":"%s"},{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME_1 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_1:$IMAGE_TAG $CONTAINER_NAME_2 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME_2:$IMAGE_TAG > imagedefinitions.json
```

<br>
デプロイまで成功すると、ECSのタスクが実行されているはずです！

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/8a74772d-d109-7a06-5239-4d7ff70e9cbf.png">

# １回のビルドで２つのサービスのタスクをデプロイする

１回のビルドで、２つのサービス（２つのタスク定義をデプロイ）にそれぞれタスクをデプロイしたい場合があるかと思います。
その場合、Deployステージに`アクションを追加`クリックし、先程設定したものとは別に、デプロイしたいサービスを指定します。
また、`アクション名`と`変数の名前空間`は、先程作成したDeployと名前を被らないように設定すると、完了です。
![スクリーンショット 2022-04-08 13.04.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/28d1af5e-b6af-8309-439c-04ce326dc154.png)

![スクリーンショット 2022-04-08 13.07.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/1ca6f271-ac2c-25ae-3187-ffa300b2b436.png)

ビルド完了後、各サービスに設定されたタスクがそれぞれデプロイされます。

# CodeBuildの環境を編集する場合
codebuildの環境を修正し、更新するとき、以下のエラーになります。

![スクリーンショット 2022-04-06 17.52.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/853fb3e3-4ebc-1029-a840-ff2975056204.png)

```
codebuild.amazonaws.com did not create the default version (v4) of the CodeBuildBasePolicy-xxxxxxx-ap-northeast-1 policy that is attached to the codebuild-xxxxxxx-role role. 
To continue, detach the policy from any other identities and then delete the policy and the role.
```

`「AWS CodeBuild にこのサービスロールの編集を許可し、このビルドプロジェクトでの使用を可能にする」`のチェックを外すと、更新できます。

![スクリーンショット 2022-04-06 17.50.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4928f29c-31fb-e9e2-1055-dd3b974def0c.png)



# DockerHubアカウントを設定
Code Buildステージエラーで以下のエラーが起きることがあるため、`DockerHubの無料プランに入ることをおすすめします。`

```
toomanyrequests: You have reached your pull rate limit. 
You may increase the limit by authenticating and upgrading:
https://www.docker.com/increase-rate-limit
```

下記の記事通りに行ってください。

https://qiita.com/holdout0521/items/9c7907fdb387e08375f4

# CodePipelineの通知設定
Slackに通知設定は下記の記事通りにするとできます。

https://qiita.com/holdout0521/items/9bc4bdda82d8bbacc94a

# CloudFrontのキャッシュを削除するステージ追加
CloudFrontを使用している場合、デプロイごとにCloudFrontのキャッシュを削除したいケースがあるかと思います。
以下の記事通り行うと実現できます。

https://kurutasu.github.io/2021/03/29/AWSLambda-cloudfront



# 参考記事
- [CodePipelineでECSにデプロイする(Ver.rolling update)](https://qiita.com/jeayoon/items/74324f338725d29de23f)
- [CodeBuildでECRビルドエラーから得た4つの知見](https://qiita.com/icck/items/bcf118a38c2a691a837d)
- [AWS CodeCommitからCodePipelineでECRへDockerイメージをビルド](https://infraya.work/posts/aws_codecommit_to_ecr/)
- [チュートリアルを通してCodeBuildを理解する](https://dev.classmethod.jp/articles/understanding-codebuild/)

https://toris.io/2021/04/speeding-up-amazon-ecs-container-deployments/