Serverspec で リモート サーバをテスト @ AWS EC2


Serverspecとは

O'REILLY『Serverspec』P.5 によると以下の目的に使うサーバテストツールです。

  1. テスト駆動によるインフラコード開発
  2. サーバ構築後の確認作業の自動化
  3. 稼働しているサーバの監視
  4. サーバの再起動後の状態確認
  5. サーバのあるべき状態の抽象化

Chef, Puppet, Ansibleと合わせて使うと、TDD(テスト駆動)なインフラコード開発が可能になります。
リモートマシンのテストは、SSH接続さえできれば可能です。テスト対象マシンは、rubyやServerspecのインストールは不要です。

対象読者

AWS EC2上でリモートサーバをServerspecでテストしてみたい初心者を対象としています。

Serverspecのインストール方法、ローカルでServerspecを実行してみる方法は、前回の記事を参照してください。
  ● Serverspec 最初の一歩 @ AWS EC2

環境の準備

■ EC2インスタンスの準備

  • EC2 Amazon Linuxインスタンス作成
    Amazon Linux のEC2インスタンスを2つ作成します。

    マシン名 IPアドレス 用途
    ec2_serverspec 172.31.24.21 Serverspecを実行するマシン
    ec2_client 172.31.21.132 テスト対象マシン

    Serverspecを実行するマシンは、前回の記事を参照してServerspecをセットアップしておきます。
      ● Serverspec 最初の一歩 @ AWS EC2
     

■ SSH接続の準備

  • OpenSSH形式のSSHプライベートキーを作成

    ec2_serverspec⇒ec2_clientにSSH接続できるようする準備をしていきます。
     

    PuTTYgenを使い、ec2_clientにPuTTYでアクセスするための*.ppk ファイル(PuTTY Private Key File)をOpenSSH形式に変換します。

    PuTTY Key Generator > Conversions > Import key > *.ppk ファイルを選択 > 開く(O) > Conversions > Export OpenSSH key > (パスワードなしでよいかの質問)はい(Y) > ファイル名(N): serverspec-key > 保存(S)
     

  • SSH接続設定

    ① Macならscpコマンド、WindowsならWinSCPを使い、/home/ec2_userにserverspec-keyファイルをアップロードします。
    ② serverspec-keyをrootの.ssh/に配置し権限を設定ます。

    [root@ip-172-31-24-21 ~]# mv /home/ec2-user/serverspec-key ./.ssh/
    [root@ip-172-31-24-21 ~]# chown root:root ./.ssh/serverspec-key
    [root@ip-172-31-24-21 ~]# chmod 600 ./.ssh/serverspec-key
    

    ③ SSHのconfigファイルを作成します。

    [root@ip-172-31-24-21 ~]# vi  ./.ssh/config
    

    configファイル

    ~/.ssh/config
    Host ec2_client
      HostName 172.31.21.132
      Port 22
      User ec2-user
      IdentityFile ~/.ssh/serverspec-key
    

    ④ SSHの通信チェックを行います。
     初回は問い合わせがありyesを選択します。2回目以降はそのまま接続できます。

    [root@ip-172-31-24-21 ~]# ssh ec2_client
    The authenticity of host '172.31.21.132 (172.31.21.132)' can't be established.
    ECDSA key fingerprint is 51:68:55:50:15:8f:5e:9b:dc:0f:47:69:8b:65:d1:98.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '172.31.21.132' (ECDSA) to the list of known hosts.
    Last login: Sat Jun 18 06:33:08 2016 from 52.68.185.60
    
           __|  __|_  )
           _|  (     /   Amazon Linux AMI
          ___|\___|___|
    
    https://aws.amazon.com/amazon-linux-ami/2016.03-release-notes/
    [ec2-user@ip-172-31-21-132 ~]$ exit
    logout
    Connection to 172.31.21.132 closed.
    [root@ip-172-31-24-21 ~]# ssh ec2_client
    Last login: Sat Jun 18 07:08:23 2016 from ip-172-31-24-21.ap-northeast-1.compute.internal
    
           __|  __|_  )
           _|  (     /   Amazon Linux AMI
          ___|\___|___|
    
    https://aws.amazon.com/amazon-linux-ami/2016.03-release-notes/
    [ec2-user@ip-172-31-21-132 ~]$ 
    

テストの準備

  • Serverspecファイルを作成
    serverspec-init コマンドを実行します。

    [root@ip-172-31-24-21 ~]# mkdir serverspec
    [root@ip-172-31-24-21 ~]# cd serverspec/
    [root@ip-172-31-24-21 serverspec]# serverspec-init
    Select OS type:
    
      1) UN*X
      2) Windows
    
    Select number: 1
    
    Select a backend type:
    
      1) SSH
      2) Exec (local)
    
    Select number: 1
    
    Vagrant instance y/n: n
    Input target host name: ec2_client
     + spec/
     + spec/ec2_client/
     + spec/ec2_client/sample_spec.rb
     + spec/spec_helper.rb
     + Rakefile
     + .rspec
    

テストの実行

rake spec コマンドを実行します。

  • 失敗テスト
    ec2_clientの80番ポートを閉じている状態でテストを実行してみます。

    spec/ec2_client/sample_spec.rb
    describe port(80) do
      it { should be_listening }
    end
    
    [root@ip-172-31-24-21 ~]# cd serverspec/
    [root@ip-172-31-24-21 serverspec]# rspec spec
    /usr/bin/ruby2.0 -I/usr/local/share/ruby/gems/2.0/gems/rspec-support-3.4.1/lib:/usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/lib /usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/exe/rspec --pattern spec/ec2_client/\*_spec.rb
    
    Port "80"
      should be listening (FAILED - 1)
    
    Failures:
    
      1) Port "80" should be listening
         On host `ec2_client'
         Failure/Error: it { should be_listening }
           expected Port "80" to be listening
           sudo -p 'Password: ' /bin/sh -c netstat\ -tunl\ \|\ grep\ --\ :80\\\
    
         # ./spec/ec2_client/sample_spec.rb:27:in `block (2 levels) in <top (required)>'
    
    Finished in 0.0415 seconds (files took 0.54213 seconds to load)
    1 example, 1 failure
    
    Failed examples:
    
    rspec ./spec/ec2_client/sample_spec.rb:27 # Port "80" should be listening
    
    /usr/bin/ruby2.0 -I/usr/local/share/ruby/gems/2.0/gems/rspec-support-3.4.1/lib:/usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/lib /usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/exe/rspec --pattern spec/ec2_client/\*_spec.rb failed
    

    無事に失敗を検出しました。
     

  • 成功テスト
    それでは、スペックファイル(spec/ec2_client/sample_spec.rb)を編集し、テストを成功させてみましょう。最後の3行を次のように変更します。

    sample_spec.rb
    describe port(22) do
      it { should be_listening }
    end
    
    describe service('ntpd') do
      it { should be_enabled }
      it { should be_running }
    end
    

    EC2のAmazon Linuxは、インスタンス生成直後は、以下の状態にあります。

    • 22番ポートが開いている
    • 「ntpd」サービスが利用可能
    • 「ntpd」サービスが稼働している

    この状態でテストを実行(rake spec)すると、3つのテストが成功します。

    [root@ip-172-31-24-21 serverspec]# rake spec
    /usr/bin/ruby2.0 -I/usr/local/share/ruby/gems/2.0/gems/rspec-support-3.4.1/lib:/usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/lib /usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/exe/rspec --pattern spec/ec2_client/\*_spec.rb
    
    Port "22"
      should be listening
    
    Service "ntpd"
      should be enabled
      should be running
    
    Finished in 0.07869 seconds (files took 0.54404 seconds to load)
    3 examples, 0 failures
    
    

セキュリティ設定のテスト

  • sshのテストを追加

    テストのサンプルとして、セキュリティの設定をテストを追加してみます。
    ec2_serverspecサーバーにログインし、serverspecディレクトリに移動します。

    login as: ec2-user
    Authenticating with public key "imported-openssh-key" from agent
    Last login: Sat Jun 18 08:55:43 2016 from dcm1-133-204-45-4.tky.mesh.ad.jp
    
           __|  __|_  )
           _|  (     /   Amazon Linux AMI
          ___|\___|___|
    
    https://aws.amazon.com/amazon-linux-ami/2016.03-release-notes/
    [ec2-user@ip-172-31-24-21 ~]$ sudo su -
    Last login: Sat Jun 18 08:56:49 UTC 2016 on pts/3
    [root@ip-172-31-24-21 ~]# cd serverspec/
    

     

  • スペック ファイル作成

    ec2_clientサーバーのテスト項目をssh_spec.rbに定義します。
    設定ファイルの変更し忘れチェックは活用したいですね。

    spec/ec2_client/ssh_spec.rb
    describe package('openssh-server') do
      it { should be_installed }
    end
    
    describe service('sshd') do
      it { should be_enabled }
      it { should be_running }
    end
    
    describe file('/etc/ssh/sshd_config') do
      its(:content) { should match /^#Port 22/ }
      its(:content) { should_not match /^PasswordAuthentication yes/ }
    

     

  • テスト実行
    テストを実行(rake spec)すると、specディレクトリの*_spec.rbにマッチするスペックファイルがすべて実行されます。
    ここでは、もともとあった3つのテストに加えてsshの5つのテストが成功します。

    client/ssh_spec.rb
    [root@ip-172-31-24-21 serverspec]# rake spec
    /usr/bin/ruby2.0 -I/usr/local/share/ruby/gems/2.0/gems/rspec-support-3.4.1/lib:/usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/lib /usr/local/share/ruby/gems/2.0/gems/rspec-core-3.4.4/exe/rspec --pattern spec/ec2_client/\*_spec.rb
    
    Port "22"
      should be listening
    
    Service "ntpd"
      should be enabled
      should be running
    
    Package "openssh-server"
      should be installed
    
    Service "sshd"
      should be enabled
      should be running
    
    File "/etc/ssh/sshd_config"
      content
        should match /^#Port 22/
      content
        should not match /^PasswordAuthentication yes/
    
    Finished in 0.1879 seconds (files took 0.55769 seconds to load)
    8 examples, 0 failures
    

Nextステップ

次は、Serverspecで複数のサーバのテストを行います。
 ・Serverspec で複数のサーバをテスト @ AWS EC2