ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

PipeCD で ECS を Deploy する

Deploy するアプリケーション

8080 で listen して、http request があったら hello を出力する Go のアプリを ECR に push する。

github.com

環境変数 "VERSION" を読み取って、それを出力している。

make docker で build し、make push で ECR に push する。今回はこのアプリケーションを v9 から v10 に更新する Deploy を PipeCD で行う。

PipeCD Application

simple の example を参考にした。

github.com

実際に設定したファイルはこんな感じ。

  • app.pipecd.yaml
apiVersion: pipecd.dev/v1beta1
kind: ECSApp
spec:
  name: simple
  labels:
    piped: chaspy-local
    owner: chaspy
  input:
    serviceDefinitionFile: servicedef.yaml
    taskDefinitionFile: taskdef.yaml
    targetGroups:
      primary:
        targetGroupArn: arn:aws:elasticloadbalancing:ap-northeast-1:655123516369:targetgroup/hello8/71d4c3025713a1ee
        containerName: hello
        containerPort: 8080
  description: |
    chaspy test
  • servicedef.yaml
cluster: arn:aws:ecs:ap-northeast-1:655123516369:cluster/pipecd-dev3
serviceName: hello
desiredCount: 2
deploymentConfiguration:
  maximumPercent: 200
  minimumHealthyPercent: 0
schedulingStrategy: REPLICA
# CAUTION: To enable PipeCD controls the deployment
# DeploymentController of type EXTERNAL is required.
deploymentController:
  type: EXTERNAL
enableECSManagedTags: true
propagateTags: SERVICE
launchType: FARGATE
networkConfiguration:
  awsvpcConfiguration:
    assignPublicIp: ENABLED
    securityGroups:
      - sg-eee24b8b
    subnets:
      - subnet-fb7f36d3
      - subnet-5118f008
      - subnet-1803d46f
  • taskdef.yaml
family: hello
executionRoleArn: arn:aws:iam::655123516369:role/ecsTaskExecutionRole
containerDefinitions:
  - command: null
    cpu: 100
    image: 655123516369.dkr.ecr.ap-northeast-1.amazonaws.com/hello:v9
    memory: 100
    mountPoints: []
    name: hello
    portMappings:
      - containerPort: 8080
    environment:
      - name: VERSION
        value: "9"
compatibilities:
  - FARGATE
requiresCompatibilities:
  - FARGATE
networkMode: awsvpc
memory: 512
cpu: 256
pidMode: ""
volumes: []

Taskdef や Servicedef は AWS でのそれぞれの json に対応している。

pipecd.dev

docs.aws.amazon.com

docs.aws.amazon.com

最初わかりづらかったので Document に PR を送った。

github.com

Control Plane 側 Application を登録する。

これは quick sync を一度したあとの状態。

f:id:take_she12:20220410230525p:plain

piped

なお piped には lambda と同様、credential file を読ませる必要がある。

apiVersion: pipecd.dev/v1beta1
kind: Piped
spec:
(skip)

  cloudProviders:
    - name: ecs-dev
      type: ECS
      config:
        region: ap-northeast-1
        profile: default
        credentialsFile: /etc/piped-secret/ecs-cred

(skip)

helm で deploy する。

#!/bin/bash
set -x
helm repo add pipecd https://charts.pipecd.dev
helm install piped pipecd/piped -n pipecd
helm upgrade -i piped pipecd/piped \
    --version=v0.27.2 \
    --namespace=pipecd \
    --set-file config.data=piped.yaml \
    --set-file secret.data.ecs-cred=ecs/credential.txt

なお credential file はこういう形式である必要がある。

[default] aws_access_key_id = your-access-key-id aws_secret_access_key = your-secret-access-key

Deploy

Image tag を更新する PR を作成

f:id:take_she12:20220411063040p:plain

Merge すると Deploy が完了。

f:id:take_she12:20220411062738p:plain

Task Definition が更新された。

その他の Deploy 方法

今回は単純な "simple" のケースを試したが、PipeCD の Pipeline の機能を使って、Wait Approval - 承認を挟んでからのデプロイや、Canary Release もできる。

Target Group を複数用意することで Weight を変更して実現している。

pipecd.dev

PipeCD 以外の ECS Application の Deploy 方法

手を動かしていない前提で、いくつか選択肢をあげてみる。

AWS CLI

task definition で新しい revision を作成し、service からの参照を変えれば良い。

docs.aws.amazon.com

docs.aws.amazon.com

code deploy を組み合わせることもできるようだ。

docs.aws.amazon.com

AWS Code Deploy

aws.amazon.com

canary release をサポートしているが、割合は用意されたもののみのようだ。

GitHub Actions

CI/CD に組み込むことを考えると GitHub Actions は有効な選択肢の1つ。便利な Action が既にある。

github.com

ecspresso

github.com

基本的には AWS SDK の薄いラッパーだが verify や diff など便利なサブコマンドが提供されている。

Terraform

taskdef と servicedef を更新すれば良いので Terraform でも可能。

registry.terraform.io

まとめ

PipeCD で ECS Application を simple にデプロイする方法を試した。

Piped と controll plane の準備が必要な点は他のデプロイツールにより手間がかかるが、デプロイパイプラインを柔軟に組み立てられる点、特に Canary Release を宣言的に行える点は他のツールにはない差別化ポイントである。