boto3でqueryオプションっぽいことを実行する

2018.01.31

こんにちは、城岸です。

先日Pythonとboto3(AWS SDK for Python)を使ってAWSリソース情報を取得するコードを書いていたところ「awscliでいうところのqueryオプションを使いたい!!」という場面に遭遇しました。
このような状況はかなりレアだと思いますが、やりたいことが実現できたので紹介したいと思います。

やりたかったこと

  • 特定のメトリクス名をもつフィルターから発報されるアラーム情報を取得する。

これがやりたかったことになります。言葉だと少しわかりにくいでが、下図でいうと「test-metricsというメトリクス名をもつtest-fliterフィルターから発報されるtest-alarm情報を取得する」ということになります。

Pythonで取得

もちろんboto3のコマンドとPythonの処理で欲しい情報を取得することはできます。下のようなイメージです。

import boto3
cloudwatch_client = boto3.client('cloudwatch')
describe_alarms = cloudwatch_client.describe_alarms()
describe_alarm = [describe_alarm for describe_alarm in describe_alarms['MetricAlarms'] if describe_alarm['MetricName'] == 'test-metrics']

普段からPythonを使っている方であれば、この書き方の方が見やすいかもしれません。
ですが、個人的にはちょっと書きにくくawscliのqueryオプションぽく取得できればなと思っておりました。

awscliのqueryライクに取得

そんなこんなで実現方法を調べていたところ、awscliのqueryオプションでは内部的にjmespathが実行されているということがわかりました。つまり、Pythonでもjmespathが実行できればawscliのqueryオプションと同じ結果を取得することができるということです。そんな訳でawscliのqueryライクに書いたコードは以下になります。

import boto3
import jmespath
cloudwatch_client = boto3.client('cloudwatch')
describe_alarms = cloudwatch_client.describe_alarms()
describe_alarm = jmespath.search('MetricAlarms[?MetricName==`test-metrics`]',describe_alarms)

awscliのqueryオプションをよく使う人には読みやすいコードになりました。

まとめ

boto3をqueryオプションっぽく実行することで、複雑な条件のデータを簡単に取得することができました。「Python縛りでかつqueryオプションを使いたいんだ!」というマニアックな方の参考になれれば幸いです。