SpringBootアプリケーションをCodePipelineを用いてEC2インスタンスに自動デプロイ

SpringBootで構築したアプリケーションをAWS CodePipelineを用いてEC2インスタンスに自動デプロイするための手順をまとめます。
# 構成
![Codepipeline.png](https://qiita-image-store.s3.amazonaws.com/0/61103/fb757883-1efa-b2db-82be-a3948829f600.png)

- Gitリポジトリ
    - GitHub(なんでも良い)
- CI
    - Jenkins
- Test & Build
    - Maven(Gradleでもそんなに変わらない)
- APサーバ
    - SpringBoot 1.4.x on EC2

# 大まかな流れ
基本的に以下で紹介していただいた内容をもとに実施した。
[SpringBootで構築したアプリケーションがgitにpushされたらCodeDeployで自動デプロイされる仕組み](https://qiita.com/ryosukehayashi/items/6a419ab73a98ce8e8217)

開発者
1. 任意の(ここでは例としてmaster) branchにpush

Jenkins
1. 5分毎にポーリングし、develop branchが更新されていればpull
2. Test & Build(Maven)
3. Test & Buildが成功したらS3にリビジョンをアップロード

CodePipeline
1. S3からアップロードされたファイルを取得
2. CodeDeployを起動

CodeDeploy
1. jarファイルに実行権限を付与
2. CodeDeployから各インスタンスにSpringBootアプリがdeployされ、新しいバージョンのアプリが起動する。


## サンプルコード
[CodeDeployを利用した自動デプロイを行ったサンプルコード(GitHub)](https://github.com/tatsuakimitani/springboot-demo)

# 追加で実施した作業

以下は、更新した箇所のみ記載。
## AWS EC2インスタンスのJavaバージョンを1.8にする。
AWS EC2インスタンスのJavaバージョンがOpenJDK1.7だった。
Oracle JDK1.8をインストールすることを前提としているため、JDKのアップデートを行う。
参照：[Amazon Linuxにjdk1.7 or 1.8インストール](https://qiita.com/watanata/items/54d194741f73f92b0efc)

## SpringBootアプリケーションのサービス化
以下のページを参考にSpringBootアプリケーションのサービス化を行う。
[Spring Bootでwarファイル作成＆jarのサービス化](https://qiita.com/Tsuji_Taku50/items/c61d732fd4d4118bcdf7#_reference-40c2f8764cfc185e7d51)

- デプロイするjarファイル名：demo.jar
- 起動するサービス名：demo

## CodeDeploy
- アプリケーション名：springboot-demo
- アプリケーショングループ名：springboot-demo-group

appspec.ymlは今回の構成は以下のようにした。

```appspec.yml
version: 0.0
os: linux
files:
  - source: demo.jar
    destination: /var/myapp/
    overwrite: yes
hooks:
  ApplicationStop:
    - location: scripts/appstop.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/appstart.sh
      timeout: 300
      runas: root
```
また、サービス停止・起動用スクリプトは以下のようにした。

サービス停止用スクリプト

```scripts/appstop.sh
#!/bin/sh
service demo stop
```

サービス起動用スクリプト

```scripts/appstart.sh
#!/bin/sh
chmod u+x /var/myapp/demo.jar # jarファイルに実行権限を付与
service demo start
```

## AWS CodePipeline
CodePipelineの設定を行う。
1.パイプライン名の登録

- パイプライン名：demo-pipeline

  ![Codepipeline-setting1.png](https://qiita-image-store.s3.amazonaws.com/0/61103/4699f989-90a0-f722-ec0f-ccbc19cab0f4.png)

2.ソース取得場所設定
  ![Codepipeline-setting2.png](https://qiita-image-store.s3.amazonaws.com/0/61103/30cc3785-ffb4-9224-b98e-ea756e76ad13.png)

3.ビルド設定
Jenkinsでビルド済みなので、ビルド設定はなし。
![Codepipeline-setting3.png](https://qiita-image-store.s3.amazonaws.com/0/61103/e21f310a-ce4d-d501-2b50-652d535763eb.png)

4.デプロイ設定
上記、CodeDeployで設定したアプリケーション名およびアプリケーショングループ名を選択
![Codepipeline-setting4.png](https://qiita-image-store.s3.amazonaws.com/0/61103/d1f5fdcf-eacb-4d33-db29-6987d9f75530.png)

5.サービスロール設定
「ロールの作成」からロール名を登録する。
![Codepipeline-setting5-1.png](https://qiita-image-store.s3.amazonaws.com/0/61103/73ca5f15-8c68-7a7c-1139-8f613ee30752.png)
![Codepipeline-setting5-2.png](https://qiita-image-store.s3.amazonaws.com/0/61103/31cb5f3d-9801-f565-77e3-b3c645a9388b.png)

作成したサービスロールを設定する。
![Codepipeline-setting5.png](https://qiita-image-store.s3.amazonaws.com/0/61103/29453d6b-2cb5-e1f3-38ac-48bcbf4fe6f9.png)

6.「パイプラインの作成」ボタンを押下して完了。


## [Jenkins]S3にリビジョンをアップロードする
1.サンプルコードを利用する場合、S3にアップロードするファイル群をzip形式にまとめる。
JenkinsのJob設定画面で`シェルの実行`を選択し、以下を追加する。

```
cd target
cp demo-0.0.1-SNAPSHOT.jar ../deploy/demo.jar
cd ../deploy/
jar -cMf demo.zip *
```

2.JenkinsのS3アップロードプラグインを利用して、zip化したファイルをS3にアップロードにする。
以下、設定画面の例。
[Destination bucket]には、CodePipelineで設定したS3バケットを指定する。
![S3-setting.PNG](https://qiita-image-store.s3.amazonaws.com/0/61103/0bdcace8-8f37-7f10-ba9e-43cf2dcb40d8.png)

3.[保存]ボタンを押下して完了。