IntelliJ IDEAで Spring Boot を Azure App Service (WebApps)へデプロイする

.NET Framework1.0 が世に出た時から仕事で C# を使っていますが、Java は15年ぐらい前に少し触った程度の私です。これから IntelliJ IDEA と Spring Boot を使ってあれこれ試していきたいと思います。どっちも初心者なので、突っかかったところを正直に書いていきたいと思います。

## 環境

- Window 11
- [IntelliJ IDEA Community Edition 2022.1.2](https://www.jetbrains.com/ja-jp/idea/download/#section=windows)
- [Microsoft Open JDK 17.0.3](https://docs.microsoft.com/ja-jp/java/openjdk/download)
- [Maven 3.8.3](https://maven.apache.org/index.html)

JDK と Maven にはPathを通してあり、環境変数 JAVA_HOME が設定済みです。
また、事前に Azure App Service を Linux で作成しています。

## Spring Initializr

まずは Spring Boot のひな形のプロジェクトをダウンロードします。Spring Initializr というWebサイトで様々なミドルウェアをセットアップする情報が pom.xml に記載された状態でダウンロードできます。

[Spring Initializr](https://start.spring.io/)

今回は Dependencies に Spring Web だけを入れています。 Artifact は FirstSpringWebApp という名前にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/1094b2e0-6867-e537-6138-b6a8b3272f22.png)

左下の GENERATE ボタンをクリックすると、Zipファイルをダウンロードすることができます。Zipファイルを Explorer の機能で解凍してもいいのですが、フォルダが余計に1つできてしまうので私は Explorer で Zipファイルの中に入って、直下のフォルダをコピーして管理したい場所へ貼り付けています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/69575cef-9efd-093c-495c-c96db6f5ae67.png)

## IntelliJ IDEA でプロジェクトを開く

プロジェクトとは Spring Initializr からダウンロードした Zip ファイルの中のフォルダを Local のどこかに貼り付けた、そのフォルダのことです。

IntelliJ を立ち上げて、開くをクリックしてプロジェクトを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/2a45a2e2-8069-ed98-946b-c71bc96bba05.png)

Javaのプロジェクトとして IntelliJ IDEA が認識しているとフォルダのアイコンが他と違うことがわかります。このアイコンの違いは覚えておいたほうがいいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/793b0330-2e66-e5a6-9d61-3870236e3ea7.png)

IntelliJ IDEA はプロジェクトの読み込みに少し時間がかかります。右下に色んな処理がされていることを示すプログレスバーが表示されている間は、大人しく待った方が良いみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/645c3431-a45d-85e1-555b-9d492080d8ad.png)

## Maven ウィンドウ

海外のエンジニアの人の動画を見ていて気付いたのですが、プロジェクトを IntelliJ IDEA で開くと自動的に pom.xml を読み込んで必要なミドルウェアをダウンロードしてくれますが、初めてプロジェクトを開いたときは念のため pom.xml の内容を再読み込みすると良いみたいです。

プログレスバーの表示が終わったら、 Maven ウィンドウを出しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/df6148ed-240b-72ae-a45d-8625bb09222a.png)

再読み込みボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/8a9e7d62-3012-f0e8-eafd-e67f17ab1f06.png)

## ローカルで実行

ひとまず何か表示させる実装して、ローカルで実行して問題がないことを確認します。まずは HelloController を Controller ディレクトリ配下に作成します。

src\main\java\com.example.FirstSpringWebApp を右クリックして、新規->Java クラスを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/6bb671df-b4f8-a378-c22b-6c8d2e7ed15c.png)

クラス名に controller.HelloController と入力します。このように入力すると、controller ディレクトリは自動的に作成されます。便利ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/6360bc15-830a-9977-bb91-6087c37a8d2b.png)

Git にファイルを追加しますか、と聞いてきますが、今回はキャンセルしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/319b14f6-2765-fd7b-0d05-4c859088c4f9.png)

HelloController が Controller ディレクトリの下に作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/efadca23-64c9-0d9d-73f7-1e13d8f0509d.png)

HelloControllerに文字列を返す実装をします。コントローラーを RestController アノテーションで修飾します。
クラス名の1行上に @RestController と入力していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/e2131214-dd92-a0af-9bff-de6cac25b687.png)


@RestController 、と入力していくと途中で「これを入力したいの？」と IntelliJ がコード補完をしようとしてくれます。この状態で Tab または Enter を押下すると、コード補完とともに import も書いてくれるのでとても便利です。私は Tab で選択するのが好みです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/7dc8e07e-0f6f-0779-f1b4-11348e6c3372.png)

```java:HelloController.java
package com.example.FirstSpringWebApp.controller;

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

@RestController
public class HelloController {
}

```

root へアクセスされたら "Hello Spring Boot!" という文字列を返却するように実装します。String 型を返却するメソッドを public で作成し、 GetMapping アノテーションで修飾します。 GetMapping は HTTP Get でアクセスされた時にだけ呼び出されることを定義するアノテーションで、引数に Path を設定します。ASP.NET Core でも HttpGet 属性で同じことができますね。

```java:HelloController.java
package com.example.FirstSpringWebApp.controller;

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

@RestController
public class HelloController {

    @GetMapping("/")
    public String hello() {
        return "Hello Spring Boot!";
    }
}
```

実行してみましょう。エントリポイントは src\main\java\com.example.FirstSpringWebApp 直下に既定で作成済みの FirstSpringWebAppApplication クラスにあります。これをダブルクリックして開いたら main メソッドの左側に緑色の三角が行番号のところに表示されているはずです。（三角が表示されるまで最初は数秒待つ必要がある）
クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/33ded8e6-9de5-a886-992e-0841790dbf12.png)

メニューが開くので、実行を選びましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/9f14b969-d437-9a98-c584-14878e9ebda5.png)

まず、ビルドが実行されます。一番下のビルドタブが自動的に開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/6b44c9c4-00ef-6c51-028c-a51063bfb76e.png)

ビルドが正常終了すると、今度は実行タブが自動的に開きます。
Spring のアスキーアートが表示された後に、Tomcat が Port 8080 で起動し、最後に FirstSpringWebAppApplication が開始されたことがログからわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/b5e965ae-90ff-91a1-c8ed-2ab741107e44.png)

ブラウザで http://localhot:8080 へアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/f2412a92-190f-0527-8af9-6aef7ebe6cce.png)

いいですね。

## Azure Toolkit for IntelliJ をセットアップ

Azure App Service へデプロイするには 様々な方法があります。Maven のプラグインを使う方法を一番見かける気がしますが、Azure の情報をpom.xml に設定する（される）必要があるため、私の好みではありません。チーム開発や本番運用後にどうするかはさておき、とりあえずデプロイして動きを確認したい場合は プラグインを使ってデプロイするのが一番簡単です。

IntelliJ IDEA から直接 Azure へデプロイするには Azure Toolkit for IntelliJ というプラグインをインストールします。

ファイル->設定をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/d414a716-8f77-91a3-3c99-c8a67327b714.png)

Marketplace にて Azure Toolkit for IntelliJ プラグインをインストールします。この図は既にインストール済みの状態です。Marketplace タブをクリックして Azure で検索するとすぐにヒットするはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/93f22eb2-13c8-e577-9a58-c5b25b3347c5.png)

## Azure App Service(WebApps)へデプロイ
ではデプロイしてみます。IntelliJ IDEA の一番左に Azure Explorer が見えていたらそれをクリックしてウィンドウを表示します。もし左に見えていなかったら表示 -> ツールウィンドウ-> Azure Explorer をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/968603e7-e8f9-e7a8-564d-6b4a2573bc72.png)

### Azure へログインする
初回はAzureにサインインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/6343c698-6b58-d017-786a-2221c34ae531.png)

ログインの方法がいくつか選択できます。Azure CLI を使っている場合は簡単です。選ぶだけで勝手にログインします。
もし使っていなかったら Device Login を選ぶといいでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/758ab705-6ba0-2b1a-6606-b25d83b17d56.png)

ログインに成功すると、アカウントに紐づくサブスクリプションを選択できるようになります。予め作っておいた App Service が存在するサブスクリプションを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/9777d6cd-9fc3-5971-1367-13858bbf8dc6.png)

### デプロイする

ここまで来たらもう Azure Explorer に用はありません。IntelliJ IDEA 画面の一番左、プロジェクトをクリックしてディレクトリ階層を再び表示させます。

プロジェクトの一番上のディレクトリを右クリックすると、メニューの一番下のあたりに Azure というメニューが追加されています。その中に Deploy to Azure Web Apps があるはずです。クリックしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/3f2768ea-03ec-382f-8d9b-c19e164d98b4.png)

デプロイする先を選択するダイアログが表示されます。予め作っておいた App Service を選択したら、実行ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/dc9cdfa7-cd6b-011d-bae0-e60eaeb554a5.png)

まずビルドが走ります。画面一番下の実行ウィンドウがアクティブになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/65c61967-db6c-b56a-b9e9-66ead5826b00.png)

ビルドが終わると、同じ実行ウィンドウ内で別タブが開いてデプロイプロセスが開始されることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/ef93f243-03f9-d708-b597-77a673f45942.png)

ブラウザで URL を開くと、デプロイされたことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/e333d7e7-6580-af32-ba2b-40ae7560bc74.png)
いいですね。

デプロイすると、実行構成に今デプロイした構成が追加され、選択状態になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/d3085224-1cd4-2d3f-84b0-49d558ecec51.png)

このままだと実行ボタンクリックで毎回デプロイしてしまうので、ローカル実行構成に戻しましょう。（上図だったら FirstSpringWebAppApplication がローカル実行の構成）

## どこにどうデプロイされた？

App Service on Linux は SSH で接続することができます。既定でドキュメントルートは ~/site/wwwroot なので覗いてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/883bb1dc-11c0-391f-3ed7-fbd54121ddee.png)

app.jar としてデプロイされていますね。

## まとめ・感想

プラグインを入れれば、クリック数回でデプロイできてしまいます。本当に簡単ですね。ぶっちゃけ C# の ASP.NET Core アプリを Visual Studio からデプロイするより簡単です。Spring Boot アプリを Azure App Service で試しにホスティングする時には是非使いましょう。