Spring BootをElastic Beanstalk上で動かしてみた

Spring BootをElastic Beanstalk上にデプロイした事例があまりなかったので、メモ代わりに残しておきます。
Spring Bootの組み込みTomcatを使用するため、BeanstalkのPlatformはTomcatではなくJavaを使用します。
また今回は作業する環境としてCentOS7を使用します。CentOS7 -> Elastic Beanstalkという流れでデプロイしていきます。


# 作業環境に Javaインストール
```sh:インストール例
sudo yum install java-1.8.0-openjdk-devel.x86_64 -y
```

# 作業環境に gradleインストール
```sh:インストール例
cd /tmp
wget https://services.gradle.org/distributions/gradle-2.10-all.zip
sudo unzip -n /tmp/gradle-2.10-all.zip -d /usr/local/
sudo sed -i -e 's%^PATH\(.*\)%PATH\1:/usr/local/gradle-2.10/bin%' /root/.bash_profile
sed -i -e 's%^PATH\(.*\)%PATH\1:/usr/local/gradle-2.10/bin%' ~/.bash_profile
rm -i /tmp/gradle-2.10-all.zip
```

# 作業環境に aws cli/eb cliインストール
```sh:インストール例
sudo pip install awscli
sudo pip install awsebcli
```
この後aws configureを実行して、awsにコマンドを発行可能な状態にしておきます。

# 作業環境にて、Spring Bootアプリケーションの準備
```java:src/main/java/trial/Application.java
package trial;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}
```
```java:src/main/java/trial/TrialController.java
package trial;

import org.springframework.stereotype.Controller;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@EnableAutoConfiguration
public class TrialController
{
    @RequestMapping("/")
    @ResponseBody
    public String getReq() {
        return "Good morning, Spring Boot サンプル";
    }
}
```
```properties:src/main/resources/application.properties
server.port=5000
```
Beanstalkのnginxがポート番号5000をProxyPassしてくるので、Spring Boot側を5000で待ち受けさせます。

```groovy:build.gradle
buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE")
  }
}

apply plugin: "java"
apply plugin: "spring-boot"

jar {
  baseName = "spring-boot-trial"
  version =  "0.0.1-SNAPSHOT"
}

repositories {
  mavenCentral()
}

configurations {
    providedRuntime
}

dependencies {
  compile("org.springframework.boot:spring-boot-starter-web")
  testCompile("org.springframework.boot:spring-boot-starter-test")
}
```

# 作業環境にて、Spring Bootアプリケーションのビルド
プロジェクトディレクトリ直下に移動し、gradleでビルドします。

```sh:ビルド実行例
gradle build
```
BUILD SUCCESSFULとなった後、build/libsの配下にjarが作成されていることを確認します。
確認後、作成されたjarをプロジェクトディレクトリ直下にコピーしておきます。

# 作業環境にて、Procfileの作成＆Jarに追加
プロジェクトディレクトリ直下に移動し、Procfileというファイル名で以下内容を記述し保存します。

```text:Procfile
web: java -jar 作成したjarファイル名(今回はspring-boot-trial-0.0.1-SNAPSHOT.jar)
```
JVMオプションがあれば（Xms等）、適宜追記願います。
作成したProcfileを上記で作成したjarに追加します。

```sh:Procfileをjarに追加例
zip 作成したjarファイル(今回はspring-boot-trial-0.0.1-SNAPSHOT.jar) Procfile
```


# 作業環境にて、Elastic Beanstalkの準備
プロジェクトディレクトリ直下に移動し、

```sh:
eb init
```
と実行します。

```sh:対話実行例
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-southeast-1 : Asia Pacific (Singapore)
7) ap-southeast-2 : Asia Pacific (Sydney)
8) ap-northeast-1 : Asia Pacific (Tokyo)
9) sa-east-1 : South America (Sao Paulo)
10) cn-north-1 : China (Beijing)
(default is 3): 8

Select an application to use
1) 初めての Elastic Beanstalk アプリケーション
2) [ Create new Application ]
(default is 1): 1

Enter Application Name
(default is "○○○○○"):
Application ○○○○○ has been created.

Select a platform.
1) Node.js
2) PHP
3) Python
4) Ruby
5) Tomcat
6) IIS
7) Docker
8) Multi-container Docker
9) GlassFish
10) Go
11) Java
(default is 1): 11

Select a platform version.
1) Java 8
2) Java 7
(default is 1): 1
Do you want to set up SSH for your instances?
(y/n): y

Select a keypair.
1) □□□□
2) [ Create new KeyPair ]
(default is 2): 1
```
環境名とキーペアは適切な値を選択/入力します。

# 作業環境より、Elastic Beanstalk環境作成＆デプロイ
プロジェクトディレクトリ直下に移動し、

```sh:
eb create 環境名(springboot-dev等) \
--tier webserver \
--instance_type インスタンスサイズ(t2.micro等） \
--single \
--vpc.id VPCのID(vpc-xxxxxxxx) \
--vpc.ec2subnets SubnetのID(subnet-xxxxxxxx) \
--vpc.publicip \
--vpc.securitygroups セキュリティグループのID(sg-xxxxxxxx) \
```
と実行します。
※上記はELBを用いない単一構成です。

しばらくすると、AWS側で環境構築が完了しますので、
AWSコンソールのElastic Beanstalkの画面に表示されている、作成した環境のURLをブラウザで確認すると、

```text
Good morning, Spring Boot サンプル
```

が画面表示されます。