1つのCodePipelineプロジェクトで複数のECSサービスをデプロイする

## 概要
CodePipelineで１つのプロジェクトで複数のECSサービスをデプロイするための設定方法に工夫が必要だったのでメモ

### ポイント
* buildspec.ymlのアーティファクトで、デプロイするサービスの数だけの`imagedefinitions.json`を生成する
* Deployステージのactionを複数作成して、buildspec.ymlに従って生成されたアーティファクトの`imagedefinitions.json`を使用する

#### buildspec.ymlのアーティファクトで、デプロイするサービスの数だけ`imagedefinitions.json`を生成する
```yaml:buildspec.yml
phases:
 post_build:
   commands:
     - echo Build completed on `date`
     - echo Pushing the Docker images...
     - docker push $SERVICE1_REPOSITORY_URI:$IMAGE_TAG
     - docker push $SERVICE2_REPOSITORY_URI:$IMAGE_TAG
     - echo Writing image definitions file...
     - printf '[{"name":"server","imageUri":"%s"}]' $SERVICE1_REPOSITORY_URI:$IMAGE_TAG > service1_imagedefinitions.json
     - printf '[{"name":"runner","imageUri":"%s"}]' $SERVICE2_REPOSITORY_URI:$IMAGE_TAG > service2_imagedefinitions.json
artifacts:
  files:
    - service1_imagedefinitions.json
    - service2_imagedefinitions.json
```
#### Deployステージのactionを複数作成して、buildspec.ymlに従って生成されたアーティファクトの`サービス名_imagedefinitions.json`を使用する
ここで指定する`サービス名_imagedefinitions.json`は、決まってないので好きな名前で名前で良い。
ビルドステージで指定した

```
       - printf '[{"name":"server","imageUri":"%s"}]' $SERVICE1_REPOSITORY_URI:$IMAGE_TAG > service1_imagedefinitions.json
       - printf '[{"name":"runner","imageUri":"%s"}]' $SERVICE2_REPOSITORY_URI:$IMAGE_TAG > service2_imagedefinitions.json
```
`service1_imagedefinitions.json`や`service2_imagedefinitions.json`の部分とDeployステージのactionで指定するFileNameが一致していることが大事

<img width="622" alt="68747470733a2f2f696d672e6573612e696f2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31333037392f323032302f30342f32322f36393035312f65376531353833332d346234382d343963322d613533612d6263633962356235656364362e706e67.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315083/89eec66c-4910-2e71-e4d7-039c0189234f.png">
<img width="553" alt="68747470733a2f2f696d672e6573612e696f2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31333037392f323032302f30342f32322f36393035312f64393663373632652d373236332d343530302d616662632d3833393361363032366162322e706e67.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315083/47d863af-00a1-4ad7-4bd3-3e50a0454cb9.png">
<img width="553" alt="68747470733a2f2f696d672e6573612e696f2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31333037392f323032302f30342f32322f36393035312f38376339333332632d393164392d343833642d393261662d6266396131643366653735392e706e67.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315083/b4dc786f-d8fe-4731-7c82-9395f0c89917.png">




#####  Terraform
Terraformでは、**FileName** の部分に`サービス名_imagedefinitions.json`といったイメージ定義を指定する

```tf
  stage {
    name = "Deploy"

    dynamic "action" {
      for_each = var.deploy_actions
      content {
        name            = action.value.name
        category        = action.value.category
        owner           = action.value.owner
        provider        = action.value.provider
        input_artifacts = action.value.input_artifacts
        version         = action.value.version

        configuration = {
          FileName    = "service1_imagedefinitions.json"
          ClusterName = var.cluster_name
          ServiceName = var.service_name
        }

      }
    }
```
[AWS: aws_codepipeline - Terraform by HashiCorp](https://www.terraform.io/docs/providers/aws/r/codepipeline.html)

### 所感
AWSCode3兄弟は概念がたくさん出現するので混乱しますが、ビルド→ECSデプロイの流れはとても便利だなと思いました:relaxed: