ちょっと話題の記事

全リージョンのEC2メンテナンスイベントを一覧表示するRubyスクリプト

2014.09.25

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

はじめに

こんにちは植木和樹です。本日(2014/09/25)、AWSより各アカウントへEC2メンテンナンスのお知らせが通知されております。EC2が稼働している、仮想ホストサーバーに対するメンテナンスのようで、かなり広範囲のインスタンスに影響がでているようです。

さてAWSからのお知らせには、具体的にどのEC2インスタンスが対象になるかは記載されておりません。マネージメントコンソールの"Events"ページを確認すれば分かるのですが、関係各所へ連絡するにあたり「いつ」「なにが」を一つ一つコピペするのは重労働です。

というわけでRubyでスクリプトを作成してみました。

スクリプト

作成にあたっては「rubyのaws-sdkでEC2のイベント情報を取得する - Qiita」を大いに参考にさせていただきました。ありがとうございます。

お約束の望月さん作aws-profile_parserを利用しています。

gem install aws-profile_parser

あつかうAWSアカウントが大量にある方は、やっぱり望月さん作のcredential_traverserを使うと、さらに幸せかもしれません。

cm-ec2-describe-events.rb

#!/usr/bin/env ruby

require 'aws-sdk'
require 'optparse'

begin
  require 'aws/profile_parser'
rescue LoadError; end

config = {}
ARGV.options do |opt|
  begin
    aws_opts = {}

    opt.on('-h', '--help')  { puts opt.help; exit 0 }
    opt.on('-d', '--debug') { aws_opts[:log_level] = :debug }
    opt.on('-k', '--access-key ACCESS_KEY') { |v| aws_opts[:access_key_id]      = v }
    opt.on('-s', '--secret-key SECRET_KEY') { |v| aws_opts[:secret_access_key]  = v }
    opt.on('-r', '--region REGION')         { |v| aws_opts[:region]             = v }
    opt.on('--profile PROFILE')             { |v| parser = AWS::ProfileParser.new; aws_opts = parser.get(v) }
    opt.parse!

    if aws_opts.empty?
      puts opt.help
      exit 1
    end
    AWS.config(aws_opts)
  rescue => e
    $stderr.puts e
    exit 1
  end
end

ec2 = AWS::EC2.new
AWS.memoize do
  #全リージョンを対象とする
  ec2.regions.each do |region|
    puts region.name

    reg = ec2.regions[region.name]
    reg.instances.each do |i|
      # イベント取得
      status = reg.client.describe_instance_status( :instance_ids => [ i.id ])
      events = status.data[:instance_status_set][0][:events_set] rescue nil
      next if events.nil? or events.empty?

      events.each do |event|
        next if event[:code] != "system-reboot" # システムリブート以外のイベントはスキップ
        next if event[:description] =~ /^\[Completed\]/ # 完了したイベントはスキップ
        printf "%10s %-20s %-20s %-20s %-16s - %-16s\n",
          i.id,
          i.tags["Name"],
          i.availability_zone,
          event[:description],
          event[:not_before].localtime.strftime("%Y-%m-%d %H:%M"),
          event[:not_after].localtime.strftime("%Y-%m-%d %H:%M")
      end
    end
  end
end

以下のように$HOME/.aws/configに記載されたプロファイル名を指定して実行してください。

$ ruby ./cm-ec2-describe-events.rb --profile default
eu-west-1
sa-east-1
us-east-1
ap-northeast-1
i-12345678 cm-ueki-ap1       ap-northeast-1a      Scheduled reboot     2014-09-28 03:00 - 2014-09-28 07:00
i-98765432 cm-ueki-db1       ap-northeast-1a      Scheduled reboot     2014-09-28 03:00 - 2014-09-28 07:00
us-west-2
us-west-1
ap-southeast-1
ap-southeast-2

まとめ

awscliでもイベントはとれるのですがNameタグを取るのが難しく、インスタンスIDだけではどのサーバーが分かりにくいです。EC2一覧をグルグルまわして何かを処理する雛形だけでも手元に置いておくとパッと応用がきいて便利ですね!!

参考:awsclie版

% aws ec2 describe-instance-status --query "InstanceStatuses[?Events != null]" | 
  jq -r '.[] | [
    .InstanceId,
    .AvailabilityZone,
    .Events[].Code,
    .Events[].Description,
    .Events[].NotBefore,
    .Events[].NotAfter
  ] | @csv'