awspecのアカウント系のAPIに悩んでいる

追記 (2017/3/10 無事解決。マージしました)

github.com

awspecでアカウントに紐づくような情報のテストが書けるように「いつかやろう」と思っていたら、とうとうそれ系のPull Requestが来てしまったので いよいよ解決しなければならない感じになっています。

後押しされた感じですね。

何が課題なのか

awspecは、AWSのサービスやリソースをIDやNameタグで一意に特定して、それに対してテストケースを書くようなAPIになっています。

例えば、EC2の場合

describe ec2('i-ec12345a') do
  it { should be_running }
end

のようにインスタンスのIDを渡すことでインスタンスを一意に特定して、そのEC2リソースについてのテストを書きます。一意に特定できなかったらエラーになります。

ところが、「VPCの最大数」や「EIPの最大数」などの上限値のチェックや、最近できたAWS Organizationsのチェックなど、awspecを実行したアカウントに紐づくような情報のテストをするようなAPIは提供されていません。

具体的にaws-sdk-rubyでいうと

  • Aws::EC2::Client#describe_account_attributes
  • Aws::RDS::Client#describe_account_attributes
  • Aws::SES::Client#get_send_quota
  • Aws::Organizations::Client#describe_organization
  • Aws::Organizations::Client#list_accounts

などで取得できるような情報のテストです。

違いとしては、これらは特に一意に特定するようなIDやNameタグがもともと必要ないのです。

微妙な違いですが、そもそも他のリソースタイプと同列に扱って良いのかそうでないのか、決め手がありません。

実装のアイデア

今のところ思いついているアイデアは2つです。

追記: アイデア3をいただきました

イデア1

テストしたい情報を別々のリソースタイプとして定義する

describe ec2_attributes do
  its(:max_elastic_ips) { should eq 5 }
  its(:max_instances) { should eq 20 }
end

describe ses_send_quota do
  its(:max_24_hour_send) { should eq 200.0 }
  its(:max_send_rate) { should eq 1.0 }
  its(:sent_last_24_hours) { should eq 1.0 }
end

describe organization do
  its(:id) { should eq 'o-exampleorgid' }  
  its(:arn) { should eq 'arn:aws:organizations::111111111111:organization/o-exampleorgid' }  
  it { should have_account('222222222222') }
end

イデア2

アカウントとAWS Organizationsの2つにわけて、リソースタイプを定義する

describe account do # or account_attributes
  its('ec2.max_elastic_ips') { should eq 5 }
  its('ec2.max_instances') { should eq 20 }
  its('ses_send_quota.max_24_hour_send') { should eq 200.0 }
  its('ses_send_quota.max_send_rate') { should eq 1.0 }
  its('ses_send_quota.sent_last_24_hours') { should eq 1.0 }
end

describe organization do
  its(:id) { should eq 'o-exampleorgid' }  
  its(:arn) { should eq 'arn:aws:organizations::111111111111:organization/o-exampleorgid' }  
  it { should have_account('222222222222') }
end

イデア3 ( from @inokara )

account_attributeに引数を与えることでネストを防ぐ(おそらくアイデア2と共存可能)

describe account_attribute('ses_send_quota') do
  its(:max_24_hour_send) { should eq 200.0 }
  its(:max_send_rate) { should eq 1.0 }
  its(:sent_last_24_hours) { should eq 1.0 }
end

今のところアイデア2のほうが使う側としては直感的かなーとは思っているのですが、決め手がなく悩んでいるところ。

うーん。