Fargate Spotの中断通知をAWS Step FunctionsだけでMackerelのアノテーションに記録する

Mackerelでグラフの変化とFargate Spotの中断イベントを合わせて確認したくなったので、Step Functionsで利用できるようになったJSONataを使ってLambdaを使わずStep FunctionsだけでMackerelに送れるようにしてみました。

ECSのクラスタ名と同じMackerelのサービス名にイベント時のタイミングでアノテーションを投稿する実装はこんな感じになります。

{
  "QueryLanguage": "JSONata",
  "StartAt": "Call HTTPS APIs",
  "States": {
    "Call HTTPS APIs": {
      "Type": "Task",
      "Resource": "arn:aws:states:::http:invoke",
      "Arguments": {
        "Headers": {
          "Content-Type": "application/json"
        },
        "InvocationConfig": {
          "ConnectionArn": "ConnectionArn"
        },
        "Method": "POST",
        "ApiEndpoint": "https://api.mackerelio.com/api/v0/graph-annotations",
        "RequestBody": {
          "title": "SpotInterruption",
          "from": "{% $floor($toMillis($states.input.time) / 1000) %}",
          "to": "{% $floor($toMillis($states.input.time) / 1000) %}",
          "service": "{% $replace($states.input.detail.clusterArn, /.*?\\/(.*)/, \"$1\") %}"
        }
      },
      "End": true
    }
  }
}

実際に投稿された様子

Fargate Spotの中断イベントはEventBridgeで拾うことができるので条件を設定し、対象のStep Functionsを実行すれば動かせます。

zenn.dev

気をつけポイントはあまりなく、EventBridgeのイベントのtime はISO 8601の形式でやってきて、MackerelのAPIはepoch秒なので変換してあげる必要があるくらいですがJSONataで実現可能です。

文字列操作もいろんな関数が用意されていて、正規表現で置換するなどもStep Functionsだけできるようになってます。

docs.jsonata.org

今回は簡単のためにECSのクラスタ名とMackerelのサービス名が同じ場合を想定しましたが、そうでない場合もECSのクラスタにMackerelのサービス名のタグをつけておいて、イベントがあったクラスタのARNからそのタグを取得してそこに送信みたいなフローもLambdaいらずで簡単にできそうですね。

あわせて読みたい

Step FunctionsからMackerelにリクエストを送る実装はこの記事が大いに参考になりました。

blog.utgw.net

記事内のLambdaで使っている Date.now()Math.random() 相当の関数はJSONataにもあるのでこの例も全てStep Functionsだけで実現可能になってそうですね。