CI/CD環境を作った時に起きたエラー備忘録[Rails + CircleCI +Capistrano +AWS]

#はじめに
作成途中のrailsアプリに自動デプロイ(AWSのEC2へ)は実装できたので、テストも自動化してCircle CIからデプロイまでして欲しいと思ったので(CI/CD環境)実装した。

実装自体は先人方の記事を参考にしてできた。
[【circleCI】rails5.2/Capistrano/CICD環境によるAWSへの自動デプロイ](https://qiita.com/AK4747471/items/882b70f663f4a80ae770)

[CircleCI + Capistrano + AWS(EC2) + Railsで自動デプロイしてみた](https://qiita.com/YK0214/items/98bbdf7ce25c557c77a3)

上記の記事の方ではコードも含めて十分な説明がされているので、ここでは個人的にハマったエラーについて備忘録を残しておく。

#環境
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に追加する。

```: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
[公式リファレンス](https://circleci.com/docs/2.0/collect-test-data/#enabling-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接続する方法](https://qiita.com/yu-croco/items/41d2114c94e3a6ea748a))



build画面でRerunのトグルを押すと下の写真の様に出てくるので「Rerun Job with SSH」を押す。
<img width="200px" alt="Screen Shot 2020-11-07 at 15.19.48.png"  src ="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736014/a7c94ad2-190f-45e2-b936-0d216a102d02.png">

すると、公開鍵が渡されるのでこれでターミナルからssh接続。

![Screen Shot 2020-11-07 at 15.30.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736014/c90e4aa4-46f7-e8bf-3199-07441f6c8847.png)


```
#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側の指定を確認する。

```:deploy.rb
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でデプロイの際に使う鍵の指定を間違えている**　が原因だった。


```:deploy.rb
#変更前
set :ssh_options, auth_methods: ['publickey'],keys:['~/.ssh/id_rsa'] 

#変更後(fingerprintは「:」を抜いたもの)
set :ssh_options, auth_methods: ['publickey'],keys:['~/.ssh/id_rsa_×××××××××']          
```

これで無事buildが成功してデプロイ完了。

![Screen Shot 2020-11-07 at 16.04.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736014/d4016699-6e55-52cf-00cc-c3025aa92e4d.png)



#後書き
fingerprintや公開鍵周りなどセキュリティ関係のことになるとまだごちゃごちゃしがち。デプロイ後にslack通知なんかもできるらしいのでやってみようかなと思う。