非エンジニアでもサーバー増強できるDatadogワークフローを作ってみた
はじめに
前置きがかなり長いので、作り方だけを知りたい方は ワークフローを作ってみよう までジャンプ推奨です!
経緯
私が担当しているプロダクトではかつて、アクセスが集中するタイミングに合わせてインフラエンジニア(私)が張り付きで見守りを行っていました。
しかし、インフラエンジニアの数に対して、見るべきプロダクトは増え続ける一方です。1つのプロダクトに張り付いて面倒を見ることはだんだん難しくなり、手離れが必要な頃合いとなってきました。また同時に、これまで行った負荷対策により多少の負荷ではダウンしないという実績が積み重なり、見守りの必要性自体も薄れてきました。
2024年7月の組織再編を皮切りに、私が他のプロダクトにも横断的に参画できるよう、これまでの担当プロダクトから徐々に手離れしていく流れができてきました。
とはいえ、いきなり完全に手離れとはいかず、アクセス集中に備えての事前のサーバー増強は今でもインフラエンジニアが担当しています。
それも自動化できればさらに手離れが進むのでは、と考えました。
自動化の要件
自動化の必須要件は 「非エンジニアだけで完結できる」 ことです。
今回のプロダクトでは、開発担当のエンジニアとは別に、現場担当の運営チームが24時間シフト制で稼働しています。この体制に着目し、運営チームだけで完結できる仕組みがあれば理想的と考えました。
現在は、アクセス集中が予想されるイベントを実施する際、運営チームからインフラエンジニアへ事前に連絡し、その情報をもとにインフラエンジニアが負荷対策を行っています。
しかし、イベントの予定が直前に変動することもあり、夜間や休日に急な対応が求められるケースもあります。また、運営チームが自由に集客施策を実施できず、必ずインフラエンジニアを介さなければならない状況は、ビジネス上の機会損失となりかねません。
そこで、運営チームが任意のタイミングでサーバー増強できるようになれば、インフラエンジニアとしても急な呼び出しがなくなり、運営チームとしても現場の状況に応じた集客が可能になり、両者にとってうれしい結果になると考えました。
例えば、品切れしていた人気商品の在庫が復活したとき、サービス上で再入荷処理を行いプッシュ通知でお知らせして集客する、といったことが運営チームの判断だけでできるようになります。
運営チームのスタッフのほとんどは非エンジニアです。運営チームだけで完結するには、前提知識がなくとも「このボタンを押すだけでサーバーが増える」といった簡素なインターフェースである必要があります。
なぜDatadogワークフローなのか
実装が容易
最初は別の方法での実装を考えていましたが、その方法を実現するには実装を作り込む必要がありました。もっと素早く提供したいが、時間がかかるのはやむを得ない……と考えていたとき、Datadogワークフローの存在を知りました。
試しに少し触ってみると、やりたいことが簡単に実現できたため、採用を決めました。Datadogをチームに普及させたい
もともとDatadogには運営チームのコアメンバーも招待済みですが、Datadogでのモニタリングはあまりチーム内に普及していないのが現状です。今後インフラエンジニアの手離れを進めるにあたり、Datadogをもっと身近で便利なものとして普及したいと考えています。
そこで、別のツールを使うよりもDatadogにいろいろまとまっていた方が、普及する側としてもされる側としてもハードルが低いと考えました。
今回の記事で作るもの
非エンジニアでもサーバー増強できるように「ECSサービスのタスク数を増やす」ワークフローを作ってみます。
内訳は以下の3ステップとなります。
- 現在のタスク数を取得する
- タスク数を5つ増やす
- 結果を出力する
増やすタスク数を「5つ」と固定値にしたのは理由があります。
任意のタスク数を入力できる方が機能としてはリッチですが、今回このワークフローの想定利用者は非エンジニアのスタッフです。適切な台数を判断するのは難しいですし、費用の面でもいくら請求されるか分からず不安になるでしょう。入力ミスの可能性もあり得ます。そこで、誰でも悩む余地がなく実行できることを重視して固定値を採用しました。
「5つ」という値は今回のプロダクトでは「小規模なアクセス増加であれば乗り切れる」ぐらいの大きさです。ほとんどの用途には1回の実行で十分なはずですが、もしそれ以上の大規模なアクセス増加が見込まれるなら2〜3回実行してもらえばいい、という考え方です。
なお、今回の記事では1から作る方法を紹介していますが、「Blueprints」からワークフローのテンプレートを確認・編集できるため、初めて作成する方は自分の目的に近いテンプレートがないか探してみることをオススメします。
私は最初、こちらのEC2 Auto Scalingを参考にしました。
Scale Capacity Up or Down with AWS Autoscaling ※Datadogログインが必要
ワークフローを作ってみよう
前置きが長くなりましたが、ECSサービスのタスク数を増やすワークフローの作成手順を紹介します。
作成画面へ
Datadogの左メニューから Actions > New Workflow と選択し、ワークフロー作成画面を開きます。
最初は以下のようにトリガーの選択肢が複数出てきます。Datadog上のイベントを起点にしたり、一定のスケジュールでワークフローを動作させたりできます。
ワークフロー作成画面
トリガーについては後述するためいったんスルーして、先にワークフローの中身を作り始めることにします。
ステップ1: タスク数を出力する
このステップでは、AWSのECSサービスを参照するアクションと、それを実行するための権限設定を行います。
1つ目のアクションなので少し手厚く解説していきます。
1つ目のアクション設置
トリガー一覧の下にある「Start with an action」を押します。
大分類として、対応している外部サービスなどの一覧が出てきます。「AWS」を選択します。
アクションの大分類
AWSのサービス一覧が出てきます。今回はECSサービスを操作したいので「ECS」を選択します。
AWSのサービス一覧
ECSで実行可能なアクション一覧が表示されます。まずは「1. 現在のタスク数を出力する」から実装すべく、「Describe ECS Service」を選択します。
ECSのアクション一覧
編集エリアに「Describe ECS Service」のブロックが置かれました。右のメニューに必要な情報を入れていきます。
「Describe ECS Service」を設置
初めてDatadogワークフローで利用するAWSアカウントの場合、ここでConnectionを設定する必要があります。
Connection作成
DatadogワークフローがIAM Roleを引き受けてアクションを実行できるようにします。
さきほどの画面の右メニューで、上から2番目の項目「Connection」から「New Connection」を選択します。
以下のようなConnection作成画面が出てくるため、入力していきます。
Connection作成画面
- Connection Name: 任意
- Identifier Tags: 任意
- Account ID: 目的のAWSアカウントのID
- AWS Role Name: ワークフローが引き受けるRoleの名前
- Roleを新しく作る場合、次の手順で作るRoleの名前を先に決めて入力する
多くの場合、Roleは新しく作ることになると思います。その理由は、ワークフローの設定ミスなどで意図せぬ操作をできてしまわないよう、Roleの強さを必要最低限としておきたいためです。
今後別のワークフローを作る場合でも、1つのRoleに多くの権限を与えて使い回すのは避けて、ワークフローの用途に特化したRoleを用意することをオススメします。
内容を入力し「Next, Confirm Access」ボタンを押すと、Connectionを誰に公開するかの選択肢が表示されます。チームメンバーにも使ってほしいので「My org」を選択します。
公開範囲の選択肢
Roleの作成時に必要な外部IDと、それを含んだ信頼ポリシーが表示されます。閉じる前に必ずこのjsonをコピーしてください。
Roleに設定すべき信頼ポリシーが表示される
これでConnectionの作成は完了です。
IAM Role作成
次に、ワークフロー実行に必要な権限を持ったIAM Roleを作ります。
今回はECSサービスの参照と変更を行いたく、AWS管理ポリシーの中には適切なものがないため、Roleにアタッチするポリシーを先に作成しておきます。
目的のECSサービスのみに対し、更新とすべての読み取りを許可します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:Describe*"
],
"Resource": "arn:aws:ecs:ap-northeast-1:000000000000:service/cluster-name/service-name"
}
]
}
続いてIAM Roleを作成します。
「信頼されたエンティティ」の画面で「カスタム信頼ポリシー」を選択し、ポリシー欄にさきほどのjsonをコピペします。
そのままでは「Missing Version」の警告が出るため、Versionを追記してあげるとなお良いでしょう。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::000000000000:root"
]
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "1234567890abcdef1234567890"
}
}
}
]
}
Roleの作成が完了したら、Datadogに戻ります。
アクションを完成させ、テストする
「Inputs」の中のRegion、Service Name、Clusterをそれぞれを入力します。
ECSサービスの情報を入力
ここで、このアクション単体のテストをしておきます。
画面右上の「Save」ボタンを押してワークフローを保存してから、「Inputs」の右にある「Test」ボタンを押します。テスト画面が開くので、そのまま「Test」ボタンを押しましょう。
テスト実行結果
ECSサービスの情報が取れました!
ここに含まれる desierdCount
を次のステップで使います。
ステップ2: タスク数を5つ増やす
このステップでは、
-
desierdCount
に+5した値を求める - その値を使ってECSサービスを更新する
という2つのアクションを用意します。
加算する
ステップ1で取得した desierdCount
に値を加算します。
ここで使うのは、計算を実行して次のアクションに渡すことができる「Expression」です。
ステップ1で作った「Describe ECS Service」の下の青い+ボタンを押してアクション選択画面を開き、「Data Transformation」から「Expression」を選択するか、検索欄で「Expression」と入力して直接選択します。すると「Describe ECS Service」の下に「Expression」が接続されます。
ステップ1と同様に右メニューに入力していきます。今回は入力するものが少なく、シンプルです。
- Description: 任意
- Expression:
$.Steps.Describe_ECS_service.service.desiredCount + 5
Expressionは $.Steps.
まで入力すると補完してくれるため、簡単に目的の値に到達できます。
Expressionを入力
念のためここでもアクション単体でテストを実行しておきましょう。
「Inputs」の右にある「Test」ボタンを押してテスト画面を開きます。
テスト画面には、Expressionで参照している $.Steps.Describe_ECS_service
のテストデータを入力する欄があります。赤矢印で示している時計のようなアイコンを押すと、さきほど「Describe ECS Service」をテスト実行したときに取得した値が入ります。
テスト画面
テストデータが入った状態で「Test」ボタンを押します。
実行結果
desiredCount: 3
でしたので、3+5で8となることを確認できました。
次に、この値を使ってサービスを更新します。
サービスを更新する
「Expression」の下の青い+ボタンを押してアクション選択画面を開き、「AWS」→「ECS」→「Update ECS service」を選択するか、検索欄で入力して直接選択します。
これまで同様に入力していきましょう。
- Step name: 任意
- Connection: 「Describe ECS Service」と同じConnection
- Region: サービスのリージョン
- Service name: サービス名
- Desierd count:
{{ Steps.Expression.data }}
- Cluster: クラスター名
これ以外は変更しないため空欄とします。
ECSサービスの情報を入力
ここでもアクション単体でテストを実行しておきます。
「Inputs」の右にある「Test」ボタンを押してテスト画面を開きます。
Expressionのテストと同様、Desierd countで参照している $.Steps.Expression.data
のテストデータを入力する欄があります。
今回は直接 8
を入力して実行してみます。
テスト画面
このとおり、 desiredCount
が8になりました!
AWS側でECSサービスを見ると、タスクの追加が始まっていることが分かります。
ECSサービスのタスク起動状況
ステップ3: 結果を出力する
ワークフローを実行したことをチーム全体に知らせる目的で、Slackに結果を投稿します。
「Update ECS service」の下の青い+ボタンを押して、Slackの「Send message」を設置します。
- Step name: 任意
- Workspace: 投稿したいSlackワークスペース
- Channel: 投稿したいSlackチャンネル
- @-mention targets: 任意
- Message text:
APIサーバーの台数を5台増やしました。現在の台数は {{ Steps.Update_ECS_service.service.desiredCount }} 台です。
Slackチャンネルとメッセージを入力
これで必要なアクションはすべて揃いました。では、ワークフロー全体を実行してみましょう!
右上の「Save」ボタンを押して保存してから「Run」を実行します。
実行のためのトリガーを問われるので、「Manual」を選択した状態で「Run」ボタンを押します。
「Manual」を選択して実行する
アクションに順次チェックが付いていき、最後まで実行されました。
全アクション成功
さきほどと同様にECSサービスのタスク数が増え、Slackにも意図した通りに通知が来ています!
Slack通知
トリガーはどうしよう?
記事の冒頭でトリガーを作らずスルーしましたが、どうやって実行するかを考えていきます。
開始地点の「Add Trigger」をクリックして選択肢を改めて確認します。
トリガーの選択肢
Monitor or Incident →不採用
今回は運用チームのスタッフが任意のタイミングで実行できるようにしたいので、MonitorやIncidentは使いません。
サーバー増強が目的ならMonitorでリクエスト数や応答速度の変化をトリガーにしてもよさそうですが、そこはある程度Auto Scalingでカバーできるのと、今回は「負荷が高まりそうなイベントに備えてあらかじめサーバー増強したい」、つまりMonitorに変化が起こる前に実行したいため不採用とします。
API →不採用
では、APIはどうでしょう?
選択してみると、curlコマンドが表示されます。この通りにPOSTすればワークフローを開始できそうですね。
curl -X POST \
-H "Content-Type: application/json" \
-H "DD-API-KEY: ${DD_API_KEY}" \
-H "DD-APPLICATION-KEY: ${DD_APP_KEY}" \
-d {} \
https://api.datadoghq.com/api/v2/workflows/(ワークフローのID)/instances
Slackワークフローなどを起点にしてAPIを実行できないか?と思って調べてみましたが、既存のSlackアプリからヘッダー付きでPOSTを叩く手段が意外とないことが分かりました。現時点では専用のSlackアプリを開発するしかなさそうです。(他の手段がありそうでしたら教えてください)
Dashboard →採用
Dashboardをトリガーにすると、任意のダッシュボードから実行できるようになります。
前置きでも述べた通りDatadogでのモニタリングを普及していきたいと考えており、全てがダッシュボードに集約していると都合が良いため、今回は普段使いのダッシュボードに置くことにします。
「Add trigger」の選択肢から「Dashboard」を選択します。ワークフローの始点にトリガーが設置されました。
Dashboardトリガーを設置
ワークフローが完成したので、Publishして実行できる状態にしておきます。
右上の「Publish」ボタンを押します。Connectionを作ったときと同様の選択肢が出てくるため、「Mo org」を選択して「Publish」ボタンを押します。
Publish確認画面
これでPublishは完了です。
次に、ダッシュボードから実行できるようにします。
右上の歯車アイコンから「Add to dashbord」を選択します。
Add to dashbord
ダッシュボード選択画面が出てくるので、設置したいダッシュボードを選択して「Save」ボタンを押します。
ダッシュボード選択画面
ダッシュボードを見に行くと、最下部にウィジェットが追加されています!
最初のサイズではスタートボタンしか表示されていませんが、ウィジェットを拡大することで実行履歴が確認できます。
ワークフローのウィジェット。拡大すると実行履歴が表示される
スタートボタンを押すとパラメータ入力画面が出てきます。今回はパラメータはないので、このまま「Run」ボタンを押します。
パラメータ入力画面
実行履歴に成功の結果が追加されました!
作成中のテストと同様、AWSでECSサービスのタスク数が増えていること、Slackに通知が来ていることも確認できました。
実行結果
以上で「非エンジニアでもサーバー増強できるDatadogワークフロー」は完成です!
残課題
このワークフローはある課題を抱えています。察しの良い方ならもうお気付きかもしれません。
このECSサービスにはAuto Scalingを設定しています。
つまり、一定の負荷がかかっていなければ、タスク数は減らされてしまうということです。
Auto Scalingの最小数を変更できれば良いのですが、それはECSではなくApplication Auto Scalingの範疇となります。残念ながら現時点ではApplication Auto Scalingの最小数を変更するアクションはありません。
落としどころとしては、アクセス集中が見込まれるタイミングの直前に実行してもらうことで、ひとまずは一定の実用性は確保できるかと思います。
おわりに
ツールを整備しても、使われないと意味がありません。
ドキュメントを書いて使い方を周知したり、関係者に知ってもらえるよう存在をアピールするという仕事がまだ残っています。ここからが本番と言っても過言ではありません。
属人化をなくす俺たちの戦いはこれからだ!
Discussion