Deploy するアプリケーション
8080 で listen して、http request があったら hello を出力する Go のアプリを ECR に push する。
環境変数 "VERSION" を読み取って、それを出力している。
make docker で build し、make push で ECR に push する。今回はこのアプリケーションを v9 から v10 に更新する Deploy を PipeCD で行う。
PipeCD Application
simple の example を参考にした。
実際に設定したファイルはこんな感じ。
- 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 に対応している。
最初わかりづらかったので Document に PR を送った。
Control Plane 側 Application を登録する。
これは quick sync を一度したあとの状態。
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 を作成
Merge すると Deploy が完了。
Task Definition が更新された。
その他の Deploy 方法
今回は単純な "simple" のケースを試したが、PipeCD の Pipeline の機能を使って、Wait Approval - 承認を挟んでからのデプロイや、Canary Release もできる。
Target Group を複数用意することで Weight を変更して実現している。
PipeCD 以外の ECS Application の Deploy 方法
手を動かしていない前提で、いくつか選択肢をあげてみる。
AWS CLI
task definition で新しい revision を作成し、service からの参照を変えれば良い。
code deploy を組み合わせることもできるようだ。
AWS Code Deploy
canary release をサポートしているが、割合は用意されたもののみのようだ。
GitHub Actions
CI/CD に組み込むことを考えると GitHub Actions は有効な選択肢の1つ。便利な Action が既にある。
ecspresso
基本的には AWS SDK の薄いラッパーだが verify や diff など便利なサブコマンドが提供されている。
Terraform
taskdef と servicedef を更新すれば良いので Terraform でも可能。
まとめ
PipeCD で ECS Application を simple にデプロイする方法を試した。
Piped と controll plane の準備が必要な点は他のデプロイツールにより手間がかかるが、デプロイパイプラインを柔軟に組み立てられる点、特に Canary Release を宣言的に行える点は他のツールにはない差別化ポイントである。