[待望の新機能] MackerelのAWSインテグレーションがAPI経由で追加・更新可能になりました! #mackerelio

もう監視対象のAWSサービスが増えるたびにWebからぽちぽちしなくて済みます! Mackerel as Codeをさらに進める、個人的に待望の機能を紹介します。
2020.06.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ついに! Mackerel の AWS インテグレーション機能を API 経由で操作可能になりました!

実はアナウンスに先立って、 6/4 (木) には上記のドキュメントも公開されていたので、お気付きの方もいらしたかと思います。

Mackerel はその取っ掛かりの手軽さと拡張性が特徴ですが、API が豊富に用意されていて「as Code」でコントロール可能なところも魅力のひとつと思っています。
ところがこれまで、AWS インテグレーション機能については API が用意されておらず、AWS を主戦場とする弊社社員としては長年歯がゆい思いをつのらせておりました。Meetup などの場ではてな社の方々に直接お願いしたことも 1 度ではないと思います。

それが! ついに!

というわけで、さっそくご紹介してまいります。なお現時点では mkr コマンドなどでのコントロールは出来ないため、API をcurlで直接叩く感じになります。
API を直接叩くことについては、以前ブログを書いていますのでそちらもご参照ください。

API

用意されている API は、以下の 7 つです。

動作 METHOD 説明
設定の一覧 GET 既存の AWS インテグレーション設定を全て取得
設定の取得 GET ID を指定し、AWS インテグレーション設定を個別に取得
設定の登録 POST AWS インテグレーション設定を新規に作成
設定の更新 PUT ID を指定し、AWS インテグレーション設定を個別に設定変更
設定の削除 DELETE ID を指定し、AWS インテグレーション設定を個別に削除
外部 ID の生成 POST AWS インテグレーション用 IAM ロールに設定する External ID を払い出す
除外可能なメトリック名の一覧取得 GET 各サービスごとに除外設定可能なメトリックの一覧を取得

それぞれ、利用シーン別に見てみましょう。

なお以下、JSON の整形に jq コマンドを多用していきますのでご了承下さい。
もし jq を使われたことがないという方がいましたら、便利ですのでこの機会に如何でしょう。下記のブログと公式マニュアルが参考になると思います。

また記載するコマンドライン (BASH) は、Mackerel の API キーが環境変数 MACKEREL_APIKEY に設定済みという前提です。

$ export MACKEREL_APIKEY={APIキー}

現在の AWS インテグレーション設定を一覧する

動作 METHOD API
設定の一覧 GET /api/v0/aws-integrations

その名の通り、AWS インテグレーションの設定一覧を JSON で取得できます。ちょっとやってみましょう。

curl -s \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations
{"aws_integrations":[{"id": ...(以下略)...}

こういう感じで、複数設定されている(かもしれない)AWS インテグレーション機能の全設定を一括で参照できます。
ちょっと見難いと思うので、jq を使って、いくつかの情報を抜き出してみましょう。ID と名称、取得対象とするタグ、有効になっているサービスを取り出してみます。

curl -s \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations \
| jq '.[][]|
    {"id":.id,
     "name":.name,
     "includedTags":.includedTags,
     "services":.services|[ to_entries[]|select(.value.enable==true).key ]
    }'
{
  "id": "3xxEXAMPLEx",
  "name": "AWS Integration-1",
  "includedTags": "monitoring:mackerel",
  "services": [
    "RDS",
    "EC2"
  ]
}

こういう感じで、「いまどんな AWS インテグレーションが設定されているか」を俯瞰する際に有用な API だと思われます。
下で紹介する「AWS インテグレーション単位での設定更新」を行う前段階として、ID を調べたりする時にも重宝しますね。

AWS インテグレーションの設定でサービス個別に除外設定可能なメトリクスの一覧を取得

動作 METHOD API
除外可能なメトリック名の一覧取得 GET /api/v0/aws-integrations-excludable-metrics

Mackerel の AWS インテグレーション機能は、監視する必要のないメトリクスを設定することが可能です。

そのためには「何が除外設定可能か」を知る必要があるのですが、それはこの API で取得が可能です。
普段はあまり使わないかもしれませんが、例えば Mackerel の設定 UI を独自に作っておいたり、設定の validate を JSON ファイルの時点で行うなどの用途では便利そうです。

curl -s \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations-excludable-metrics \
| jq .
{
  "RDS": [
    "rds.cpu.used",
    "rds.cpu_credit.used",
    "rds.cpu_credit.balance",
    "rds.database_connections.used",
    "rds.memory.free",
    "rds.memory.swap",
    "rds.disk_usage.bin_log",
    "rds.network_throughput.receive",
... (以下略)

既存の AWS インテグレーション操作を個別に行う

各 AWS インテグレーションの設定を as Code で管理する時には、ID を指定する系の API が便利です。

動作 METHOD API
設定の取得 GET /api/v0/aws-integrations/{awsIntegrationId}
設定の更新 PUT /api/v0/aws-integrations/{awsIntegrationId}
設定の削除 DELETE /api/v0/aws-integrations/{awsIntegrationId}

例えば ID: 3xxEXAMPLEx の設定内容を aws-integration-3xxEXAMPLEx.json として保存 (GET) しておいて、変更はその JSON に対して行い PUT する、ということが可能です。mkr で監視ルールを扱うときのような感じで、GitOps することもできますね。
取得するとき、API の出力のままだと人間には読みづらいし差分確認も大変になるので、jq などをはさんで可読性を上げておくとよいでしょう。そのままの状態で PUT することは可能です。

### 取得 (GET)

AWS_INTEGRATION_ID=3xxEXAMPLEx
curl -s \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations/${AWS_INTEGRATION_ID} \
| jq . > aws-integration-${AWS_INTEGRATION_ID}.json
### 更新 (PUT)

AWS_INTEGRATION_ID=3xxEXAMPLEx
curl -s \
    -X PUT \
    -d @aws-integration-${AWS_INTEGRATION_ID}.json \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations/${AWS_INTEGRATION_ID}

AWS インテグレーションを新規に追加する

動作 METHOD API
設定の登録 POST /api/v0/aws-integrations
外部 ID の生成 POST /api/v0/aws-integrations-external-id

最後に残った API の紹介をしつつ、まだ AWS インテグレーションを設定していないオーガニゼーションに対して、新規に設定する場合の手順を書いておきます。
ざっくりと以下の手順になります。

  1. 外部 ID を払い出す
  2. 払い出した外部 ID を IAM ロールに設定する
  3. 外部 ID と IAM ロールを使って、AWS インテグレーションの設定 JSON を POST する

1. 外部 ID を払い出す

Mackerel の AWS インテグレーション設定を行うには、まず「外部 ID(External ID)」を払い出してもらう必要があります。
これを IAM ロールに設定することで、セキュリティを保ちつつ柔軟に外部 SaaS から AWS リソースへのアクセスを可能にしています。

また、外部 ID が固定ではなく個別に払い出されることに対する経緯については、以下のブログで説明されています。
上記 AWS ドキュメントの「"混乱した代理" 問題」の項と合わせてご参照ください。

というわけで、
まずはこの外部 ID を払い出してもらいます。

curl -s \
    -X POST \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations-external-id
{"externalId":"AAAA.....aaaaEXAMPLE"}

この ID は以下の手順でつかうのでとっておきましょう。

なお、現在 AWS インテグレーションを使用中の場合に払い出した場合でも、既存の ID が無効になるわけではない(みたいな)のでご安心ください。
ちなみに外部 ID は、API ドキュメントによると、ひとつのオーガニゼーション内では使い回しが可能とのことです。

一度発行した外部IDは、当該外部IDが設定されたAWSインテグレーション設定が全て削除されない限り、同一オーガニゼーション内であれば再利用することができます。

2. 払い出した外部 ID を IAM ロールに設定する

こちらは AWS 上の作業になります。監視対象の AWS 環境にて、以下の手順に従って IAM ロールを作成します。
このときの外部 ID として、 1. で払い出してもらった ID を指定するようにしてください。

作成された IAM ロールの ARN を次で指定する必要があるので、忘れずにコピーしておきましょう。

3. AWS インテグレーションの設定 JSON を POST する

準備が整いましたので、いよいよ AWS インテグレーションを作成しましょう。設定内容を書いた JSON を用意して POST する感じです。
必要な最低限のエントリはこんな感じです。

{
  "name": "AWS Integration 2",
  "memo": "",
  "roleArn": "arn:aws:iam::{AWSアカウントID}:role/MackerelAWSIntegrationRole",
  "externalId": "AAAA.....aaaaEXAMPLE(外部ID)",
  "region": "ap-northeast-1",
  "includedTags": "",
  "excludedTags": "",
  "services": {}
}

このような JSON ファイルをファイル名 aws-integration-new.json として保存しておいて、以下のようにして API にたたき込めば ok です。

curl -s \
    -X POST \
    -d @aws-integration-new.json \
    -H 'X-Api-Key: '${MACKEREL_APIKEY} \
    -H 'Content-Type: application/json' \
    https://api.mackerelio.com/api/v0/aws-integrations

この JSON の場合だと、AWS インテグレーションは設定されるものの監視対象は何もないという状態ですね。EC2 と ALB など、監視対象が決まっているならこの時点で設定しても良いですし、上にあげた別の API でアップデートしてもいいでしょう。

まとめ

個人的にいちばん待ち望んだ API が、ついに最高の形で実装されました!

弊社内で Mackerel を使う場合、AWS インテグレーションはほぼ必須なのですが、この部分が毎回 Web からしか設定できない・設定内容を Code に落とせないことが悩みの種でした。そんな悩みともおさらばです。はてな開発陣の方々には厚く御礼申し上げます。

みなさんもよき Mackerel ライフを!