CloudWatch Alarmを管理する、たったひとつの冴えたやりかた

記事タイトルとURLをコピーする

こんにちは。照井@さっぽろです。

札幌は雪虫が大量発生しています。厳密には、雪っぽい虫は少数派で、同じ種類でも雪っぽくない虫が居るのか別の種類なのかは分かりませんが、雪っぽくない方の虫が大量発生して、外を歩くとその虫が大量に体中にくっつくので、ちょっと迷惑だったりします。離れて眺めている分にはふわふわ白いのが漂ってて良い感じなんですけどね・・・。
とか言ってたら雪が降ってきました。寒い。。。

さて、皆さんAWS環境の監視はどうしていますか?CloudWatchを使っていますか?
マネージドサービス系はそもそもCloudWatchでしかメトリクスを取れないので切っても切れない関係ではありますが、実際にアラートを飛ばすのはCloudWatchからデータをAPIで抜いて他の監視ツールやサービスから飛ばすような運用をしている方も多いと思います。

そういった運用をする理由の一つに「アラームの管理が大変」ということがあるかと思いますが、今回はそのアラーム管理をとても楽にするたったひとつかは正直分かりませんが、とても便利な方法を紹介したいと思います。

CloudWatchのアラーム管理が大変なのは何故か?

その理由の大きなものに「リソース変化への追従が大変」というものがあると思います。たとえば、EC2やEBSだと1リソース単位で監視しようとすると、標準のEC2メトリクスはID(InstanceID, VolumeID)がキー(Dimension)となっているため、AutoScalingは言わずもがなですが、障害のリカバリなどでAMIから再作成するような場合でもIDが変わってしまうため、その度にアラームの再設定が必要になってしまいます。

起動時にUserData等で自身のmetadataからIDを取得してアラームを設定するような処理を埋め込むことも可能ですが、監視の敷居値が個々のインスタンス内で持つことになるのでメンテナンスがツラいのと、最初の設定は自動化されても不要になったアラーム設定は残り続けるためにゴミだらけになってしまう等の問題もあります。
また、そもそもこの方法はEC2だからできるのであってマネージドサービスでは不可能な方法です。

たったひとつの冴えたやりかた

使用するツール

こちらのツール(とAWS SDK for Ruby)を使用します。
winebarrel/radiosonde: Radiosonde is a tool to manage CloudWatch Alarm. It defines the state of CloudWatch Alarm using DSL, and updates CloudWatch Alarm according to DSL.

Radiosonde というツールで、Cookpadの菅原さんが開発したCodenize.toolsの一つです。CloudWatch AlarmをRuby DSLで記述し、その定義に従ってAlarm設定のCRUDを行ってくれます。いつもお世話になっております。

動的にリソースの変化に対応する定義の書き方

インストール方法や基本的な使い方はREADMEをご覧いただくとして、ここでは動的にリソースの変化に対応する定義の書き方をご紹介したいと思います。

簡単な例としては、以下のようになります。

require 'aws-sdk'

ec2 = Aws::EC2::Client.new
instances = ec2.describe_instances.reservations.first.instances

instances.each do |instance|
  alarm "CPUUtilization_#{instance.instance_id}" do
    namespace "AWS/EC2"
    metric_name "CPUUtilization"
    dimensions "InstanceId"=>instance.instance_id
    period 300
    statistic :average
    threshold ">=", 90.0
    evaluation_periods 1
    actions_enabled true
    alarm_actions ["arn:aws:sns:us-east-1:123456789012:my_topic"]
    ok_actions ["arn:aws:sns:us-east-1:123456789012:my_topic"]
    insufficient_data_actions ["arn:aws:sns:us-east-1:123456789012:my_topic"]
  end
end

ポイントとしては以下のような点になります。

  • 対象のリソースはAWS SDKを利用して動的に取得する
  • アラーム名やDimensionなど、リソース毎に異なる部分には上記で動的に取得したデータを利用する

このような記述をすることで、既に設定済みのアラームの設定変更が一箇所で済むことはもちろんのこと、新しいリソースへの設定が追加され、削除されたリソースへの設定は削除されるため、存在するリソースに対してのみアラームを設定することが出来ます。
定義と実際の設定を比較し、同じ状態に設定してくれる冪等性のあるRadiosonde というツールのおかげです。最高ですね。
また、この例では使用していませんが、describe系のAPIは、ほとんどfilter等の引数でフィルタリングできるため、「特定のタグを持つリソースのみ」などに限定することも可能です。

これをCronやJenkinsなどで回せば、常に最新のリソース状況に追従させることも可能です。

最後に

面倒な設定管理も、動的な記述が可能なツールを使うことで、このように柔軟な管理を実現できます。Cloud FormationやTerraformも良いですが、私がCodenize.toolsを好んで使う大きな理由の一つがこれです。こういったことができることこそInfrastrincute as Codeの本領ではないかと思ったりもします。このように、積極的にコード化を推進して、より効率を高め価値創造へフォーカスしていきたいですね。