こんにちは、技術3課の森です。
とうとう9月になりましたね。秋ですね。秋といえば、「食」です。秋刀魚が早く食べたい時期になってきました。
とはいえ、食べ過ぎと飲み過ぎは体を悪くしますので、健康診断でしっかりみてもらうといいかもしれません。
健康診断といえば、テスト。今回はテストについてのブログです。
はじめに
今回は、AWS環境を構築した後に、テストをしようと思い、色々探していたところ、出会ったのが、awspecです。
サーバーワークスでは、永田さんを中心にAWS環境の構築を自動化してしまおうという取り組みをされています。詳しくはこちらを。
ここで作成される定義書(YAML)を使って、awspecのインプットにしております。
作業環境構築
awspecのインストール
awspecのインストールを行います。コマンド一行でOKです。
$ gem install awspec
awspecの環境構築
次に、awspecを使って実行できる環境作りを行います。
awspecの初期化
実行に必要なファイルなどを用意するためのコマンドを実行します。
$ awspec init
これを実行すると以下のような状態となります。
$ tree . ├── Rakefile └── spec └── spec_helper.rb
クレデンシャル情報の追加
awspecを実行する環境がテストする環境であれば、IAM Roleを付与することでOKですが、異なる場合はクレデンシャル情報を用意する必要がございます。
今回は、お試しということで、「ReadOnlyAccess」ポリシーを適用したIAM Userを作成し、アクセスキーとシークレットアクセスキーを用意しています。
spec/secrets.ymlを作成し、以下の情報を入れてください。(「X」になっているところはそれぞれ、アクセスキーとシークレットアクセスキーを入力してください
region: ap-northeast-1 aws_access_key_id: XXXXXXXXXXXXXXXXXXXX aws_secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
実装
ここから実装に入ります。
準備
今回は、YAMLを読み込んでテストを実行するようにしますので、いくつか準備として、コードを追加する必要がございます。
Rakefile
まずは、Rakefileに以下の情報を追加します。
require 'yaml'
spec/spec_helper.rb
次に、spec_helper.rbに以下の情報を追加します。
@properties = YAML.load_file("aws_environment.yml")
コード作成
ここでコードの作成に移ります。環境構築自動化のYAMLファイルの例をまずは記載します。(ある程度抜粋します)
Resources: EC2Instances: - name: TEST_EC2 ebs_optimized: false source_dest_check: true key_name: test_ec2_key instance_type: m4.large image_id: ami-bbf2f9dc tags: - Name: TEST_EC2 - AUTO_START: ON block_device_mappings: - volume_type: gp2 volume_size: 1000 encrypted: false tags: - Name: EBS_TEST_EC2_01 - DiskName: root network_interfaces: - subnet: subnet-TEST-AZ-1 security_groups: - TESTSG-AP-in-01 - TESTSG-AP-ext-01 private_ip_addresses: - 10.0.1.11 - 10.1.1.11 tags: - Name: NI_TEST_EC2 - ENI: EXT
次は、コードです。
require 'spec_helper' properties = @properties print properties['Resources']['EC2Instances'] properties['Resources']['EC2Instances'].each do |ec2| describe ec2(ec2['name']) do it { should exist } its(:ebs_optimized) { should eq ec2['ebs_optimized'] } its(:source_dest_check) { should eq ec2['source_dest_check'] } its(:key_name) { should eq ec2['key_name'] } its(:instance_type) { should eq ec2['instance_type'] } its(:image_id) { should eq ec2['image_id'] } it { should have_tag('Name').value(ec2['tags'][0]['Name']) } it { should have_tag('AUTO_START').value(ec2['tags'][1]['AUTO_START']) } ##EBS## ec2['block_device_mappings'].each do |ebs| describe ebs(ebs['tags'][0]['Name']) do it { should exist } it { should be_attached_to(ec2['name']) } its(:volume_type) { should eq ebs['volume_type'] } its(:size) { should eq ebs['volume_size'] } its(:encrypted) { should eq ebs['encrypted'] } it { should have_tag('Name').value(ebs['tags'][0]['Name']) } it { should have_tag('DiskName').value(ebs['tags'][1]['DiskName']) } end end ##EBS## ##NetworkInterface## ec2['network_interfaces'].each do |eni| describe network_interface(eni['tags'][0]['Name']) do it { should exist } it { belong_to_subnet(eni['subnet']) } eni['security_groups'].each do |sg| it { should have_security_group(sg) } end eni['private_ip_addresses'].each do |pip| it { should have_private_ip_address(pip) } end it { should have_tag('Name').value(eni['tags'][0]['Name']) } it { should have_tag('ENI').value(eni['tags'][1]['ENI']) } end end ##NetworkInterface## end end
これで、実行準備は完了です。
テスト実行
これでテストを実行します。実行結果も以下のような感じで出力されます。
$ rake spec /Users/awspecuser/.rbenv/versions/2.3.4/bin/ruby -I/Users/awspecuser/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/rspec-support-3.6.0/lib:/Users/awspecuser/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/rspec-core-3.6.0/lib /Users/awspecuser/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/rspec-core-3.6.0/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb .................................................................. Finished in 2.66 seconds (files took 1.25 seconds to load) 66 examples, 0 failures
最後に
これで、テストが簡単にできるようになります。
ベースとなるコード(今回で言う「ec2_spec.rb」)を作るのに多少時間はかかるものの、ある程度汎用的には作っているので、YAMLの中身を変えれば、試験はどこでも可能になります。
(クレデンシャル情報には注意が必要)
とは言え、awspecはリソースの全てのパラメータを見れるわけではないので、目視確認は必要になります。
でも、かなりいいモノですので、是非ご活用いただければなと考えております