Help us understand the problem. What is going on with this article?

ゼロから始めるJavaでAWS Elastic Beanstalk #1~ EB CLIを使ったJava Webアプリ環境構築 ~

概要

  • AWS Elastic Beanstalkを使えば、EC2でのOSやミドルウェアのセットアップ不要でコマンド1つでWebアプリ実行環境を構築することができます。セキュリティパッチ等も自動適用できるため運用が軽くなるメリットもある上、ベースはEC2等AWSのコンポーネントの組み合わせなので、その気になれば色々カスタマイズもできるという、とても使い勝手の良いサービスです。
  • 本稿ではEB CLIというツールをつかってコマンド1つでJava Web アプリの実行環境を構築します。
  • Java Webアプリは、Tomcatで動作するWARではなく、Java SEでつくったスッピンのWebアプリ(JAR)が対象です。
    (つまり概念さえ理解できればWebアプリFrameworkはSpring BootでもPlay frameworkでもかまいませんし、アプリサーバーもTomcatでもJettyでもGlassfishでもOKです)
  • また、続編で独自ドメイン対応、HTTPS対応、HTTP→HTTPSへのリダイレクト対応、Auto Scaling設定をします。

環境・構成

以下のような構成をコマンドラインから作ります
(コマンドラインから作るので環境の量産、再構築もカンタン)

image.png

  • アプリ・プラットフォーム
    • AWS Elastic Beanstalkの Java 8 プラットフォーム
    • 本稿ではJSP/ServletのWebアプリをJetty9で実行
  • クラウド環境
    • サービス:AWS Elastic Beanstalk (EC2 + Application Loadbalancer on VPC)
    • リージョン:東京(ap-northeast-1) →東京じゃなくてもOK

ソースコード

本稿で紹介する全ソースコードはこちらにあります
https://github.com/riversun/java-jetty-app-on-elasticbeanstalk

本編

Elastic Beanstalk コマンドラインインターフェイス(EB CLI)のインストール

Elastic BeanstalkアプリはWeb GUIをつかっても構築できるが、環境構築の自動化など本番運用を考えるとコマンドラインを使うと同じような操作を何度もせずにすみ手間もへるし、アプリ・環境の構築・変更がコマンド一発で済のでCIに組み込むなどすれば安定した運用が可能となる。

1.EB CLIをインストールする

EB CLIのインストールにはPythonが必要となる。
もし、PCにPythonがインストールされていなければ、
https://www.anaconda.com/distribution/
などからインストールしておく。最新版をインストールしておけばOK

Pythonがインストールが完了していれば、以下のコマンドで EB CLI をインストールできる

pip install awsebcli --upgrade --user

2.以下のコマンドでインストール終了チェック

EB CLIがインストールされ、コマンドラインで利用可能になっているかどうか、以下のコマンドで確認する

eb --version

EB CLI 3.15.2 (Python 3.7.1)

ちゃんとインストールできた模様

TIPS
Windows環境の場合、eb コマンドがみつからない場合がある。
そのときは、

C:\Users\[ユーザー名]\AppData\Roaming\Python\Python37\Scripts

をパスに追加する

JavaでWebアプリを作る

Elastic Beanstalkで作るJavaアプリは FAT JAR形式で作る

Elastic BeanstalkでJava Webアプリを実行するにはいくつかの方法がある。

  • warファイルをアップロード(Tomcatで実行する)
  • JARファイルをアップロード(Java SE環境で実行する)

本稿では JARファイルをアップロード する方式を採用する。

JARファイルとは、Javaで作ったアプリ(Webアプリ)のソースコード+依存ファイルを1つのJARにまとめたモノの事を言う。全部1つにしてサイズの大きなJARを作るので「FAT JAR」とも言う。

JARを使うメリットは、作ったWebアプリをJARファイルにさえできれば、何でもOKということ。

FrameworkはPlay Frameworkでも、Spring Bootでも、Strutsでも、JSFでも良いし(もちろん素のJSP/ServletでもOK)、APサーバーもTomcatでもJettyでもGlassfishでもUndertow(Wildfly)でもOK。

ただしJARをつくってElastic Beanstalkで動かすには、「Elastic Beanstalkのお作法」があるので、そちらをみていく。

といっても、難しくはない。

Elastic Beanstalk用のJavaソースコード構成

Web APサーバーとしてJettyを使ったJava Webアプリを考える。

まず、全体像は以下のとおり。「★」印がついているところが Elastic Beanstalkのための構成
その他はJavaのMavenプロジェクトの標準的なソースコード構成となる

ElasticBeanstalk用Javaソースコード構成
elastic-beantalk-java-app
├── src/main/java ・・・Javaのソースコードのルートディレクトリ
│   └── myserver  
│       └── StartServer.java
├── src/main/resources
│   └── webroot  ・・・静的WebコンテンツやJSPのルートディレクトリ
│       ├── index.html
│       └── show.jsp 
├── src/main/assembly
│   └── zip.xml ・・・★elastic beanstalkにアップロードするZIPファイルの生成ルールを記述
├── .elasticbeanstalk ・・・★Elastic Beanstalkへのデプロイ情報を格納するディレクトリ
│   └── config.yml  ・・・★Elastic Beanstalkへのデプロイ情報のYAMLファイル
├── target ・・・ビルドした結果(jarなど)が生成されるディレクトリ
├── Procfile ・・・★Elastic BeanstalkのEC2上でJARファイルを実行するためのスクリプトを記述する
└── pom.xml ・・・Maven用設定ファイル

ソースコードや設定ファイル等の中身については後で説明するとして、
先にこのソースコードがどのようにビルドされて Elastic Beanstalkにアップロードされるかをみておく。

Elastic BeanstalkにアップロードするZIPファイルの構造

本稿では、手元のPCでソースコードをビルドして、それを1つのJARファイルにパッケージし、さらにJARファイル以外にもElastic Beanstalkに必要なファイル含めてZIPファイルを生成する。

ここで、JavaのソースコードをビルドしてできたFAT JARのファイル名をeb-app-jar-with-dependencies.jarとする。(maven-assembly-pluginで生成する、後で説明)
ElasticBeanstalkにアップロードするためのZIPファイル名をmy-jetty-app-eb.zipとすると、そのZIPファイルの中身構造は以下となる。

my-jetty-app-eb.zipの中身
my-jetty-app-eb.zip
├── my-jetty-app-jar-with-dependencies.jar ・・・Javaのソースコードを1つのJARにパッケージしたもの
└── Procfile ・・・Elastic BeanstalkのEC2内でJARを実行するためのスクリプト

ZIPファイルの中には、ソースをまとめたJARファイルと、実行スクリプトの書いてあるファイルであるProcfileの2つとなる。
ということで、この形式のZIPファイルをEB CLI経由でElastic Beanstalkにアップロードすればデプロイできる。
これが「Elastic Beanstalkのお作法」の1つということになる。

次は、Javaアプリのソースをみていく。
とくに「Elastic Beanstalkのお作法」に関連する部分を中心に説明する

Javaアプリのソースコードの作り方

これからJavaアプリを動かそうとしているElastic Beanstalk環境は以下のようなもので、Java Webアプリとしてケアしておくべき点はポート番号 5000をListenするところ

image.png

つまり、Javaでポート番号 5000をListenするサーバープログラムを作ってあげればひとまずOK

サンプルコード
ということでサンプルコードを以下のリポジトリに置いた
https://github.com/riversun/java-jetty-app-on-elasticbeanstalk

このサンプルはServlet/JSP/プッシュ通知機能をJetty上動作させている

このコードをクローンすると

clone https://github.com/riversun/java-jetty-app-on-elasticbeanstalk.git

前述したとおり以下のようなソースコード構成となっている。
(一部ファイルは省略)

ElasticBeanstalk用Javaソースコード構成
elastic-beantalk-java-app
├── src/main/java ・・・Javaのソースコードのルートディレクトリ
│   └── myserver  
│       └── StartServer.java
├── src/main/resources
│   └── webroot  ・・・静的WebコンテンツやJSPのルートディレクトリ
│       ├── index.html
│       └── show.jsp 
├── src/main/assembly
│   └── zip.xml ・・・★elastic beanstalkにアップロードするZIPファイルの生成ルールを記述
├── .elasticbeanstalk ・・・★Elastic Beanstalkへのデプロイ情報を格納するディレクトリ
│   └── config.yml  ・・・★Elastic Beanstalkへのデプロイ情報のYAMLファイル
├── target ・・・ビルドした結果(jarなど)が生成されるディレクトリ
├── Procfile ・・・★Elastic BeanstalkのEC2上でJARファイルを実行するためのスクリプトを記述する
└── pom.xml ・・・Maven用設定ファイル

※「★」印がついているところが Elastic Beanstalkのための構成

Javaアプリとしてのメインクラス(エントリーポイント)は StartServer.javaとなる。
これをローカル実行して http://localhost:5000/ にアクセスすれば、以下のようになり
JSPやServletなどのシンプルな実装を試すことができるサンプルとなっている。

image.png

ここからは、ソースコードで重要なところを以下に説明する

src/main/java myserver.StartServer.java

メインクラス。
Jettyを起動してServlet/JSPをホストしポート5000で待ち受ける

/pom.xml

pom.xml(抜粋)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.riversun</groupId>
    <artifactId>my-jetty-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    <name>my-jetty-app</name>
    <description>jetty app on elastic beanstalk</description>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>org.riversun</groupId>
    <artifactId>my-jetty-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    <name>my-jetty-app</name>
    <description>jetty app on elastic beanstalk</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jetty-version>9.4.19.v20190610</jetty-version>
    </properties>

    <dependencies>
        <!-- for server -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-annotations</artifactId>
            <version>${jetty-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${jetty-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>apache-jsp</artifactId>
            <version>${jetty-version}</version>
            <type>jar</type>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>apache-jstl</artifactId>
            <version>${jetty-version}</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.9</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <excludes>
                        <exclude>examples/**/*</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <author>true</author>
                    <source>1.7</source>
                    <show>protected</show>
                    <encoding>UTF-8</encoding>
                    <charset>UTF-8</charset>
                    <docencoding>UTF-8</docencoding>
                    <doclint>none</doclint>
                    <additionalJOption>-J-Duser.language=en</additionalJOption>
                </configuration>
            </plugin>
            <!-- add source folders -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>src/main/java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <!-- ソースコードをfat-jar化する -->
                    <execution>
                        <id>package-jar</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <appendAssemblyId>true</appendAssemblyId>
                            <archive>
                                <manifest>
                                    <mainClass>myserver.StartServer</mainClass>
                                </manifest>
                            </archive>
                            <finalName>${project.artifactId}</finalName>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                    <!-- Elastic Beanstalkにアップロードするzip(fat.jarや関連ファイルを含む)を作成する -->
                    <execution>
                        <id>package-zip</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <appendAssemblyId>true</appendAssemblyId>
                            <finalName>${project.artifactId}</finalName>
                            <descriptors>
                                <descriptor>src/main/assembly/zip.xml</descriptor>
                            </descriptors>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>
</project>

以下、ポイントだけみていく。

mavenのartifactId

以下はartifactIdとしてmy-jetty-appとした。
この後のビルドで生成されるファイル名などもこのartifactIdの値が使われる

    <groupId>org.riversun</groupId>
    <artifactId>my-jetty-app</artifactId>

maven-assembly-pluginの設定

以下はmaven-assembly-pluginの設定を行っている。
maven-assembly-pluginとは、配布用のjarファイルやzipファイルを作るためのmavenプラグイン。
このmaven-assembly-pluginには2つのタスクをさせている。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <!-- ソースコードをfat-jar化する -->
    <execution>
      <id>package-jar</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <appendAssemblyId>true</appendAssemblyId>
        <archive>
          <manifest>
            <mainClass>myserver.StartServer</mainClass>
          </manifest>
        </archive>
        <finalName>${project.artifactId}</finalName>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
    <!-- Elastic Beanstalkにアップロードするzip(fat.jarや関連ファイルを含む)を作成する -->
    <execution>
      <id>package-zip</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <appendAssemblyId>true</appendAssemblyId>
        <finalName>${project.artifactId}</finalName>
        <descriptors>
          <descriptor>src/main/assembly/zip.xml</descriptor>
        </descriptors>
      </configuration>
    </execution>
  </executions>
</plugin>

その1 JARファイル生成
まず前半の設定に注目。

  <execution>
      <id>package-jar</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <appendAssemblyId>true</appendAssemblyId>
        <archive>
          <manifest>
            <mainClass>myserver.StartServer</mainClass>
          </manifest>
        </archive>
        <finalName>${project.artifactId}</finalName>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>

ここで記述しているのはJavaソースコードを1つのJARファイルにまとめること。
つまり、FAT JARを作るためのタスク設定となる。

<mainClass>myserver.StartServer</mainClass>はJARファイルを実行するときの起動クラス。

<finalName>${project.artifactId}</finalName>は、最終的にできあがるJARファイルのファイル名がartifactIdで指定された値=my-jetty-app-[AssemblyId].jarとなる。

<descriptorRef>jar-with-dependencies</descriptorRef>はmavenのdependenciesに記載した依存ライブラリも一緒にJARファイルとしてパッケージする。

<appendAssemblyId>true</appendAssemblyId>は、生成されるJARファイルのファイル名にAssemblyIdをつけるか否かをセットする。もしこれをtrueにすると、JARファイル名はmy-jetty-app-jar-with-dependencies.jarとなる。

ここで設定した条件でJARファイルを生成するには

mvn package

とすればよい。するとtargetディレクトリにmy-jetty-app-jar-with-dependencies.jarが生成される

その2 ZIPファイルの生成

次は後半の設定

   <execution>
      <id>package-zip</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <appendAssemblyId>true</appendAssemblyId>
        <finalName>${project.artifactId}</finalName>
        <descriptors>
          <descriptor>src/main/assembly/zip.xml</descriptor>
        </descriptors>
      </configuration>
    </execution>

ここで記述しているのは、上でつくったJARファイルとElastic Beanstalk関連ファイル(Procfileなど)をZIPファイルにまとめるタスクとなる。

<finalName>${project.artifactId}</finalName>としているところはJARのときと同じく生成されるファイル名を指定している。

ZIPの生成ルールは外だしされた設定ファイルである<descriptor>src/main/assembly/zip.xml</descriptor>で設定する。

src/main/assembly/zip.xml

さて、その外だしされた zip.xmlをみてみる。

これは最終的にZIPファイルを生成するときの生成ルールとなる。

<include>でJARファイルとProcfileなどを指定して、Elastic Beanstalkにアップロードする形式のZIPファイルの生成方法を指示している。

zip.xml
<?xml version="1.0" encoding="UTF-8"?>
<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>eb</id>
    <baseDirectory>/</baseDirectory>
    <formats>
        <format>zip</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>Procfile</include>
                <include>Buildfile</include>
                <include>.ebextensions/*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>my-jetty-app-jar-with-dependencies.jar</include>
                <!-- <include>*.jar</include> -->
            </includes>
        </fileSet>
    </fileSets>
</assembly>

最終的に生成されるZIPファイルのファイル名はmy-jetty-app-[id].zipとなる。
zip.xmlでは、<id>eb</id>と指定しているので、生成されるZIPファイル名はmy-jetty-app-eb.zipとなる。

まとめると必要パッケージを生成するためのmavenコマンド mvn package を実行するとmy-jetty-app-jar-with-dependencies.jarmy-jetty-app-eb.zipの両方がtargetディレクトリ以下に生成されることになる。

ここは、あとで実際にdeployファイルを生成するところでもう一度確認する。

/Procfile

ProcfileはElastic BeanstalkのEC2内でJARを実行するためのファイル。

Elastic BeanstalkのEC2上でアプリを起動するためのコマンドをweb:以下に記載する。

Procfile
web: java -jar my-jetty-app-jar-with-dependencies.jar

↓のように起動オプションを記述してもOK

web: java -jar my-jetty-app-jar-with-dependencies.jar -Xms256m

詳細は公式参照

.elasticbeanstalk/config.yml

config.ymlにはデプロイ情報を記述する
ここにはElastic Beansalkにデプロイするファイルtarget/my-jetty-app-eb.zipを指定している。

config.yml
deploy:
  artifact: target/my-jetty-app-eb.zip

Elastic Beanstalkにデプロイする際に、このファイルが参照される。

いまはdeploy:artifact:しか記述していないが、これからEB CLIをつかってElastic Beanstalkのデプロイ設定をしていく過程でこのconfig.ymlに必要な値が追加されていく。

EB CLIを使ってアプリをデプロイする

ファイルの意味をざっくり理解できたところで、さっそくElastic Beanstalkにアプリをデプロイする。

EB CLIを使ってElastic BeanstalkアプリケーションをAWS上に作る

1.アプリのディレクトリに移動する

cd java-jetty-app-on-elasticbeanstalk

2.Elastic BeanstalkにJava用の箱*を作る
(* 箱=アプリケーション)

そのためのEB CLIのコマンドは以下の形式となる。

eb init アプリ名 --region リージョン名 --platform プラットフォーム

ここではアプリ名をmy-eb-app、リージョンは東京リージョン(ap-northeast-1)、プラットフォームをjava-8とする

コマンドは以下のようになる。

eb init my-eb-app --region ap-northeast-1 --platform java-8

すると

Application my-eb-app has been created.

というメッセージがでて、
AWS Elasticbeanstalk上にアプリケーションの箱ができる

さっそくWebコンソールで確認すると箱(アプリケーション)ができている

https://ap-northeast-1.console.aws.amazon.com/elasticbeanstalk/home

image.png

さて、ソースコードにある/.elasticbeanstalk/config.ymlを見てみる。

上記コマンドで、config.ymlも更新され、以下のようになっている。

config.yml
branch-defaults:
  master:
    environment: null
deploy:
  artifact: target/my-jetty-app-eb.zip
global:
  application_name: my-eb-app
  branch: null
  default_ec2_keyname: null
  default_platform: java-8
  default_region: ap-northeast-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: eb-cli
  repository: null
  sc: git
  workspace_type: Application

TIPS
------------

もし、Credential情報が登録されていなければ、以下のようにaws-access-idaws-secret-keyを聞かれるので入力する。

eb init my-eb-app --region ap-northeast-1 --platform java-8
You have not yet set up your credentials or your credentials are incorrect
You must provide your credentials.
(aws-access-id): xxxxx
(aws-secret-key): xxxxx
Application my-eb-app has been created.

1回入力すれば、[user]/.awsディレクトリ以下にconfigファイルができるので、次からは聞かれない。

------------

デプロイ用のパッケージを作る

さきほどみてきたように、Elastic BeanstalkにデプロイするためのZIPファイルを生成する。

ZIP生成はMavenでやるのでmaven packageコマンドをたたく

(cleanもついでにやっておくと、コマンドは以下のとおり)

mvn clean package

以下のようになり、無事 target/ディレクトリにmy-jetty-app-eb.zipが生成できた。

[INFO] --- maven-assembly-plugin:2.2-beta-5:single (package-zip) @ my-jetty-app ---
[INFO] Reading assembly descriptor: src/main/assembly/zip.xml
[INFO] Building zip: jetty-app-on-eb\target\my-jetty-app-eb.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 32.984 s
[INFO] Finished at: 2019-07-01T15:55:14+09:00
[INFO] Final Memory: 37M/449M
[INFO] ------------------------------------------------------------------------

Elastic Beanstalkにデプロイし環境を構築する

いまから、つくったZIPファイルをEB CLIをつかってElastic Beanstalkにデプロイする

Elastic Beanstalkにデプロイするには、eb createコマンドを使う

eb createコマンドの使い方

eb createコマンドは以下のように指定する。

eb create 環境の名前 [オプション][オプション]・・・[オプション]
オプションは以下のとおり
オプション 説明
--cname URLのCNAMEを指定。
例 CNAMEにmy-jetty-app-test を指定すると
http://my-jetty-app-test.ap-northeast-1.elasticbeanstalk.com/
としてアクセスできる
--instance_type インスタンスタイプ。
t2シリーズを指定する場合はVPC必須
--elb-type ロードバランサーのタイプ
「application」を指定すると
アプリケーションロードバランサーになる。
あとで、独自ドメインやHTTPS対応するときにも
ロードバランサーあると楽
--vpc.id VPCのID
--vpc.elbpublic ロードバランサーを
パブリックサブネットに置く
--vpc.elbsubnets ロードバランサーのサブネットIDを指定。
複数指定するときはカンマ区切り
--vpc.publicip Elastic BeanstalkのEC2を
パブリックサブネットに置く
--vpc.ec2subnets Elastic Beanstalkの
EC2のサブネットIDを指定。
複数指定するときはカンマ区切り

詳しくは公式参照

それでは、
コマンドラインから以下を実行する。

eb create my-jetty-app-test --cname my-jetty-app-test --instance_type t2.small --elb-type application --vpc.id vpc-xxxxxxxxxxxxxxxxx --vpc.elbpublic --vpc.elbsubnets subnet-xxxxxxxxxxxxxxxxx,subnet-yyyyyyyyyyyyyyyyy --vpc.publicip --vpc.ec2subnets subnet-xxxxxxxxxxxxxxxxx,subnet-yyyyyyyyyyyyyyyyy

上記は実際のID等はダミーだが、環境名my-jetty-app-test、cnameがmy-jetty-app-testでEC2のインスタンスタイプがt2.small、ELB(ロードバランサー)がapplicationロードバランサー、VPCのIDがvpc-xxxxxxxxxxxxxxxxxとしてさきほどのZIPファイルをデプロイするコマンドとなる。

(どのZIPファイルがアップロードされるかは、.elasticbeanstalk/config.ymlで指定されているのでそれが参照される)

また、--vpc.elbpublic--vpc.publicipはELB(ロードバランサー)とElastic BeanstalkのEC2が指定したVPC内のパブリックサブネットで実行されることを示している。--vpc.elbsubnets--vpc.ec2subnetsそれぞれおなじパブリック・サブネット(2つ)を指定してある。ELBはパブリックにアクセスできないとアプリにアクセスできないのでパブリックサブネットに置く。EC2側はパブリックサブネットに置く方法とプライベートサブネットにおく方法がある。本稿の例では、パブリックサブネットにおいているが、自動生成されたセキュリティグループによってELBからしかアクセスできないようになっている。ただし、パブリックIPは割り当てられる。
(よりセキュアにするにはEC2はプライベートサブネットに置くなど工夫ができるが、これはElastic BeanstalkというよりEC2,VPCまわりのセキュリティイシューなのでここでは割愛とする。)

さて、上記コマンドを実行すると、以下のようにアップロードから環境構築までが自動的に実行される。

Uploading: [##################################################] 100% Done...

Environment details for: my-jetty-app-test
  Application name: my-eb-app
  Region: ap-northeast-1
  Deployed Version: app-1d5f-190705_00000
  Environment ID: e-2abc
  Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Java 8 running on 64bit Amazon Linux/2.8.6
  Tier: WebServer-Standard-1.0
  CNAME: my-jetty-app-test.ap-northeast-1.elasticbeanstalk.com
  Updated: 2019-07-01 07:08:01.989000+00:00

Printing Status:
2019-07-01 07:08:00    INFO    createEnvironment is starting.
2019-07-01 07:08:02    INFO    Using elasticbeanstalk-ap-northeast-1-000000000000 as Amazon S3 storage bucket for environment data.
2019-07-01 07:08:23    INFO    Created target group named: arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:targetgroup/awseb-AWSEB-LMAAAA/000000000
2019-07-01 07:08:23    INFO    Created security group named: sg-11111111111111111
2019-07-01 07:08:39    INFO    Created security group named: sg-22222222222222222
2019-07-01 07:08:39    INFO    Created Auto Scaling launch configuration named: awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingLaunchConfiguration-3V
2019-07-01 07:09:41    INFO    Created Auto Scaling group named: awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXX
2019-07-01 07:09:41    INFO    Waiting for EC2 instances to launch. This may take a few minutes.
2019-07-01 07:09:41    INFO    Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:000000000000:scalingPolicy:4e:autoScalingGroupName/awseb-e-
xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXX:policyName/awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingScaleUpPolicy-FA
2019-07-01 07:09:42    INFO    Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:000000000000:scalingPolicy:8a:autoScalingGroupName/awseb-e-
xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXX:policyName/awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingScaleDownPolicy-SSZW
2019-07-01 07:09:57    INFO    Created CloudWatch alarm named: awseb-e-xxxxxxxxxx-stack-AWSEBCloudwatchAlarmHigh-H0N
2019-07-01 07:09:57    INFO    Created CloudWatch alarm named: awseb-e-xxxxxxxxxx-stack-AWSEBCloudwatchAlarmLow-BX
2019-07-01 07:10:34    INFO    Created load balancer named: arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:loadbalancer/app/awseb-AWSEB-1BQ
2019-07-01 07:10:34    INFO    Created Load Balancer listener named: arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:listener/app/awseb-AWSEB-1BQ
2019-07-01 07:11:05    INFO    Application available at my-jetty-app-test.ap-northeast-1.elasticbeanstalk.com.
2019-07-01 07:11:05    INFO    Successfully launched environment: my-jetty-app-test

環境構築が開始されると、Webコンソールでも状況を把握することができる。

デプロイできた模様

image.png

image.png

無事アプリが http://my-jetty-app-test.ap-northeast-1.elasticbeanstalk.com/ にデプロイされた模様

アクセスすると、

image.png

ちゃんとJSPやServletも動いている模様

image.png

まとめ

  • Java SEをつかったWebアプリをEB CLIをつかって、AWS Elastic Beanstalkにデプロイするまでの手順をハンズオン方式で紹介しました

  • 結果、以下のような構成をコマンドから構築することができました

image.png

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away