Slide 1

Slide 1 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. サーバーレスな社内業務システムを稼働させて 1年経ったので、今⽇までの⾜跡を語ろうと思う 橋本 拓弥 / HASHIMOTO Takuya B - 4 Corporate Engineer 株式会社サーバーワークス / Serverworks Co., Ltd.

Slide 2

Slide 2 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. ■ 名前 橋本 拓弥 / HASHIMOTO Takuya Speaker ■ 所属 株式会社サーバーワークス プロセスエンジニアリング部 コーポレートエンジニア ■ SNS Twitter: @hassaku_63 GitHub: hassaku63

Slide 3

Slide 3 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. ■ 普段の仕事 開発寄りの社内 SE Speaker • MSP/バックオフィス系 • CRM (Salesforce) • AWS Step Functions • Python • Serverless Framework ■ SNS Twitter: @hassaku_63 GitHub: hassaku63

Slide 4

Slide 4 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Serverworks ? AWS 特化のインテグレーター • 国内では⽼舗な AWS パートナー企業 • 最上位認定 “AWS Premier Tier Service Partner” (2014年〜) 公表実績(2022年8⽉時点) • 1050 社 • 14200 プロジェクト

Slide 5

Slide 5 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Serverworks ? https://www.serverworks.co.jp/recruit/ We are Hiring(カジュアル⾯談やってます)

Slide 6

Slide 6 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. • ⽉間 1,000 件超(2022年10⽉時点の実績) の請求書作成 & 送付業務を AWS Step Functions + AWS Lambda (+α) で⾃動化した • サーバーレスの開発の実際のところ • AWS Step Functions はいいぞ 今⽇お伝えしたいこと

Slide 7

Slide 7 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. • システム概要と開発背景 • 請求書⾃動送付システムの実装・設計 • 開発・保守で⾏った意思決定やポイント • まとめ Agenda

Slide 8

Slide 8 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. システム概要と開発背景

Slide 9

Slide 9 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務にまつわるデータ管理 請求の元データはすべて Salesforce に集約 • 取引先、担当者 • 商談、商品情報 • インテグレーション • 運⽤代⾏ (MSP) • 請求代⾏ (AWS 利⽤料) • 売上(会計) • 請求、請求明細

Slide 10

Slide 10 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務と関連システム(移⾏前) Salesforce (1) 請求データ作成 データ連携 SaaS 請求書 Excel アップロード Box 請求書 Excel 作成 Gmail / 郵送 (3) pdf にして送信 or 郵送⼿配 取引先 (2) ダウンロード

Slide 11

Slide 11 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務と関連システム(移⾏前) Salesforce (1) 請求データ作成 データ連携 SaaS 請求書 Excel アップロード Box 請求書 Excel 作成 Gmail / 郵送 (3) pdf にして送信 or 郵送⼿配 取引先 (2) ダウンロード n 百件(ほぼ⼿作業)

Slide 12

Slide 12 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務と関連システム(移⾏前) Salesforce (1) 請求データ作成 データ連携 SaaS 請求書 Excel アップロード Box 請求書 Excel 作成 Gmail / 郵送 (3) pdf にして送信 or 郵送⼿配 取引先 (2) ダウンロード EoS

Slide 13

Slide 13 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務と関連システム(移⾏前) Salesforce (1) 請求データ作成 データ連携 SaaS 請求書 Excel アップロード Box 請求書 Excel 作成 Gmail / 郵送 (3) pdf にして送信 or 郵送⼿配 取引先 (2) ダウンロード ・数百件/⽉以上のメール送付(⼿作業) ・データ連携 SaaS が EoS ・請求書を郵送する業務負担 😩

Slide 14

Slide 14 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務と関連システム(移⾏後) Salesforce (1) 請求データ作成 請求書データ アップロード Box 請求書作成&送付システム 取引先 AWS API Gateway AWS Step Functions AWS Lambda (PDF, Excel, 利⽤明細) SendGrid ⾃動送付 OK の 請求ならメール⾃動送付

Slide 15

Slide 15 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求業務と関連システム(移⾏後) Salesforce (1) 請求データ作成 請求書データ アップロード Box 請求書作成&送付システム 取引先 AWS API Gateway AWS Step Functions AWS Lambda (PDF, Excel, 利⽤明細) SendGrid ⾃動送付 OK の 請求ならメール⾃動送付 ・メール送付の⾃動化(半数以上) ・AWS で内製化 ・ペーパーレスへの移⾏ 🎉

Slide 16

Slide 16 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 移⾏による変化 Before After • ⼤量の⼿作業送付 • 外部 SaaS が EoS • 半数以上の送付を⾃動化 • AWS で内製化 ($10.0/1ヶ⽉ 程度) • ペーパーレス移⾏ Keep • 特別対応案件の業務継続 (Excel を利⽤)

Slide 17

Slide 17 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 請求書⾃動送付システムの実装

Slide 18

Slide 18 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 技術スタック • Python 3.8 • Serverless Framework (2.x) • AWS(⼀部抜粋) • AWS Step Functions • AWS Lambda • 3rd party Services • Salesforce (Salesforce) • Box (Box.com) • SVF Cloud (ウイングアーク1st) • SendGrid (SendGrid) • Datadog (Datadog)

Slide 19

Slide 19 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図

Slide 20

Slide 20 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 Salesforce からの リクエストを受け付ける フロントエンド的役割

Slide 21

Slide 21 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 1件の請求に対する処理を担う部分 (請求書作成、AWS利⽤明細作成、送付)

Slide 22

Slide 22 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 Request: - bill_ids: list - auto_send: bool

Slide 23

Slide 23 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 Request: - bill_ids: list - auto_send: bool 請求ID 1件ごとに分割し 後続のステートマシンを 実⾏開始 Start × n回

Slide 24

Slide 24 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 Request: - bill_ids: list - auto_send: bool 請求ID 1件ごとに分割し 後続のステートマシンを 実⾏開始 請求書 (Excel, PDF)作成 + アップロード Start × n回

Slide 25

Slide 25 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 Request: - bill_ids: list - auto_send: bool 請求ID 1件ごとに分割し 後続のステートマシンを 実⾏開始 請求書 (Excel, PDF)作成 + アップロード 利⽤明細 (csv) 作成 Start × n回

Slide 26

Slide 26 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図 Request: - bill_ids: list - auto_send: bool 請求ID 1件ごとに分割し 後続のステートマシンを 実⾏開始 Start × n回 請求書 (Excel, PDF)作成 + アップロード メール送信 利⽤明細 (csv) 作成

Slide 27

Slide 27 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図(ステートマシン) ■ 請求書作成 1. Salesforce から請求データをクエリ 2. 請求書作成 (PDF, Excel) 3. アップロード (Box + S3) 4. AWS 利⽤料に関する請求であれば 後続の「AWS 利⽤明細作成」を開始 5. ⾃動送付フラグが有効であれば 後続の「メール送付」を開始

Slide 28

Slide 28 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図(ステートマシン) ■ AWS 利⽤明細作成 1. Salesforce から AWS 利⽤料をクエリ 2. 請求に紐づく AWS アカウントの数だけ繰り返す 1. 明細 csv 作成 2. アップロード (Box + S3) 3. ⾃動送付フラグが有効であれば 後続の「メール送付」を開始

Slide 29

Slide 29 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 構成図(ステートマシン) ■ メール送付 1. Salesforce から宛先情報をクエリ 2. 送信猶予として⼀定時間待機 3. S3 から成果物 (pdf, csv) をダウンロードし メールに添付して送信

Slide 30

Slide 30 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Topics 1. リトライやエラー制御はステートマシンに移譲 2. 成果物 (PDF など) の情報をステートマシンあるいはタスク間で直接扱わない 3. マネジメントコンソールが使いやすい 4. デプロイ 5. メール送信の是⾮ 6. ジョブの成否監視と通知 7. ステートマシンの分割設計の是⾮ 8. テスト

Slide 31

Slide 31 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Topics 1. リトライやエラー制御はステートマシンに移譲 2. 成果物 (PDF など) の情報をステートマシンあるいはタスク間で直接扱わない 3. マネジメントコンソールが使いやすい 4. デプロイ 5. メール送信の是⾮ 6. ジョブの成否監視と通知 7. ステートマシンの分割設計の是⾮ 8. テスト Step Functions を利⽤する上 での(よくある?)⼯夫の話

Slide 32

Slide 32 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Topics 1. リトライやエラー制御はステートマシンに移譲 2. 成果物 (PDF など) の情報を直接扱わない 3. マネジメントコンソールが使いやすい 4. デプロイ 5. メール送信の是⾮ 6. ジョブの成否監視と通知 7. ステートマシンの分割設計の是⾮ 8. テスト Step Functions を利⽤する上 での(よくある?)⼯夫の話 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 33

Slide 33 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (1)リトライやエラー制御はステートマシンに移譲 実装側ではできるだけ関与しないで任せる⽅針 • 業務⽂脈的に意味のある事象をステートマシン上のエラーで表現 • 失敗した場所が視覚的にわかりやすい • 例外は基本的にそのまま失敗させる • 「1件の Fail = 請求漏れ」なのでそもそもリカバリ対応は必須 • トランザクション区間がないので重症化する場所が少ない • 「とりあえず落とす」が⼀番安全で、かつ⼗分対応可能 • リトライは外部サービスの API を呼ぶ場所で利⽤ • SVF Cloud, SendGrid, Box • Timeout かスロットリングで失敗するケースが観測上多かった • リトライ間隔は Exponential Backoff Catch による失敗例 Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 34

Slide 34 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (1)リトライやエラー制御はステートマシンに移譲 実装側ではできるだけ関与しないで任せる⽅針 • 業務⽂脈的に意味のある事象をステートマシン上のエラーで表現 • 失敗した場所が視覚的にわかりやすい • 例外は基本的にそのまま失敗させる • 「1件の Fail = 請求漏れ」なのでそもそもリカバリ対応は必須 • トランザクション区間がないので重症化する場所が少ない • 「とりあえず落とす」が⼀番安全で、かつ⼗分対応可能 • リトライは外部サービスの API を呼ぶ場所で利⽤ • SVF Cloud, SendGrid, Box • Timeout かスロットリングで失敗するケースが観測上多かった • リトライ間隔は Exponential Backoff Catch による失敗例 ※右図はエラー制御の実例 (メール送付ジョブ) Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 35

Slide 35 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (1)リトライやエラー制御はステートマシンに移譲 Catch による失敗例 Step Functions を利⽤する上での (よくある?)⼯夫の話 「適切な担当者がいない」 を表現する Fail 状態に遷移

Slide 36

Slide 36 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (1)リトライやエラー制御はステートマシンに移譲 Catch による失敗例 「適切な担当者がいない」 を表現する Fail 状態に遷移 送付先としての役割を持つ 担当者をクエリした Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 37

Slide 37 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (1)リトライやエラー制御はステートマシンに移譲 Catch による失敗例 結果が0件だった場合 ユーザー定義の例外を送出 「適切な担当者がいない」 を表現する Fail 状態に遷移 送付先としての役割を持つ 担当者をクエリした Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 38

Slide 38 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (2) 成果物 (PDF など) の情報を直接扱わない 極⼒⼤きなペイロードをタスク間の受け渡しで扱わないこと • ステートマシン上で扱うファイルコンテンツ (PDF, csv) を S3 で扱う • タスク処理中の⼀時ファイルの置き場として利⽤ • ベストプラクティスに記述あり 「ラージペイロードを渡す代わりに Amazon S3 ARNs を使⽤する」 (※1) • 後から使う際はハンドラの /tmp 以下に都度ダウンロード • AWS サービス同⼠の連携であるため、容易に利⽤でき安全に認証できる • Box は業務担当者向けに最終成果物をアップロードする⽬的でのみ利⽤ ※1 ... https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/avoid-exec-failures.html Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 39

Slide 39 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい ⾒やすい、わかりやすい(主にリトライ時) • ステータスフィルタと実⾏名による検索 • どこで失敗したのか⼀⽬瞭然 • 失敗した「実⾏」のリトライが容易 Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 40

Slide 40 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい ⾒やすい、わかりやすい(主にリトライ時) • ステータスフィルタと実⾏名による検索 • どこで失敗したのか⼀⽬瞭然 • 失敗した「実⾏」のリトライが容易 Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 41

Slide 41 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい ⾒やすい、わかりやすい(主にリトライ時) • ステータスフィルタと実⾏名による検索 • どこで失敗したのか⼀⽬瞭然 • 失敗した「実⾏」のリトライが容易 ステータスフィルタ Execution Name のフィルタ ※請求 ID のプレフィックスを 命名規則にしている Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 42

Slide 42 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい ⾒やすい、わかりやすい(主にリトライ時) • ステータスフィルタと実⾏名による検索 • どこで失敗したのか⼀⽬瞭然 • 失敗した「実⾏」のリトライが容易 Catch による失敗例(再) ステートの最終遷移先可能で 発⽣事象を把握 Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 43

Slide 43 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい ⾒やすい、わかりやすい(主にリトライ時) • ステータスフィルタと実⾏名による検索 • どこで失敗したのか⼀⽬瞭然 • 失敗した「実⾏」のリトライが容易 Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 44

Slide 44 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい 失敗した Execution の詳細画⾯で “New execution” をクリック Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 45

Slide 45 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (3) マネジメントコンソールが使いやすい 失敗した Execution の⼊⼒値がコピーされる ランダム ID で Execution Name が⼊⼒済み (任意に変更可能) Step Functions を利⽤する上での (よくある?)⼯夫の話

Slide 46

Slide 46 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (4) デプロイ 現状はローカルマシンからの “serverless deploy” コマンド • 設定ミスの暫定対策として Makefile を使った簡易的なガードレールを作成 • 当初はこれで必要⼗分 • 最低限の実装でミスの原因を潰せた • デプロイ⾃体も(依存関係まわりで)不安定な時期があり、CI に載せたくなかった • ⾃分以外のアサインが増えたらデプロイタスクは⾃動化しようと思っている • AssumeRole 経由で本番アカウント⽤のプロファイルを保持 • >>> AWS_PROFILLE=foo make prod-deploy # npx sls deploy • 管理もデプロイもほぼ⾃分メインなのでギリギリ間に合ってる(?) が、好ましくはない • AWS_PROFILE や環境変数の設定間違いが起きる(起きた) • 個⼈のローカルマシンが本番アカウントの知識を持っている ※コードスニペットは Appendix に記載 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 47

Slide 47 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (5) メールによる請求書送付の是⾮ • 良い⽅法ではない認識、やめたいとは思っている • 当初、最速で作れる⼿段を模索した結果としてそうなった • ファイル共有プラットフォームの利⽤に切り替えたかったが諸般の事情で断念 • バウンス対応が⼀番運⽤シーンで⼿間がかかる 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 48

Slide 48 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 前提要件 • 「どの顧客のどの請求が失敗したか︖」を特定したい • ステートマシンの Execution ID と⼊⼒値を、通知⽂で知りたい • 失敗したジョブ(=請求1件)は、原則すべて個別確認してリカバリを判断する必要がある • ステートマシンの Fail (正確には、発⾏に失敗した ”請求”)はすべてキャッチしたい • 失敗したジョブは原則的に同⽇内なるはやのリカバリが必要 • 遅延は⾃社の回収遅延や、取引先の経理の⼊⾦業務に影響する • 対応漏れは NG だが、再実⾏等のリカバリ対応が重複するのも NG (顧客が混乱するため) 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 49

Slide 49 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で即実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 50

Slide 50 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Datadog Integration Step Functions State machine Datadog 直近の N 分間で “Fail” が 1件以上ならアラート︕ 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 51

Slide 51 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Datadog Integration Step Functions State machine Datadog ・アラートの情報量が「N 分間で発⽣した Fail 数」になる ・Fail Execution の件数しか得られない ・個別の Fail Execution に関する情報は取れない ・アラート通知と、実際に⾒るべき Execution 件数が⼀致しない ・N 分間の中で複数件 Fail することがありえる 直近の N 分間で “Fail” が 1件以上ならアラート︕ 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 52

Slide 52 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Event Bridge Step Functions State machine Slack Fail に遷移した Execution を通知 Event Bridge Execution Fail Event Rule SQS Queue Lambda Functio n ・Fail した Execution ごとの情報が Consumer 側で取得できる → アラート通知⽂をより Actionable にできる ・Slack への通知件数と、実際に⾒るべき Execution 件数が⼀致する → 対応漏れしづらくなる 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 53

Slide 53 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Event Bridge Step Functions State machine Slack Fail に遷移した Execution を通知 Event Bridge Execution Fail Event Rule SQS Queue Lambda Functio n ・Fail した Execution ごとの情報が Consumer 側で取得できる → アラート通知⽂をより Actionable にできる ・Slack への通知件数と、実際に⾒るべき Execution 件数が⼀致する → 対応漏れしづらくなる 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 54

Slide 54 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Event Bridge Step Functions State machine Slack Fail に遷移した Execution を通知 Event Bridge Execution Fail Event Rule SQS Queue Lambda Functio n ・Fail した Execution ごとの情報が Consumer 側で取得できる → アラート通知⽂をより Actionable にできる ・Slack への通知件数と、実際に⾒るべき Execution 件数が⼀致する → 対応漏れしづらくなる 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ 実際の Slack 通知

Slide 55

Slide 55 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Event Bridge Step Functions State machine Slack Fail に遷移した Execution を通知 Event Bridge Execution Fail Event Rule SQS Queue Lambda Functio n ・Fail した Execution ごとの情報が Consumer 側で取得できる → アラート通知⽂をより Actionable にできる ・Slack への通知件数と、実際に⾒るべき Execution 件数が⼀致する → 対応漏れしづらくなる 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ エラー情報の通知 ・どのジョブか ・どの請求 ID か

Slide 56

Slide 56 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (6) ジョブの成否監視と通知 実装(最初期) • Datadog Integration を⽤いてステートマシンの Fail を監視していた • 1時間未満で実装できる点が素晴らしかった • メンテナの⽴場としては監視・通知要件を⼗分満たしていなかった • 失敗したステートマシンの個別の情報がわからない(Execution ARN, Input) • 「直近 N 分間でエラーがあったかどうか」の判定であるため、アラート通知のされ⽅と障害対応の実態(1件単位を⾒たい)がリンクしない • 「要対応のレギュラー事象が発⽣している」ことだけを知らせる仕組みとしては依然有⽤ • 業務担当者(not 技術職)向けの Notice として残している 実装(現在) • EventBridge + Amazon SQS + Lambda 経由の通知に変更 • ステートマシンの実⾏状態変化 (to Fail) を拾ってキューイング、Lambda から Slack の専⽤チャンネルに通知 • 「Slack の通知1件 = 1件の請求がストップ」であるため解釈しやすいのが好都合だった • 「通知に対して⾃分がリアクションしていない=対応漏れ」であるとわかるので漏れが起きづらい Event Bridge Step Functions State machine Slack Fail に遷移した Execution を通知 Event Bridge Execution Fail Event Rule SQS Queue Lambda Functio n ・Fail した Execution ごとの情報が Consumer 側で取得できる → アラート通知⽂をより Actionable にできる ・Slack への通知件数と、実際に⾒るべき Execution 件数が⼀致する → 対応漏れしづらくなる 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ 対応漏れなし︕

Slide 57

Slide 57 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (7) ステートマシンの分割思想の是⾮ • ステートマシンの「構成単位」の分割 • 請求書作成 • AWS 利⽤明細作成 • メール送付 • ステートマシンの「実⾏粒度」の分割 • 請求1件ずつ実⾏ (Execution) する仕様 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 58

Slide 58 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (7-1) ステートマシンの構成単位での分割 • 外部サービス API の応答不良による失敗に多少の耐性がつく • 複数の SaaS を使っており、そのうち⼀部サービスは稀に Timeout で失敗することがある • 失敗した場所からリトライすれば良い • 監視・通知の実装が簡単 • 何がどう失敗したのかの情報が取りやすい • アラート通知の実装が楽 • 外部サービス API の呼び出し頻度をコントロールしづらくなった • 特に Salesforce ではすべてのステートマシンでそれぞれクエリする⽤事がある • サービス(ステートマシン)跨ぎで特定サービスのスロットリングを気にする必要がある 構成要素が把握しやすく、基本的には良い判断だった 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 59

Slide 59 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (7-2) ステートマシンの実⾏粒度の分割 • ジョブ失敗時の対応が⾮常に楽 • 影響範囲の特定 • 並列実⾏している ”隣” の請求に影響が出ない • 原因の切り分け調査 • 少数であればリトライはコンソールで⼀瞬 • 監視・通知の実装が簡単 • 何がどう失敗したのかわかる • 外部 API の呼び出しの時間密度が⾼い • Salesforce へのクエリで N+1 ライクな箇所がある • スロットリングを起こしやすい • 分割を進めた弊害で、全体としての API コールの 頻度を⾮常にコントロールしづらい 直感的で把握しやすい、 ただしバッチ処理のアーキテクチャとしては⾮効率 メリット デメリット 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 60

Slide 60 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (7-3) 外部サービス API のスロットリング対策 [A] そもそも⼤量にコールしないで済むような構成を採る • アーキテクチャを変える、N+1 クエリを回避する、Bulk API があれば⽤いる、など • 正攻法ではあるが限度もある • e.g) サービス側の API 仕様でリクエスト/レスポンスのペイロード⻑上限がある [B] 実⾏間隔を空けて個々でリトライ • タスクの Exponential Backoff リトライや、Execution 1件ごとの実⾏インターバルの指定 • 最も簡易的な緩和策 • 429 レスポンス時に Retry-After ヘッダを返す API であれば(※1)もう少し建設的な対策ができるかも • ステートマシンの Wait ステート + InputPath で動的な時間指定 + ⾃前のループ構造を実装することで対策になりそう • 採⽤できるかどうかはサービスの API 仕様や、採⽤している SDK / ラッパーライブラリの実装に依る 個々のステートマシン、Lambda から直接呼び出す限りは回避が難しい 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ ※1 ... 参考: MDN Web Docs - 429 Too Many Requests https://developer.mozilla.org/ja/docs/Web/HTTP/Status/429

Slide 61

Slide 61 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (7-3) 外部サービス API のスロットリング対策 [C] API 呼び出しを直接実⾏せず、レート制御の責務ごと別の Proxy サービスに切り出す • .waitForTaskToken を⽤いて外部 API 呼び出し(およびレート制御)の責務をステートマシンの外部に切り出す • (参考) サービス統合パターン https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-to-resource.html#connect-wait-token • e.g) SQS を介してステートマシンと外部サービスを同期的に統合する • 同種のクエリ (where 句の条件のみが異なる)をマージできる可能性がある • 構成要素は増えるので、やりたいことに対して Too much の感もある • 素直に元の構成をチャンク対応する⽅向で考えた⽅が建設的では。。。(今回の事例の場合) 個々のステートマシン、Lambda から直接呼び出す限りは回避が難しい 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ 外部サービスのスロットリング対策は発表者⾃⾝まだ⾒解がふわふわしています。 SNS コメント等でご意⾒・フィードバック等あればお聞かせください。ディスカッションしましょう🙏 🙏

Slide 62

Slide 62 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (8) テスト ⼿探り中 ⾃動化したユニットテスト+ ⼿作業の結合テストでリリース判定している • ユニットテストをかなり⼿厚めにした • Small サイズ (※1) に収まる & ロジック部分のテストを⾃動テストで担保しにいく意識 • ⼿元 + GitHub Actions で Lint + Test + Coverage を随時実⾏ • 結合テストの領域を(⾃動テストの枠組みで)担保しに⾏くのは諦めた • 結合テストはステートマシン単位、⼿作業で検証 • AWS 以外の外部サービスに複数依存している • サービスによっては本番同等の環境再現が困難で⾃動化を諦めた ※1 Google Testing Blog - Test Sizes ... https://testing.googleblog.com/2010/12/test-sizes.html 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 63

Slide 63 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. (8) テスト • ステートマシン単位の⾃動テストを実現させたい(できてない) • 外部サービス (SaaS) との付き合い⽅が最⼤の課題 • Step Functions, Lambda は実際にデプロイする前提で、SaaS 連携の部分をよしなにしたい • localstack, step functions local などのコンテナベース環境はテスト時に利⽤していない • テストのため「だけ」の技術スタック(キャッチアップ & 維持コスト)を要求する • 実環境で動かす場合と、コンテナ環境を動かす場合のメリット差分はなにか︖ • そこに⼿間暇かけるよりはデプロイして確認した⽅がより正確で、得るものも⼤きいと考えている • ローカルでのイテレーションが捗る点は利点 • ステートの遷移を再現する⽤途としてはありがたい(ただ、環境構築の部分に障壁がある印象) • チームの体制・状況等で結論が変わる可能性はある 今回の案件で⾏った設計や実装の 意思決定と、それに伴うトレードオフ

Slide 64

Slide 64 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 振り返り

Slide 65

Slide 65 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. 振り返り うまくいった 苦労した(している) • 業務的な⽬的は⼗分達成した • AWS での内製化 • AWS 利⽤料が約 $10.0/⽉ 前後 • ⽚⼿間リソースでなんとか(?)なっている • 時期が偏る稼働特性に噛み合っている • ステートマシンを請求1件単位にしたこと • 失敗状況が追いやすくリトライが容易 • 悪い点もあるが、業務の回しやすさはある • 監視 • 現状の業務要件に照らして必要⼗分 • プロジェクトの計画と下準備 • CRM 上の既存データ構造、業務ルールの理解 • 移⾏の段取り • システム化 しない スコープの決定 • ステートマシン単位のテスト • 外部サービス (SaaS) との付き合い⽅ • テスト • スロットリング対策 • メンテの頻度が確保できていない • 依存関係のこまめな更新 • CI/CD の整備 • メールのバウンス対応 • 愚直にやるしかない

Slide 66

Slide 66 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. おわりに まだ喋りたいことが ... • トレーシングの活⽤と、ハマった事例 • 保守しやすいデータ構造 (Task input/output) の設計 • Lambda のデプロイは Zip? コンテナ? • 「AWS SDK サービス統合」は使う︖ • たられば話 • 懐事情的な制約を外したら採⽤スタックの結論は変わる︖ • Python ? • ECS Fargate ? • Serverless Framework? terraform? AWS CDK?

Slide 67

Slide 67 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. おわりに Step Functions はいいぞ

Slide 68

Slide 68 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Thank you! © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. HASHIMOTO Takuya Serverworks Co., Ltd. Twitter: @hassaku_63 We are Hiring ! https://www.serverworks.co.jp/recruit

Slide 69

Slide 69 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Appexdix

Slide 70

Slide 70 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. © 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. a. デプロイ⽤ Makefile

Slide 71

Slide 71 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Makefile Makefile (抜粋) AWS_PROFILE の指定有無をチェックし、 プロンプトを出す Python スクリプト “check_profile.py”を実⾏

Slide 72

Slide 72 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Makefile Makefile (抜粋) prod へのデプロイタスクを “check-aws-profile” に依存することで デプロイ前にプロファイル指定を確認するプロンプトを出す デプロイステージを prefix にしておくことで、 tab 補完 -> ⼿拍⼦デプロイ実⾏ ...のような事故が起きづらい

Slide 73

Slide 73 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. ガードレール⽤の簡易補助ツール check_profile.py

Slide 74

Slide 74 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. ガードレール⽤の簡易補助ツール check_profile.py 実際の deploy コマンドを実⾏する前に プロンプトを表⽰して警告

Slide 75

Slide 75 text

© 2022, Amazon Web Services, Inc. or its affiliates. All rights reserved. Point 慣れによる「油断」が発⽣する前提で、その抵抗措置を講じる意識だった • タスクの名前は ”-” でデプロイステージ名を prefix • 最初に “prod” とタイプするので、⼊⼒を「対象環境の認識」から始められる • ⼿拍⼦で tab 補完 → Enter パーン → 「あっっ」する確率が減る(体感) • 本番環境対象の場合のみ AWS_PROFILE の確認⽤プロンプトを出す • 簡易的な CI/CD の承認フローのような感じ • 本番環境の場合のみプロンプトを出すことで「本番」であることを認識しやすくなる • システム側の管理者が複数⼈体制になるならデプロイ⾃動化する • よくあるマージトリガー⽅式の⾃動実⾏にするかどうかは思案中。個⼈的には(今回の案件では)不要と判断 • 任意のタイミングで任意の commit, tag をデプロイできる⽅が好み(トリガーは GitHub の UI や⾃作 bot) • ⾃動化をマージトリガーに結合しても、さほど楽にならない(今回の開発規模が⼤きくないことも理由) • 期待する恩恵はデプロイの再現性を⾼めることであって、⾃動実⾏ではない • トラブル時の調査やリカバリで余計な追加要素を考えなくて済む