SecurityGroupの逆引きをするスクリプト書いた

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

こんにちは。望月です。 今日は小ネタスクリプトを一つ。

SecurityGroupのList

AWSのセキュリティグループは、画面上から通信を許可するポート番号/IPアドレスの変更・追加・削除ができて非常に便利です。が、Management Consoleに一点不満があるとしたら、このSecurityGroupはどのインスタンスから使われているのかというのを確認するのが少し面倒だというところです。SecurityGroupの数が少ないうちはまだ良いのですが、エントリ数やインスタンス数が20や30になると追っていくのが面倒になります。

なので、SecurityGroupを利用しているインスタンスのNameタグを一覧で出力するRubyスクリプトを書きました。

コード

コードはいつもどおりGistに置いてあります。短いのでここにも貼り付けておきます。

#!/usr/bin/env ruby

require 'aws-sdk'
require 'optparse'
require 'logger'
require 'yaml'

begin
require 'aws/profile_parser'
rescue LoadError; end

ARGV.options do |opt|
  begin
    aws_opts = {}
    is_debug = false

    opt.on('-h', '--help')                  { puts opt.help; exit 0 }
    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('--debug')                       { is_debug = true}
    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)
    if is_debug
      AWS.config(:log_level => :debug, :logger => Logger.new($stdout))
    end

  rescue => e
    $stderr.puts e
    exit 1
  end
end

# list all security groups and make it Hash
security_groups = {}
# dictionary for mapping SecurityGroup ID and Name
dict = {}

ec2 = AWS::EC2.new
AWS.memoize do
  ec2.security_groups.each do |sec|
    security_groups[sec.name] = []
    dict[sec.id] = sec.name
  end

  # EC2
  ec2.instances.each do |i|
    i.security_groups.each do |sec|
      security_groups[sec.name].push(i.tags.Name)
    end
  end

  # RDS
  #
  # use bare client class because AWS::RDS::Instance
  # does not have "vpc_security_group_id" property

  rds = AWS::RDS::Client.new
  db_instances = rds.describe_db_instances.db_instances

  db_instances.each do |i|
    i.vpc_security_groups.each do |sec|
      security_groups[dict[sec.vpc_security_group_id]].push(i.db_instance_identifier)
    end
  end

# ELB
  elb = AWS::ELB.new

  elb.load_balancers.each do |lb|
    lb.security_groups.each do |sec|
      security_groups[sec.name].push(lb.name)
    end
  end
end

# Output
puts security_groups.to_yaml

コンソールから実行すると、依存関係が出力されます。
出力部分は、yaml形式にしてかなり手を抜きました。いずれ改良します。。

実行方法

以下の様な形で実行できます。

$ ruby secgroup_search.rb -k <aws_access_key> -s <aws_secret_key>
---
WebSecurityGroup:
- WEB01
AutoScaling-Security-Group-1: []
quick-create-1:
- Sever01
- WEB01
$ 

yaml形式なので、多少読みづらいですが可視化は出来ました。Valueが空の配列になっているSecurityGroupは、どこからも使われていないということです。

また、aws-profile_parserにも対応しているので、そちらがインストールされていれば以下の様に使うことも出来ます。

$ ruby secgroup_search.rb --profile default