Spring Boot アプリケーションを最速でAzure WebAppsにデプロイする

# Spring Boot アプリケーションを最速でAzure WebAppsにデプロイする

タイトルは釣りです。今回は、Spring Boot アプリケーション お手軽に WebApps にデプロイするまでを解説しようと思います。

ちなみに知らない方に説明すると、WebAppsとは、Azure上で動作するWebアプリケーションをホストするSaaSサービスです。とてもポピュラーで、Webアプリケーションのデプロイ先としてこれ以外あり得ないくらい便利です。

デプロイできるJavaアプリケーションはSpring Boot だけではありませんが、一番ポピュラーなので、まだ一度もWebAppsを試したことがないかたは真っ先に試すべきだと思います。

# 実行手順

## 必要なもの

必要なものは、Azure サブスクリプションと Azure CLI と Java です。ここでは Java 11 を使いますが、適宜 Java 8 を選択するポイントを間違わなければ、Java 8 で問題ありません。

Azure サブスクリプションは以下から無料で作れます。

* [Azure の無料アカウントを今すぐ作成しましょう | Microsoft Azure](https://azure.microsoft.com/ja-jp/free/)

Azure CLIは、Azureを操作するためのコマンドラインインタフェースです。ポータルからブラウザベースでAzureリソースを作成できますが、CLIを使えば簡単です。

今回は、Mavenプラグインが勝手に必要なリソースを作ってくれるので、単にサブスクリプションへの認証と、最後にリソースを削除するのに必要なだけです。以下からダウンロードして、インストールしましょう。

* [Install the Azure CLI | Microsoft Docs](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli) からインスタンスできます。

## Spring Bootアプリケーションの準備

有名どころの、[Spring Initializr](https://start.spring.io/) からプロジェクトのひな形を生成できますが、以下のようにCURLを叩くと希望するひな形が生成＆ダウンロードできて便利です。

```sh
curl -G https://start.spring.io/starter.zip -o ./demo.zip -d javaVersion=11 -d packaging=jar -d dependencies=web
```
※ Java 8のひな形が欲しいときは、引数を`javaVersion=8`に変更する

そもままですと、何のAPIも用意されていないので、適当に`RestController`を用意しておきます。

```java
package com.example.demo;

import java.util.Date;
import java.util.HashMap;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
public class HelloController {

    @GetMapping("hello")
    public Map<String, String> hello() {
        return new HashMap<String, String>() {
            {
                put("message", "Hello Spring Boot Application");
                put("date", (new Date().toString()));
            }
        };
    }
}
```

`mvn spring-boot:run` してローカル実行してみて確認しましょう。 `http://localhost:8080/hello` でレスポンスがあればOKです。


## Azureの認証

次のステップに進む前に、`az` コマンドで目的のサブスクリプションに対して認証を行っておきます。`~/.azure` に認証情報が保存されるので、次の Maven プラグインのステップでは、それらを暗黙的に利用して Azure を操作します。

`az login` コマンドを実行すると、ブラウザが開いて認証が促されますので適宜実行してください。お使いの環境によっては、デバイスコード認証になるかもしれませんが、その場合は自力で表示されたURLにアクセスし、表示されたデバイスコードを入力すると認証されます。

複数サブスクリプションを持っていて、どこに接続されているか分らない場合は、`az account`コマンドでサブスクリプションの一覧が確認できます。

```
az login
az account list -o table
```

## WebAppsの構成

展開したディレクトリに移動して以下のコマンドを実行します。Mavenはインストールされてなくても、プロジェクトに組み込まれたものが実行されます。

以下のコマンドの意味は、Azure WebApps用のMavenプラグインを呼び出して、これから作成するAzureリソースの構成設定をしてくれます。

```sh
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:1.13.0:config
```

この後、いくつかの選択肢について、対話的に聞かれると思いますので、以下のように答えてください。詳細は後述します。

1. WebApps : Create
2. OS : Linux
3. Pricing Tier : B1
4. Java Version : Java 11 

※ Java 8 で実行したい場合は、`Java 8`を選択する

構成が終わると、`pom.xml`の `build` セクションに以下が追加されます。タグ名見れば何の構成値かはすぐ分ると思います。

注意したい点は、

* アプリケーション名とリソースグループと、適当なルールで命名される。アプリケーション名は、URLの一部になるので、一意性が必要です。
* ロケーションが `westeurope`になっているので、`japaneast`あたりに変更する

な感じです。

```xml
      <plugin>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-webapp-maven-plugin</artifactId>
        <version>1.13.0</version>
        <configuration>
          <schemaVersion>v2</schemaVersion>
          <subscriptionId>2399f90b-a4c8-4e60-ad23-6708f2149c6b</subscriptionId>
          <resourceGroup>demo-1617863761590-rg</resourceGroup>
          <appName>demo-1617863761590</appName>
          <pricingTier>B1</pricingTier>
          <region>westeurope</region>
          <runtime>
            <os>Linux</os>
            <javaVersion>Java 11</javaVersion>
            <webContainer>Java SE</webContainer>
          </runtime>
          <deployment>
            <resources>
              <resource>
                <directory>${project.basedir}/target</directory>
                <includes>
                  <include>*.jar</include>
                </includes>
              </resource>
            </resources>
          </deployment>
        </configuration>
      </plugin>
```

## WebApps へのデプロイ

ビルドセクションにプラグインが明示的に指定されたので、つぎは完全修飾名の形ではなく、省略系でコマンドを実行できます。

```
./mvnw clean package azure-webapp:deploy
```

コマンドを実行すると存在しないをリソースを作成します。二度目以降のデプロイは、`pricingTier` とか `javaVersion`とかの変更可能な値ならば、修正することで変更してくれますが、OS等は変更できないです。

最終的にデプロイが成功したら、アクセスしてみますが、WebAppsの再起動に時間がかかる場合があるので、1分くらい待ってみましょう。

```log
[INFO] Auth method: AZURE_CLI
...
[INFO] Creating resource group demo-1617863761590-rg in region westeurope...
[INFO] Successfully created resource group demo-1617863761590-rg.
[INFO] Creating app service plan...
[INFO] Successfully created app service plan asp-demo-1617863761590.
[INFO] Creating web app demo-1617863761590...
[INFO] Successfully created Web App demo-1617863761590.
[INFO] Trying to deploy artifact to demo-1617863761590...
[INFO] Successfully deployed the artifact to https://demo-1617863761590.azurewebsites.net
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:25 min
[INFO] Finished at: 2021-04-08T15:58:22+09:00
[INFO] ------------------------------------------------------------------------
```

ブラウザでアクセスするとJSONのレスポンスが確認出来ると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34017/ff045c6e-6f63-2dd2-66e9-24f627bb6bd5.png)

## 削除

そのままですと、課金されつづけてしまいますので、以下のコマンドでリソースグループ毎削除します。お使いの環境に合わせてリソースグループ名は変更してください。

```sh
az group delete -n demo-1617863761590-rg
```

# 補足

先ほどは、さっさっと構成を済ませてしまいましたが、いくつか補足しておきます。

## WebAppsの構成

SaaSである WebAppsなのですが、いくつか選択肢があります。1つ目はホスティング OSで、Windows または Linux のいずれかが選択できます。どちらを選んでも大きな違いはないのですが、好みで良いともいます。

Javaのバージョンは、Java 8 または、 Java 11 のどちらかです。

Linux の場合、アプリケーションコンテナとして以下が選択できます。ですので、Tomcat などを選択すれば war もデプロイできます。

* Java SE (Spring Boot アプリのようば組み込みWebサーバーを実行する場合)
* Tomcat 8.5 / 9.0 
* JBOSS EAP 

いずれのコンテナもマイナーバージョンを固定できますが、自動更新にしておいたほうが良いでしょう。

Windows の場合は、JBOSS EAPが 使えなくなります。

色々と細かい選択肢があるので、デプロイするアプリケーションによって構成を変更する必要があるでしょう。

## Mavenプラグイン

タグの説明は、DocsやGithubで説明されています。

* [azure-maven-plugins/README.md at develop · microsoft/azure-maven-plugins](https://github.com/microsoft/azure-maven-plugins/blob/develop/azure-webapp-maven-plugin/README.md)
* [Maven Plugin for Azure App Service | Microsoft Docs](https://docs.microsoft.com/ja-jp/java/api/overview/azure/maven/azure-webapp-maven-plugin/readme?view=azure-java-stable)


今回はAzure CLIで認証しましたが、他にも色々な方法がかかれていますので、細かい話はGithubを見るとよいでしょう。

# まとめ

Mavenプラグインをを使えばWebApps向けのパッケージングとデプロイまで簡単にやってくれます。Azure DevopsでMavenタスクも書けるので実際のデプロイにもつかえるでしょう。そのときは、pom.xml にリソースはべた書きせずに環境変数にで追い出してください。