Slide 1

Slide 1 text

ECS Scheduled Task 上の定期実行バッチを ecschedule で GitOps 化した話 2021.03.17 KGDC Tech Conference #0 通信インフラだけじゃないKDDIグループの多彩な技術 Kei IWASAKI (@laugh_k)

Slide 2

Slide 2 text

お前誰よ Kei IWASAKI Twitter: @laugh_k Github: @laughk コネヒトのインフラエンジニア 最近はTerraformとよく戯れています

Slide 3

Slide 3 text

https://connehito.com/

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

本日のお話 ECS Scheduled Task を利用して動く定 期実行バッチの運用を ecschedule で GitOps 化することにより改善した話で す 先日のテックブログにも記事があるの であわせご覧ください

Slide 6

Slide 6 text

ECS Scheduled Task とは

Slide 7

Slide 7 text

ECS Scheduled Task とは Amazon ECS は、cron のようなスケジュール、または CloudWatch イベ ント に応答してタスクをスケジュールする機能をサポートしています。 この機能は、Fargate および EC2 の両方の起動タイプを使用する Amazon ECS タスクでサポートされています。 from: タスクのスケジューリング (cron) - Amazon ECS "

Slide 8

Slide 8 text

ECS Scheduled Task とは 簡単に言えば EventBridge を組み合わせてECSタスクをCronのように実行できるサービス Amazon ECS は、cron のようなスケジュール、または CloudWatch イベ ント に応答してタスクをスケジュールする機能をサポートしています。 この機能は、Fargate および EC2 の両方の起動タイプを使用する Amazon ECS タスクでサポートされています。 from: タスクのスケジューリング (cron) - Amazon ECS "

Slide 9

Slide 9 text

ECS Scheduled Task はとても便利 定期実行バッチ処理のコンテナ化ができる cron実行するような定期実行バッチをほぼサーバレスで動かすことができる 専用バッチサーバは不要 ECS 運用の資産(Dockerイメージ、Task定義など)を生かせる Dockerレイヤキャッシュを使うことでスケジュール通りのバッチ実行が可能 Fargateを使えば完全にサーバレス化することもできる など

Slide 10

Slide 10 text

ECS Scheduled Task のコネヒトの以前の利用状況 1つのバッチに対し、1つのECSタスク定義を用意 ECSタスク定義はTerraformで管理をし、バッチ追加の際は開発者がPRを出す運用 PRをインフラエンジニアがレビューし、OKなら terraform apply スケジューリングについては特にコード管理せず、手動適用

Slide 11

Slide 11 text

ECS Scheduled Task のコネヒトの以前の利用状況

Slide 12

Slide 12 text

参考資料 AWSサービスで実現するバッチ実行環境のコンテナ/サーバレス化/ Container service of batch execution environment realized by AWS service - Speaker Deck

Slide 13

Slide 13 text

ECS Scheduled Task はとても便利 AWSサービスで実現するバッチ実行環境のコンテナ/サーバレス化/ Container service of batch execution environment realized by AWS service - Speaker Deck

Slide 14

Slide 14 text

ただし、運用し続けると問題は出てくる

Slide 15

Slide 15 text

コネヒトの運用で陥っていた状態 EventBridgeルールは手作業で追加・変更なので作業の属人化は結局発生 1つのバッチに対して1つのタスク定義を用意する運用は、数が少ないうちはよかっ たがバッチの数が増え運用がきつくなってきた

Slide 16

Slide 16 text

コネヒトの運用で陥っていた状態

Slide 17

Slide 17 text

Terraformのコードも無駄に肥大化 利用しているDockerイメージは同一なのにcommand と環境変数の微妙な違いによるコピペコードが量産さ れていた 気が付いたらtfファイルが1564行まで膨れてしまった クラスタも

Slide 18

Slide 18 text

バッチを動かすためにマネージドサービスを便利に 使えてはいるが、運用はしんどい

Slide 19

Slide 19 text

バッチ運用を楽にするための 改善プロジェクトを開始

Slide 20

Slide 20 text

バッチ運用を楽にするための改善プロジェクトを開始 コピペコードの量産に、変更の適用フローが属人的で開発者体験は良くはなかった @laugh_k が入社したばかりで着手しやすい状況だったこともおおきい

Slide 21

Slide 21 text

目指したところ 開発者でもわかりやすく、直接扱いやすい仕組みにしたい バッチの追加・更新の際は属人的でなく、極力開発者の裁量でできるようにしたい

Slide 22

Slide 22 text

改善方針 バッチ一つにつき一つのタスク定義を用意する方法をやめ、バッチ共通のタスク定 義を一つ用意して使う タスク定義ではなく、イベントルールを管理する 手作業はできるだけ排除したい

Slide 23

Slide 23 text

こうしたいイメージ

Slide 24

Slide 24 text

タスク定義は1つなので特別なツールは使わない

Slide 25

Slide 25 text

ここをどうするか?

Slide 26

Slide 26 text

EventBridgeルール管理の技術選定 次の二つが候補に上がる Songmu/ecschedule ansible-collections/community.aws (AnsibleのAWSモジュール)

Slide 27

Slide 27 text

Ansible (AWSモジュール) vs ecschedule

Slide 28

Slide 28 text

Ansible (AWSモジュール) 構成管理ツールとしての実績は間違いなし ContainerOverrideはJSON文字列で渡す必 要がある タスクの単発実行には対応してない など

Slide 29

Slide 29 text

ecschedule ワンバイナリで環境がそろう ECS Scheduled Task 特化なので余計な機能 がない タスクの単発実行に対応 ContainerOverrideも含めて一気通貫YAML で書ける など

Slide 30

Slide 30 text

比較した結果 ecschedule を選択 EventBridgeルールをよりシンプルに管理できる タスクの単発実行ができるのも嬉しい 一気通貫でYAMLで管理できるのもよい Ansibleは社内で特に使われていなかったのも大きい

Slide 31

Slide 31 text

対応方針を整理

Slide 32

Slide 32 text

決まった方針 1. ecscheduleでEventBrideのルールを管理する 2. タスク定義の管理を簡略化するための構成変更 1. タスク定義はawscliで適用可能なJSONを用意する 2. バッチで利用しているタスク定義を切り替える

Slide 33

Slide 33 text

ecscheduleでEventBrideのルールを管理する

Slide 34

Slide 34 text

ecschedule の導入

Slide 35

Slide 35 text

ecschedule の導入 とりあえず導入するのはdump機能があるのでとても簡単 $ ecschedule dump \ > --cluster clusterName1 \ > --region ap-northeast-1 > event-rule.yaml

Slide 36

Slide 36 text

ecschedule の導入は

Slide 37

Slide 37 text

コネヒトではバッチ用クラスタが三つあり、 dev環境とprd環境があるので実際には次のようなファイル構成に . |-- cluster1/ | |-- dev-events-rules.yaml | |-- prd-events-rules.yaml |-- cluster2/ | |-- dev-events-rules.yaml | |-- prd-events-rules.yaml `-- cluster3/ |-- dev-events-rules.yaml `-- prd-events-rules.yaml

Slide 38

Slide 38 text

タスク定義の管理を簡略化するための構成変更

Slide 39

Slide 39 text

タスク定義の管理を簡略化するための構成変更

Slide 40

Slide 40 text

タスク定義の管理を簡略化するための構成変更

Slide 41

Slide 41 text

共通のタスク定義は愚直にJSONを 用意 管理するタスク定義はバッチ用ECSクラスタあたり 1つ ※ Dockerイメージもreleaseタグを参照しているので、 更新する頻度は少ない ※ FargateとEC2を利用している環境の場合は2つ必要

Slide 42

Slide 42 text

バッチ管理のためのファイル構成は次のように `-- cluster1/ |-- dev-events-rules.yaml |-- dev-task-definition.json ← 追加 |-- prd-events-rules.yaml `-- prd-task-definition.json ← 追加 長くなるので一つのクラスタだけ抜粋

Slide 43

Slide 43 text

バッチ管理のためのファイル構成は次のように (Fargate併用版) `-- cluster3/ |-- dev-events-rules.yaml |-- dev-task-definition-ec2.json ← 追加 |-- dev-task-definition-fargate.json ← 追加 |-- prd-events-rules.yaml |-- prd-task-definition-ec2.json ← 追加 `-- prd-task-definition-fargate.json ← 追加 長くなるので一つのクラスタだけ抜粋

Slide 44

Slide 44 text

タスク定義の管理を簡略化するための構成変更

Slide 45

Slide 45 text

タスク定義の管理を簡略化するための構成変更

Slide 46

Slide 46 text

バッチで利用する タスク定義の切り替え ecschedule管理のYAMLを編集 適用は ecschedule apply で

Slide 47

Slide 47 text

$ ecschedule apply -conf cluster1/dev-event-rule.yaml -all

Slide 48

Slide 48 text

タスク定義の共通化ができ、Terraform管理から解放

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

ecschedule (YAML) のみでバッチの更新・追加がで きるように 基本的にEventBridgeルールだけを考えればよくなった タスク定義のTerraformに比べてコード量も大幅に削減 (1564行から335行) 手作業ではなく、コードの内容がそのまま適用されるようになった

Slide 51

Slide 51 text

ただし、まだ課題は残る

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

1コマンドで終わるとはいえ、手作業は残っている 適用する人が属人化してる状況はかわらない 今はコロナ渦のフルリモート業務、新たな手動オペレーションは結構リスキー せっかくPRベースで追加・更新ができるようになったものの、適用のタイミングは 調整する必要がある

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

ここでもう一押し対応

Slide 56

Slide 56 text

GitHub Actions による自動化

Slide 57

Slide 57 text

GitHub Actions による自動化のためにやったこと 必要なコマンドのmakeタスク化 GtiHub Actions用の設定YAMLを準備 mainブランチにレビューなしのコードが入らないように READMEを整え全体周知

Slide 58

Slide 58 text

自動化にあたって必要な コマンドをmakeタスク化 設定YAMLに直接ベタ書きしてもいいが、手動で も簡単にCI上のオペレーションを再現できたほ うが便利 GitHub Actions上でも手動でも make apply-all すればOKな状態に

Slide 59

Slide 59 text

用意したmakeタスクを活用す る形でGitHub Actionsで自動 Apply AWS向けのsecretsをリポジトリに設定 公式ドキュメントに従いYAMLを準備 mainブランチの内容は常にすべてapplyする

Slide 60

Slide 60 text

ブランチの設定も変更 mainブランチにレビューしていないコードが入らないように

Slide 61

Slide 61 text

GitHub上でバッチ追加・更新が完結するように! 1. YAMLを編集し、PRを出す 2. インフラエンジニアがレビューし、Approveする 3. マージする 以上で

Slide 62

Slide 62 text

READMEを整備 バッチ追加に必要な流れをドキュメント化 いくら仕組みを用意しても 安心して使ってもらえないと意味がない

Slide 63

Slide 63 text

最後は全体周知

Slide 64

Slide 64 text

こうしたいイメージが現実に!

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

導入後の話

Slide 67

Slide 67 text

通常のバッチ追加・更新は晴れてGitOps化が実現 開発者の裁量でバッチの適用までできるように

Slide 68

Slide 68 text

安全な計画停止の実現(GitOps化以前) 以前は停止に伴う影響を調べスプレッドシートにまとめていた

Slide 69

Slide 69 text

安全な計画停止の実現(GitOps化以前) 停止の際は秘伝のシェルスクリプトを実行していた (@shnagai のPCより発掘)

Slide 70

Slide 70 text

安全な計画停止の実現(GitOps化後) 計画停止の内容もPRで共有できる

Slide 71

Slide 71 text

PRベースでバッチ停止に関する相談もできる

Slide 72

Slide 72 text

停止も再開も安全に実施できる 停止時 $ git switch maintenance-20210128 $ make apply-all 再開時 $ git switch main $ make apply-all

Slide 73

Slide 73 text

もちろん問題がないわけではない ecscheduleはバッチの削除には対応していないので、削除は手動対応が必要 YAMLのタスク名に重複がある場合に意図しない適用のされ方をする など

Slide 74

Slide 74 text

必要に応じてYAML内容のチェックを入れたり、 時には ecschedule 自体へのフィードバックを 行うことで対応していきます

Slide 75

Slide 75 text

ご清聴ありがとうございました https://connehito.com/recruit/ We are hiring!!