2017年3月30日

awspec

ブロードバンドタワー緒方です。今回は awspec を試してみたので紹介させて頂きます。

awspec とは ?

GitHub にある awspec の公式サイト によると、RSpec tests for your AWS resources.
とあります。

Serverspec の AWS 版といったところですね。

日頃 Serverspec を利用しているのですが、同じことを AWS 環境に対してできないかな、と色々と検索をしていたら awspec にたどり着きました。

インストール

今回も手元の Mac にインストールをしてみました。

Mac の環境は下記のようになっています。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G1217

$ ruby -v
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin15.0]

インストールは gem でサクッとインストールできます。

$ gem install awspec

$ awspec -v
0.67.0

無事にバージョンが 0.67.0 の awspec がインストールできました。
awspec は Ruby バージョン 2.1 以上が必要になってきますのでご注意ください。

使い方

はじめに

まず最初に awspec の初期ファイルの作成を実施します。

awspec init コマンドを実行します。

$ mkdir awstest
$ cd awstest/
$ awspec init
   + spec/
   + spec/spec_helper.rb
   + Rakefile
   + spec/.gitignore
   + .rspec

secrets.yml ファイルの準備

AWS にアクセスするための、アクセスキーやシークレットアクセスキーの情報を secrets.yml ファイルに記述します。
secrets.yml ファイルは spec ディレクトリ以下に設置します。

  • secrets.yml
region: ap-northeast-1
aws_access_key_id: <access_key>
aws_secret_access_key: <secret_access_key>

generate コマンドの実行

awspec には generate コマンドがあって、既存の AWS の状態を spec ファイル形式で表示してくれる機能があります。

spec ファイルの記述はシンプルな記法で楽に書くことができるのですが、やはりゼロから記述するのは大変です。
generate コマンドを利用して spec ファイルを簡単に作成することができます。

試しに、既に起動している EC2 の spec ファイルを作成してみしょう。

実行するコマンドは awspec generate ec2 に引数として VPC の ID を指定します。

$ awspec generate ec2 vpc-fbcf759f

describe ec2('centos7-dev') do
  it { should exist }
  it { should be_running }
  its(:instance_id) { should eq 'i-****************' }
  its(:image_id) { should eq 'ami-eec1c380' }
  its(:private_dns_name) { should eq 'ip-10-62-0-253.ap-northeast-1.compute.internal' }
  its(:public_dns_name) { should eq 'ec2-***-***-***-***.ap-northeast-1.compute.amazonaws.com' }
  its(:instance_type) { should eq 't2.medium' }
  its(:private_ip_address) { should eq '10.62.0.253' }
  its(:public_ip_address) { should eq '***.***.***.***' }
  it { should have_security_group('development_sg') }
  it { should belong_to_vpc('development') }
  it { should belong_to_subnet('public_subnet_1a') }
  it { should have_ebs('vol-****************') }
  it { should have_network_interface('eni-********') }
end

上記のように spec ファイル形式で表示してくれます。この出力結果をリダイレクトしてファイルとして保存してみます。

$ awspec generate ec2 vpc-fbcf759f > spec/ec2_spec.rb

先ほど作成した spec ファイル ( ec2_spec.rb ) の 1 行目に下記の記載を追加します。

require 'spec_helper'

最終的に作成した spec ファイルは下記のようになります。

require 'spec_helper'

describe ec2('centos7-dev') do
  it { should exist }
  it { should be_running }
  its(:instance_id) { should eq 'i-****************' }
  its(:image_id) { should eq 'ami-eec1c380' }
  its(:private_dns_name) { should eq 'ip-10-62-0-253.ap-northeast-1.compute.internal' }
  its(:public_dns_name) { should eq 'ec2-***-***-***-***.ap-northeast-1.compute.amazonaws.com' }
  its(:instance_type) { should eq 't2.medium' }
  its(:private_ip_address) { should eq '10.62.0.253' }
  its(:public_ip_address) { should eq '***.***.***.***' }
  it { should have_security_group('development_sg') }
  it { should belong_to_vpc('development') }
  it { should belong_to_subnet('public_subnet_1a') }
  it { should have_ebs('vol-****************') }
  it { should have_network_interface('eni-********') }
end

require 'spec_helper' の記述を追加し損ねると、後ほど実行します rake spec コマンドが失敗してしまいます。
私はこの記述をし忘れてよくハマります…

ちなみに、generate コマンドを利用して spec ファイルを作成できる AWS のリソースは下記のコマンドを実行することで確認できます。

$ awspec generate --help
Commands:
  awspec generate cloudwatch_alarm                    # Generate cloudwatch_alarm spec
  awspec generate cloudwatch_event                    # Generate cloudwatch_event spec
  awspec generate directconnect                       # Generate directconnect spec
  awspec generate ebs                                 # Generate attached ebs spec
  awspec generate ec2 [vpc_id]                        # Generate ec2 spec from VPC ID (or VPC "Name" tag)
  awspec generate efs                                 # Generate efs spec
  awspec generate elasticsearch                       # Generate elasticsearch spec
  awspec generate elb [vpc_id]                        # Generate elb spec from VPC ID (or VPC "Name" tag)
  awspec generate help [COMMAND]                      # Describe subcommands or one specific subcommand
  awspec generate iam_group                           # Generate iam_group spec
  awspec generate iam_policy                          # Generate attached iam_policy spec
  awspec generate iam_role                            # Generate iam_role spec
  awspec generate iam_user                            # Generate iam_user spec
  awspec generate kms                                 # Generate kms spec
  awspec generate lambda                              # Generate lambda spec
  awspec generate nat_gateway [vpc_id]                # Generate nat_gateway spec from VPC ID (or VPC "Name" tag)
  awspec generate network_acl [vpc_id]                # Generate network_acl spec from VPC ID (or VPC "Name" tag)
  awspec generate network_interface [vpc_id]          # Generate network_interface spec from VPC ID (or VPC "Name" tag)
  awspec generate rds [vpc_id]                        # Generate rds spec from VPC ID (or VPC "Name" tag)
  awspec generate route53_hosted_zone [example.com.]  # Generate route53_hosted_zone spec from Domain name
  awspec generate route_table [vpc_id]                # Generate route_table spec from VPC ID (or VPC "Name" tag)
  awspec generate s3_bucket [bucket_name]             # Generate s3_bucket spec from S3 bucket name. if NO args, Generate all.
  awspec generate security_group [vpc_id]             # Generate security_group spec from VPC ID (or VPC "Name" tag)
  awspec generate subnet [vpc_id]                     # Generate subnet spec from VPC ID (or VPC "Name" tag)
  awspec generate vpc [vpc_id]                        # Generate vpc spec from VPC ID (or VPC "Name" tag)
                   :

rake コマンドの実行

それでは、先ほど作成しました ec2_spec.rb をもとに、テストを実施してみましょう。

$ rake spec
<一部省略>

ec2 'centos7-dev'
  should exist
  should be running
  should have security group "development_sg"
  should belong to vpc "development"
  should belong to subnet "public_subnet_1a"
  should have ebs "vol-****************"
  should have network interface "eni-********"
  instance_id
    should eq "i-****************"
  image_id
    should eq "ami-eec1c380"
  private_dns_name
    should eq "ip-10-62-0-253.ap-northeast-1.compute.internal"
  public_dns_name
    should eq "ec2-***-***-***-***.ap-northeast-1.compute.amazonaws.com"
  instance_type
    should eq "t2.medium"
  private_ip_address
    should eq "10.62.0.253"
  public_ip_address
    should eq "***.***.***.***"

Finished in 0.36466 seconds (files took 1.49 seconds to load)
14 examples, 0 failures

14 の項目に関して test を実施して、全てパスしていることが確認できました。

最後に

generate コマンドを利用すれば、既存の AWS の状態を spec ファイルに簡単に落とし込めるので、テストのコードを簡単に作ることができます。必要なテスト項目だけを残して、別の AWS 環境のテストに使い回しが出来るため、すごく楽チンです。

実は、このブログを作成している時点では、awspec を実運用に組み込めていません…。
今後、別のツール等を組み合わせてまとまった形で本ブログで発信していこうと思っています。

本ブログの情報につきましては、自社の検証に基づいた結果からの情報提供であり、
品質保証を目的としたものではございません。

投稿者: 緒方 亮

主に Azure や AWS などの Public Cloud を担当しています。機械学習/深層学習で R を利用しているため、投稿する記事に R がよく登場します。