Travis-CIの自動デプロイでSSHを実行する方法 [翻訳]

> How to Encrypt/Decrypt SSH Keys for Deployment

正しくは、”Travis-CIのデプロイ時に使うSSHキーを暗号化/復号化する方法”です。
Travis-CIでテストをパスしたとき、デプロイとしてSSHでサーバに接続してスクリプトを叩くとか、そんな時に必要なものです。

以下 <https://github.com/dwyl/learn-travis/blob/master/encrypted-ssh-keys-deployment.md> の翻訳です。

# Travis-CIのデプロイ時に使うSSHキーを暗号化/復号化する方法

暗号化された SSHキーをプロジェクトに追加して、Travis-CIがアプリを自動的にデプロイできるようにします。

## なぜ？

CIは、プロジェクト/アプリケーションの最新バージョンを特定の環境に展開するプロセスを完全に自動化します。これにより、新しい機能またはバグ修正をデプロイする必要があるたびに手動で実行するステップがないため、チームの時間を大幅に節約でき、特定のインスタンスにどのバージョンが存在するかについての混乱を回避できます。

多くの人は、SSHベースの展開ツール（[Edeliver](https://github.com/edeliver/edeliver)など ）を使用することを好みます。これは、シンプルで高速で、暗号化されたSSH "トンネル"で保護されているためです。

## これは何?

Travis-CIであなたのアプリを１つ（あるいは複数）のサーバにSSH経由でデプロイする、”デプロイメント・パイプライン”、をセットアップする為の、セキュアな方法です。

## 安全ですか？

SSHキーは作成および暗号化され、プレーンテキストで送信されること はありません。Travis-CIのみがキーを復号化できます。

注：有料版のTravis-CIを使用している場合、Web-UIを使用してSSHキーを追加できます。
参照： <https://docs.travis-ci.com/user/private-dependencies>
via： <https://stackoverflow.com/questions/27444891/how-to-add-ssh-key-in-travis-ci>

## 対象

* Herokuを使っている人で、なおかつ[簡単な方法](https://1000ch.net/posts/2016/heroku-automatic-deploy.html)が許されない人
* デプロイ/プラットフォームを "full control" したい人
* 「DevOps」に興味がある熱心なEager-beavers


## どうやって?

### Step 0. 前提条件

このガイドは、AWS、Google Cloud、Digital Ocean、LinodeなどのクラウドサービスにLinux「仮想プライベートサーバー」（VPS）インスタンスが既にあることを前提としています。
※[翻訳者追記] 自前のサーバでも問題なし

以下に説明では、インスタンス（VPS）へのSSHアクセスとIPアドレスのメモが必要になります。
このチュートリアルでは、DigitalOceanで実行されているCentOSインスタンスを使用していますが、AWS、Azure、およびLinodeの両方で実行されているUbuntuインスタンスでもテストしました。

> デジタルオーシャンアカウントをまだお持ちでない場合は、次の（「紹介」）リンクを使用して登録してください： <https://m.do.co/c/29379863a4f8> クレジット$10がもらえます。

他に必要とする知識はありません。すべてのコマンドは説明しました。しかしもし不明確なものがあれば、いつもの通り、私達は”ここにいるし喜んで助けましょう”; ここでissueを開いてください。: <https://github.com/dwyl/learn-travis/issues>

### Step 1. サーバーインスタンスへのログイン

IPアドレスを使用してSSH経由でサーバーインスタンスにログインします。

例えば：

```bash
ssh root@138.68.163.126
```

端末プロンプトが変化するのが確認できるはずです。
![40557858-68a7f3ea-6049-11e8-8bc6-24bdf52c7300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488658/514bec29-35ca-ae81-9699-4f30f4f50b52.png)

### Step 2. 新しいSSH Keyを生成する

カレントディレクトリを`.ssh`へ変更して次のコマンドを実行します。

```bash
cd ~/.ssh
ssh-keygen -t rsa -b 4096 -C "TravisCIDeployKey"
```
※[翻訳者追記] `-b`ばビット長、`-C`はコメントオプション

[Enter]キーを押して、ファイル名のデフォルトを使用し、password 空白のままにします。
次のような出力が端末に表示されます。
![40580695-b5550956-613b-11e8-936c-9ba091b3c1ba.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488658/f8db3c05-2393-c853-a203-702101442656.png)

#### 2.1 生成したSSHキーを`authorized_keys`ファイルへ追加

新しいキーをSSHアクセスに使用するにためには、サーバー上の`authorized_keys`ファイルにそれを含める必要があります。
次のコマンドを実行して、公開鍵を"authorized keys"のリストに追加します。

```bash
cat id_rsa.pub >> authorized_keys
```
これをStep 3.1でテストします。

### Step 3. SSHキーを安全にダウンロードする

現在の作業ディレクトリが、SSHキーを追加するプロジェクト/アプリであることを確認します。（したがって、後でキーを移動する必要はありません）

SSHキーをダウンロードする前に、まず`.gitignore`に次の行を追加して、秘密鍵を誤って平文でコミットしないようにします。

```bash
echo  " deploy_key "  >> .gitignore
```

それが完了したら、次のコマンドでキーをダウンロードします。

```
scp user@ip.add.ress.here：/root/.ssh/id_rsa ./deploy_key
```

例えば：

```bash
scp root@138.68.163.126：/root/.ssh/id_rsa ./deploy_key
```

![40564862-4ac51e98-6062-11e8-8ac0-a6c0fab92902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488658/04bbe887-4e5a-0952-6928-e9c39bd2f101.png)

#### 3.1 サーバーにログインできることをテストする

`deploy_key`を使ってサーバにログインできることをテストします。

```
ssh -i /path/to/deploy_key user@ip.add.ress.here
```

例えば：

```bash
ssh -i ./deploy_key root@138.68.163.126
```

### Step 4. Travis-CI CLIをインストールする

SSHキーとパスフレーズの両方を暗号化するには、Travis-CI CLIが必要です。
localhost （サーバではなく）にTravis-CIをインストールします：

```bash
gem install travis
```

もしgemが入っていなかったら、まずは`ruby`をインストールしてやり直してください。

### Step 5. 秘密鍵を暗号化する

`travis`のCLIを使用して、localhostで秘密鍵を暗号化します。

```bash
touch .travis.yml && travis encrypt-file ./deploy_key --add
```

次のようなものが表示されるはずです。
![40564928-8b1209f2-6062-11e8-83a1-2a0df73fe519.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488658/f28bf40a-d94d-0049-efb5-55eb1d6615dc.png)

プロジェクトディレクトリの`.travis.yml`を見ると、次の行が追加されているのを確認できるはずです。

```
before_install:
- openssl aes-256-cbc -K $encrypted_77965d5bdd4d_key -iv $encrypted_77965d5bdd4d_iv
  -in deploy_key.enc -out ./deploy_key -d
```

GitHubにpushする前に、`deploy_key.enc`と`.travis.yml`をあなたのプロジェクトにコミットしたことを確認してください。

>注：これを行う別の方法があります。暗号化したSSHキーをbase64にエンコードして`.travis.yml`に含める方法です。：<https://gist.github.com/lukewpatterson/4242707>を参照してください。 ただし`.travis.yml`にノイズを含むことになります。どちらの方法がいいか、あなたが好むものを自分で決めて構いませんが、プロジェクト全体で一貫性を保つべきです。

#### 5.1 RSAキーを`preferred key`として`.travis.yml`に設定する

Step 5では、暗号化したRSAキーをリポジトリに追加しましたが、これをまた、Travis-CIに`preferred key`として設定する必要があります。
次を`.travis.yml`に加えてください。

```
- ssh-add ./deploy_key
```

この行は、キー復号化の行の後にあることを確認してください。例：<https://github.com/nelsonic/hello-world-node-http-server/blob/master/.travis.yml#L13>


### Step 6. Travis-CIでテストする

論より証拠で確認してみます。Travis-CIはあなたのサーバインスタンスでSSHコマンドを実行できるはずです。

次を`.travis.yml`に追加します。

```bash
- eval "$(ssh-agent -s)"
- chmod 600 ./deploy_key
- echo -e "Host $SERVER_IP_ADDRESS\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- ssh-add ./deploy_key
- ssh -i ./deploy_key root@138.68.163.126 pwd
```

これらの行を見ていきましょう。

* eval "$(ssh-agent -s)" = `ssh-agent`をスタートします (sshコマンドを実行できるように)
* chmod 600 ./deploy_key = warningを避けるため、権限を変更します.
* echo -e "Host $SERVER_IP_ADDRESS\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config = Travisがホスト（VPS）のIDをチェックするかどうかを尋ねるのを避けます。: <https://stackoverflow.com/questions/16638573/auto-authorize-ssh-auth-requests-on-travis-ci>
* ssh-add ./deploy_key = `deploy_key`をsshの優先RSAキーとして設定します。
* ssh -i ./deploy_key root@138.68.163.126 pwd = `deploy_key`を”identity”ファイル（RSAキー）として使用して、サーバーでpwdコマンドを実行します

sshコマンドがTravis-CI上で動くと、次のような出力を確認できるはずです。: <https://travis-ci.org/nelsonic/hello-world-node-http-server/builds/385702903#L457>
![40725130-8a4134f6-641a-11e8-86b8-c948b5b0d0dc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488658/764719ff-46bb-5a16-5a82-45a40662ebd1.png)

[.travis.ymlの完全な例](https://github.com/nelsonic/hello-world-node-http-server/blob/master/.travis.yml#L7-L16)


## 背景/関連資料
* 展開キーの管理（SSH展開の場合）：<https://developer.github.com/v3/guides/managing-deploy-keys>
* 新しいSSHキーの生成：<https://help.github.com/articles/generated-a-new-ssh-key-and-adding-it-to-the-ssh-agent/>
* SSHはTravis CIでデプロイします：<https://oncletom.io/2016/travis-ssh-deploy/>
* <https://www.rusiczki.net/2018/01/25/use-travis-to-build-and-deploy-your-jekyll-site-through-ssh/>
* <http://anil.recoil.org/2013/10/06/travis-secure-ssh-integration.html>
* Travisを使用してビルドされた製品をghページに自動展開する：<https://gist.github.com/domenic/ec8b0fc8ab45f39403dd>