#はじめに
作成途中のrailsアプリに自動デプロイ(AWSのEC2へ)は実装できたので、テストも自動化してCircle CIからデプロイまでして欲しいと思ったので(CI/CD環境)実装した。
実装自体は先人方の記事を参考にしてできた。
【circleCI】rails5.2/Capistrano/CICD環境によるAWSへの自動デプロイ
CircleCI + Capistrano + AWS(EC2) + Railsで自動デプロイしてみた
上記の記事の方ではコードも含めて十分な説明がされているので、ここでは個人的にハマったエラーについて備忘録を残しておく。
#環境
CircleCI 2.0
Capistrano 3.14.1
Ruby 2.6.5
Rails 6.0.0
#① rspec_junit_formatterがないと言われる
テストを走らせた時に出たエラー
Error reading historical timing data: file does not exist
Requested weighting by historical based timing, but they are not present. Falling back to weighting by name.
No examples found.
bundler: failed to load command: rspec (/home/circleci/circleci-demo-ruby-rails/vendor/bundle/ruby/2.5.0/bin/rspec)
LoadError: cannot load such file -- rspec_junit_formatter
結論としてはrspec_junit_formatterをgemfileに追加する。
group :test do
gem 'rspec_junit_formatter' # 追加
end
公式によると、
Test metadata is not automatically collected in CircleCI 2.0 until you enable the JUnit formatters. For RSpec, Minitest, and Django, add the following configuration to enable the formatters
公式リファレンス
どうもCircleCIはテスト結果をXMLファイルから集めるらしい。しかし自動的に集めてくれるわけではなく、このJUnit formattersを入れておくことで自動的に吸い取ってくれる仕組みらしい。
#② デプロイ時にec2へsshログインができない。
bundle exec cap production deployを実行した時のエラー
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@××××××××××: Authentication failed for user ec2-user@××××××××××
Caused by:
Net::SSH::AuthenticationFailed: Authentication failed for user ec2-user@××××××××××
挙げてみた可能性は2つ
1. Circle CI に設定したsshキーが間違えている
2. Capistranoでデプロイの際に使う鍵の指定を間違えている
1を確かめるために、CircleCIにsshで接続してコンテナ内からEC2にログインできるかどうか試してみる。(こちらを参考にした。Circle CIのテスト環境へSSH接続する方法)
build画面でRerunのトグルを押すと下の写真の様に出てくるので「Rerun Job with SSH」を押す。
すると、公開鍵が渡されるのでこれでターミナルからssh接続。
#circle ciにssh接続ok
circleci@××××××××××:~$
#ec2にssh接続
circleci@××××××××××:~$ ssh -i <keypair> ec2-user@<IP address>
#ec2にcircle ciで設定した鍵でssh接続ok
[ec2-user@ip-×××××××××× ~]$
ec2に接続できたということは少なくとも設定した鍵自体は間違いなさそうなので、とりあえず1の「Circle CI に設定したsshキーが間違えている」は大丈夫そう。
続いて2のCapistranoでデプロイの際に使う鍵の指定を間違えている を確かめる。まずは
Capistrano側の指定を確認する。
set :ssh_options, auth_methods: ['publickey'],keys:['~/.ssh/id_rsa']
次に、Circle CIで設定したsshキーがどのような名前で保存されているかを確認する。
#circle ciにssh接続
circleci@××××××××××:~$ cd .ssh
circleci@××××××××××:~/.ssh$ ls
config id_rsa id_rsa_×××××××××× known_hosts
# 上の(id_rsa_××××××××××)がcirleciの設定で追加したもの
どうも登録したsshキーはfingerprintを付け加えたものを指定するらしい。結局2のCapistranoでデプロイの際に使う鍵の指定を間違えている が原因だった。
#変更前
set :ssh_options, auth_methods: ['publickey'],keys:['~/.ssh/id_rsa']
#変更後(fingerprintは「:」を抜いたもの)
set :ssh_options, auth_methods: ['publickey'],keys:['~/.ssh/id_rsa_×××××××××']
これで無事buildが成功してデプロイ完了。
#後書き
fingerprintや公開鍵周りなどセキュリティ関係のことになるとまだごちゃごちゃしがち。デプロイ後にslack通知なんかもできるらしいのでやってみようかなと思う。