serverspecでZabbixサーバの稼働テストを書いてみた
先日http:/http://togetter.com/li/501076togetter.com/li/501076(5/10)開催されたProvisioning Frameworks Casual Talks vol.1に参加しました。
Provisioning Frameworks Casual Talks vol.1の中身は他の方がたくさんブログを書かれているのでそちらを参照して下さい。
Provisioning Frameworks Casual Talks vol.1 - Togetter
serverspecの話がたくさん出てきたので自分も試しにservespecを使ってテストコードを書いてみました。
ついでに、serverspecのver.0.3.0から利用できるようになったattributeの機能も使ってみました。
serverspecのattributeはこちらを参考にしました。
今回テストコードを書いたのは、Zabbixサーバが正しい状態で稼働しているかのテストです。
以下のようなテストを書いています。
Zabbixサーバのテスト
- 必要なパッケージがインストールされていること
- Zabbixプロセスが稼働していること
- Zabbixの初期起動設定がされていること
- Zabbixの起動ユーザが作成されていること
- Zabbixが正しいポートでリッスンしていること
- Zabbixの設定ファイル(zabbix_server.conf)に最低限の設定(DB設定が行われていること)
MySQLサーバのテスト
Apacheのテスト
実際に書いたテスト
実際に作成したファイルは次のようになります。
なお、今回は全て同じサーバ上で稼働している前提で以下のようにspecファイル類を作成しました。
$ serverspec-init Select a backend type: 1) SSH 2) Exec (local) 3) Puppet providers (local) Select number: 2
attributes.yml
(設定は環境に応じて書き換えて下さい)
zabbix_server: :listen_port: 10051 :user: zabbix :db_name: zabbix :db_user: zabbix :db_password: zabbixpassword :db_socket: /var/lib/mysql/mysql.sock mysql_server: :listen_port: 3306 :user: mysql :innodb_buffer_pool_size: 64M :innodb_log_file_size: 16M :innodb_log_files_in_group: 2 httpd: :listen_port: 80 :user: apache :max_execution_time: 300 :memory_limit: 128M :post_max_size: 16M :upload_max_filesize: 2M :max_input_time: 300 :timezone: Asia/Tokyo
Rakefile
(attributes.ymlから値を取得し、サービス毎にテストができるよう設定)
require 'rake' require 'rspec/core/rake_task' require 'yaml' attributes = YAML.load_file('attributes.yml') desc "Run serverspec to all services" task :serverspec => 'serverspec:all' namespace :serverspec do task :all => attributes.keys.map {|key| 'serverspec:' + key } attributes.keys.each do |key| desc "Run serverspec to #{key}" RSpec::Core::RakeTask.new(key.to_sym) do |t| ENV['TARGET_SERVICE'] = key t.pattern = "spec/*/#{key}_spec.rb" end end end
spec/spec_helper.rb
(attrubutes.ymlから値を取得し、各サービス毎に属性値を設定)
require 'serverspec' require 'pathname' require 'yaml' ### include requirements ### include Serverspec::Helper::Exec include Serverspec::Helper::DetectOS include Serverspec::Helper::Attributes attributes = YAML.load_file('attributes.yml') RSpec.configure do |c| if ENV['ASK_SUDO_PASSWORD'] require 'highline/import' c.sudo_password = ask("Enter sudo password: ") { |q| q.echo = false } else c.sudo_password = ENV['SUDO_PASSWORD'] end c.before :all do c.os = backend(Serverspec::Commands::Base).check_os end attr_set attributes[ENV['TARGET_SERVICE']] end
spec/localhost/zabbix_server_spec.rb
require 'spec_helper' describe 'zabbix-server' do it { should be_installed } it { should be_enabled } it { should be_running } end ### related package install check ### %w(zabbix-release zabbix-server-mysql zabbix-web-mysql zabbix-web zabbix-web-japanese zabbix zabbix-get).each do |pkg| describe pkg do it { should be_installed } end end describe attr[:user] do it { should be_user } end describe "port #{attr[:listen_port]}" do it { should be_listening } end describe '/etc/zabbix/zabbix_server.conf' do it { should be_file } it { should contain "DBName=#{attr[:db_name]}" } it { should contain "DBUser=#{attr[:db_user]}" } it { should contain "DBPassword=#{attr[:db_password]}" } it { should contain "DBSocket=#{attr[:db_socket]}" } end
spec/localhost/mysql_server_spec.rb
require 'spec_helper' describe 'mysql55-server' do it { should be_installed } end describe 'mysqld' do it { should be_enabled } it { should be_running } end describe attr[:user] do it { should be_user } end describe "port #{attr[:listen_port]}" do it { should be_listening } end describe '/etc/my.cnf' do it { should be_file } it { should contain "innodb_file_per_table" } it { should contain "innodb_buffer_pool_size=#{attr[:innodb_buffer_pool_size]}" } it { should contain "innodb_log_file_size=#{attr[:innodb_log_file_size]}" } it { should contain "innodb_log_files_in_group=#{attr[:innodb_log_files_in_group]}" } it { should contain "character-set-server=utf8" } end
require 'spec_helper' describe 'httpd' do it { should be_installed } it { should be_enabled } it { should be_running } end describe attr[:user] do it { should be_user } end describe "port #{attr[:listen_port]}" do it { should be_listening } end describe '/etc/httpd/conf.d/zabbix.conf' do it { should be_file } it { should contain "php_value max_execution_time #{attr[:max_execution_time]}" } it { should contain "php_value memory_limit #{attr[:memory_limit]}" } it { should contain "php_value post_max_size #{attr[:post_max_size]}" } it { should contain "php_value upload_max_filesize #{attr[:upload_max_filesize]}" } it { should contain "php_value date.timezone #{attr[:timezone]}" } end
実行するとこんな感じ
$ rake serverspec /usr/bin/ruby -S rspec spec/localhost/zabbix_server_spec.rb ................. Finished in 0.61575 seconds 17 examples, 0 failures /usr/bin/ruby -S rspec spec/localhost/mysql_server_spec.rb ........... Finished in 0.31917 seconds 11 examples, 0 failures /usr/bin/ruby -S rspec spec/localhost/httpd_spec.rb ........... Finished in 0.26358 seconds 11 examples, 0 failures
まだまだ勉強不足なため記述がこれで正しいのかは怪しいですが、非常に簡単にサーバの状態をテストできるので活用できそうです。
attributeの機能のおかげでテストコードの使い回しがとてもやりやすくなっているかと思います。