🤖

CircleCI+Ansible+ServerspecでServerspecポートテストがエラー

2023/11/16に公開
3

「Ansible から Serverspec テストを実行したとき、ローカルでは成功するが CircleCI から起動すると失敗する」という謎事象について調査したので解決策(ワークアラウンド)と合わせてメモを残します。

きっかけ

  • とあるスクールでメンターをやっており、その受講生から上記の問い合わせを受けた
  • テストコードを確認したが異常はなく、申告された事象はこちらの環境でも再現した

現象詳細

  • CircleCI で Ansible に記述した Serverspec テストを実行すると、describe portが成功しない
  • ローカルで実行した場合、テストは正常に動作する
  • 以下がそのテストコード
spec/before.rb
require 'spec_helper'

listen_port = 8080

describe package('nginx') do
  it { should be_installed }
end

describe port(listen_port) do
  it { should be_listening }
end

describe command('curl http://127.0.0.1:#{listen_port}/_plugin/head/ -o /dev/null -w "%{http_code}\n" -s') do
  its(:stdout) { should match /^200$/ }
end

原因

  • 調査の結果、describe portが呼び出すss -tunlコマンドは、SSH 経由で実行されたときに使えなくなることが判明
    • SSH 経由でコマンドを発行するとssの所在地/usr/sbin/$PATHに含まれない(環境変数を読まない仕様)ため
  • どうやらJenkns でも起きていたらしい

対処

  • 結論、何をどうやってても Ansible を経由させるとdescribe portが失敗するようでした
  • Serverspec には$PATHの指定やpre_commandなる機能があるのですが、これらを使っても解決できませんでした
  • そこで Ansible を経由することを諦め、CircleCI から直接 Serverspec を実行することにしました
  • テストコード自体に変更はありません

まとめ

  • Serverspec のテストは Ansible や Jenkins を経由させると失敗する可能性がある
  • ポートテスト以外にも怪しい挙動があれば、CircleCI から直接 Serverspec を実行することを検討すると良いかもしれません

Discussion

Gosuke MiyashitaGosuke Miyashita

spec_helper.rbあたりに

set :path, '/usr/sbin:$PATH'

と書いてもダメですかね?

Masatoshi MizumotoMasatoshi Mizumoto

コメントありがとうございます!
これも試した記憶はあるのですが、解決には至らなかったです🤔
テスト結果の文字色も正しく反映されていないなど他にも好ましくないことがありましたので、相談者にはCircleCIから実施してもらうようにお願いしました。

Gosuke MiyashitaGosuke Miyashita

なるほど、そうなんですね。

機能的には設定できるのと、自分の手元の環境では正常に動作しているので、何か環境固有の問題がありそうですね。