こんにちは、貴子です。
インフラチームでchefのテストを導入して、運用フローまで落とせてきたので
何が問題でどう改善したかをまとめました。
テストを導入する前の問題点
テストを始める前のrecipeにはたくさんの問題がありました。
* bash・executeを多様している
* ダブルコーテーションとシングルコーテーションの使い分けができていない
* recipe通りに動いているか確認が漏れがある
* CentOSだと動くけれどAmazon linuxだと動かない
..etc
これらの問題は2つに分類することが出来ました。
1. コードの書き方に統一されていない
2. 動作チェックが甘い
改善へ
1.コーディングスタイルを統一させる
Foodcritic・ Rubocopを利用して構文チェックをするようになりました。
Foodcritic (http://acrmp.github.io/foodcritic/) はchefの構文のチェックをしてくれるツールです。
実際に使用してみます。
(1). まずはchef-repositoryにテストに必要なもののGemfileを作成します
vim Gemfile # Gemfile source 'https://rubygems.org' gem 'test-kitchen' gem 'kitchen-ec2' gem 'kitchen-vagrant' gem 'serverspec' gem 'foodcritic' gem 'rubocop'
(2). vendor/bundle配下にgemインストールします
bundle install --path vendor/bundle
(3). stashへvendor/bundle配下のものはプッシュしたくないので、無視をするように.gitignoreに記述をします。
vim .gitignore # .gitignore vendor/bundle
準備ができたので、Foodcriticを実行します
bundle exec foodcritic .
エラーが出ました。
指摘部分を確認します。
directory "/etc/skel/Maildir/new" do mode '0700' recursive true end directory "/etc/skel/Maildir/cur" do mode '0700' recursive true end directory "/etc/skel/Maildir/tmp" do mode '0700' recursive true end
FC005のエラーと照らし合わせると、配列を使わずディレクトリを作成していたことが原因でした。
#修正後のコード %w(new cur tmp).each do |dir| directory "/etc/skel/Maildir/#{dir}" do mode '0700' recursive true end end
指摘通りに書きなおして再度foodcriticをかけるとエラーはでなくなりました。
次はRubocop実行してrubyの構文チェックをします。
bundle exec rubocop recipes
Criticalを示すCがでて42行目に空白があるのがよくないよーと言われました。
確認すると確かに最終行に無駄な改行が入っています。
削除して再度実行すると通りました。
rubocopはそれぐらい良えやんと言いたくなるところまで、ビシッと指摘してくれるとても良い子です。
きっと、それぐらい良えやんという怠惰が醜いコードを生むのです。
2. 動作チェックのテスト自動化
serverspecでテストを書いて、test-Kitchenで実行して動作保証をします。
serverspec ( http://serverspec.org/ )とは、サーバの状態をテストするためのフレームワークです。
まずは、テストファイルを置くdirectoryを作成します。
mkdir -p test/integration/default/serverspec/
テストを書きます。
基本的にはrecipeに書いたことを、そのままテストをします。
上のrecipeではdirectoryを作成して権限を変更したので、
ディレクトリが作成されていて、権限が0700になっていることを確認します。
vim test/integration/default/serverspec/default_spec.rb # new cur tmpのdirectory作成確認と権限確認 %w(new cur tmp).each do |dir| describe file("/etc/skel/Maildir/#{dir}") do it { should be_directory } it { should be_mode 700 } end end
test-Kitchenの実行環境を整えます。
test-Kitchen ( http://kitchen.ci/ )とはクラウド上にテスト用のInstanceを立てて、recipe ~ testまで実行して確認できるツールです。
kitchen init
kitchen.ymlを書き換えます。 (※kitchen.ymlは自分の環境に合わせて書き換えてください。)
vim .kitchen.yml # .kitchen.yml driver: name: ec2 availability_zone: b aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> aws_ssh_key_id: '秘密鍵名' instance_type: 't2.small' security_group_ids: ['*subnet_id'] image_id: 'ami-cbf90ecb' region: <%= ENV['AWS_REGION'] %> subnet_id: 'subnet_id' associate_public_ip: true interface: private user_data: "#!/bin/bash\necho 'Defaults !requiretty' >> /etc/sudoers.d/cloud-init" transport: ssh_key: 秘密鍵名 connection_timeout: 10 connection_retries: 5 username: ec2-user provisioner: name: chef_solo platforms: - name: amazonlinux suites: - name: defaults run_list: - recipe[base::default] attributes:
test-Kitchenを実行します。
# テストサーバー構築 bundle exec kitchen create # recipe実行 bundle exec kitchen converge # テスト(serverspec)実行 bundle exec kitchen verify # テストサーバー削除 bundle exec kitchen destroy
kitchen verify を叩いて上手くいったら、テスト完了なのでテストサーバーを潰します。
これで「コードの書き方に統一されていない・動作チェックが甘い 」という問題点を解決できました。
継続的に続けていくために、運用フローに落とします。
改善後の運用フロー
これで動作保証がされた品質の良いrecipeを書いていくことができます。
慣れるまでとても大変でしたが、一度身につけてしまえば、とても楽しくテスト実行までをやれるようになりました。
しかし、やはり好き勝手に書いて提供していた時の方がスピードは早く、
今後はいかに早く品質が良い物を提供していけるかに取り組んでいきたいです。
そもそもテストを一回で通れば時間はかなり節約できると思うので、
綺麗なrecipeがかけるエンジニアになれるよう精進します。