AzureにWebアプリをデプロイする

# はじめに
Azureについての学習の一環として、Azure App ServiceにローカルGitを用いてWebアプリをデプロイしてみました。その手順を振り返りを兼ねてまとめてみます。

手順にはApp Service以外のリソース作成も入っていますので、App ServiceへのWebアプリのデプロイのみ確認したい場合は[手順２](#手順２ローカルgit経由でのwebアプリのデプロイ)より読み進めてください。

# 前提
デプロイにローカルGitを用いているので、事前にGitをインストールしておく必要があります。
 
 # システム構成
今回、構成としては以下を目指し構築を行いました。
![スクリーンショット 2024-09-26 161447.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/3ffc8b4d-b3c0-a076-e689-272137d9474d.png)

# アプリ概要
本記事ではWebアプリ自体のプログラミングには触れませんが、機能としてはBlob Storageに格納されているファイル名の一覧を表示するといったアプリケーションになっています。

# 手順１（リソースの作成）
### 仮想ネットワーク及びサブネットの作成
1. Azure Potalから仮想ネットワークに移動します<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/ee102667-1bb5-5cc2-6c4b-a5b673d282b6.png)

    <br>
2. [作成]を選択します<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/e88de456-4d34-75ee-d17c-c8c3dc371f39.png)

    <br>
3. 必要情報を入力し、[作成]を選択します<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/ae9b5081-6f68-92fd-a00f-c75981826963.png)

    今回は以下のように入力しました。
    仮想ネットワーク名等、各リソースの命名は任意ですが、リソース名の省略形を入れるとわかりやすくなると思われます。
    リソース名の省略形についてはMicrosoftが出しているドキュメントをご覧ください。
    [Azure リソースの省略形の例](https://learn.microsoft.com/ja-jp/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)

    - 基本
      - サブスクリプション：任意
      - リソースグループ：任意
      - 仮想ネットワーク名：任意
      - 地域：(Asia Pacific) Japan East
    - セキュリティ
      -  仮想ネットワークの暗号化：チェックなし
      -  Azure Bastion を有効にする：チェックなし
      -  Azure Firewall を有効にする：チェックなし
      -  Azure DDoS Network Protection を有効にする：チェックなし
    - IPアドレス
      - IPv4アドレス空間：10.0.1.0/26
      - サブネット（App ServiceのVNet統合用）
        - サブネットの目的：Default
        - 名前：任意
        - IPv4
          -  IPv4 アドレス空間を含める：チェック
          -  IPv4 アドレスの範囲：10.0.1.0/26
          -  開始アドレス：10.0.1.0
          -  サイズ：/27 (32 個のアドレス)
      - サブネット（プライベートエンドポイント用）
        - サブネットの目的：Default
        - 名前：任意
        - IPv4
          -  IPv4 アドレス空間を含める：チェック
          -  IPv4 アドレスの範囲：10.0.1.0/26
          -  開始アドレス：10.0.1.32
          -  サイズ：/28 (16 個のアドレス)
    - タグ
      - 名前：（空欄）
      - 値：（空欄）

### App Serviceの作成
1. Azure PotalからApp Serviceに移動します(仮想ネットワークとほぼ同様な操作のため画像は省略します)
    <br>
2. [作成]→［Web アプリ］を選択します
    <br>
3. 必要情報を入力し、[作成]します
    今回は以下のように入力しました
    
    - 基本
      - サブスクリプション：任意
      - リソースグループ：任意
      - 名前：任意
      - 一意の既定のホスト名(プレビュー)をお試しください：オフ
      - 公開：コード
      - ランタイムスタック：Node 20 LTS
      - オペレーティングシステム：Linux
      - 地域：Japan East
      - Linuxプラン(Japan East)：任意の名前で新規作成
      - 価格プラン：Basic B1
      - ゾーン冗長：無効
    - データーベース
      - データーベースの作成：チェックなし
    - デプロイ
      - 継続的デプロイ：無効化
      - 基本認証：無効にする
    - ネットワーク
      - パブリック アクセスを有効にする：オフ　
        ※後にアクセス制限設定で個別に設定します。最終的には特定のIPアドレスからのパブリックアクセスを有効にしますが、この段階ではオフにしておくことでアクセス制限設定をかけるまでの間に特定のIPアドレス以外からのアクセスを防ぐことができます
      - ネットワーク インジェクションを有効にする：オン
      - 仮想ネットワーク：<上記で設定した仮想ネットワークを選択>
      - プライベートエンドポイントの有効化：オフ
      - VNet 統合を有効にする：オン
      - 送信サブネット：<上記で設定したVNet統合用サブネットを選択>
    - 監視とセキュリティ保護
      -  Application Insights を有効にする：いいえ
    - タグ
      - 名前：（空欄）
      - 値：（空欄）

### App Serviceのアクセス制限
1. Azure potalからApp Serviceに移動し、上記で作成したApp Serviceを選択します
    <br>
2. ［設定］＞［ネットワーク］から公衆ネットワークアクセス横の『無効』をクリックします<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/50f2260e-400f-d469-8791-c83f1ec9bc31.png) 

    <br>
3. 必要事項を入力し、保存します<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/fc40b2a3-7294-7a14-07c3-52edb3d83e44.png)

    今回は以下のように入力しました
    - アプリのアクセス
      - 公衆ネットワークアクセス：選択した仮想ネットワークとIPアドレスからのパブリックアクセスを有効
    - サイトのアクセスとルール
      - 一致しないルールのアクション：拒否
    - 規則の追加（ [＋追加] を選択し必要事項を入力後 [規則の追加] を選択）
      -  名前：任意
      -  アクション：許可
      -  優先度：300
      -  説明：（空欄）
      -  ソースの設定
         - 種類：IPv4
         - IPアクセスブロック：<アクセス許可したいIPアドレス> 
      - HTTP ヘッダーのフィルター設定：すべて空欄

### ストレージアカウント作成
1. Azure Potalからストレージアカウントに移動します
    <br>
2. [作成]を選択します
    <br>
3. 必要情報を入力し、[作成]を選択します
    今回は以下のように入力しました
    <br>
    - 基本
      - サブスクリプション：任意
      - リソースグループ：任意
      - ストレージアカウント名：任意
        ※仮想ネットワークやApp Serviceに比べ命名の制限事項が多いです。ハイフンなど記号は使用できず、小文字と数字かつ3-24文字で指定する必要があります
      - 地域：(Asia Pacific) Japan East
      - プライマリサービス：（未設定）
      - パフォーマンス：Standard
      - 冗長性：LRS
    - 詳細
      -  REST API操作の安全な転送を必須にする：チェックあり
      -  個々のコンテナーでの匿名アクセスの有効化を許可する：チェックなし
      -  ストレージアカウントキーへのアクセスを有効にする：チェックあり
      -  Azure portalでMicrosoft Entra 許可を規定にする：チェックなし
      -  TLSの最小バージョン：バージョン1.2
      -  コピー操作の許可されるスコープ：任意のストレージアカウントから
      -  階層型名前空間を有効にする：チェックなし
      -  SFTPを有効にする：チェックなし
      -  ネットワークファイルシステムv3を有効にする：チェックなし
      -  クロステナントレプリケーションを許可する：チェックなし
      -  アクセス層：ホット
      -  大きいファイルの共有を有効にする：チェックあり
    - ネットワーク
      - ネットワーク アクセス：選択した仮想ネットワークとIPアドレスからのパブリックアクセスを有効 
      - 仮想ネットワーク：（未設定）
      - IPアドレス：<アクセス許可したいIPアドレス>
      - プライベートエンドポイント：（未設定）
        ※プライベートエンドポイントは個別に作成するのでここでは作成しません
      - ルーティングの優先順位：Microsoftネットワークルーティング
    - データ保護
      -全項目：チェックなし  
    - 暗号化
      - 暗号化の種類：Microsoftマネージドキー(MMK)
      - カスタマーマネージドキーのサポートを有効にする：BLOBとファイルのみ
      - インフラストラクチャ暗号化を有効にする：チェックなし
    - タグ
      - 名前：（空欄）
      - 値：（空欄）


### コンテナー作成
1. Azure Potalからストレージアカウントに移動し、作成したストレージアカウントを選択します
    <br>
2. [データストレージ]>[コンテナ]を選択し、［＋コンテナー］を選択します
    <br>
3. 任意の名前を付け、[作成]を選択します。今回はfilesというコンテナーを作成しました<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/0494bb2b-33ce-cf72-8e66-8305a081c1be.png)
    <br>
4. 作成したコンテナーを選択し、[アップロード]から任意のファイルをアップしておきます。今回はfruits.txtというテキストファイルをアップしました<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/0fc762d5-4c77-d077-39b9-d8d9c02ec93f.png)

### App Serviceの環境変数設定
App Serviceがストレージアカウントにアクセスできるように環境変数を指定しておきます
1. Azure Potalからストレージアカウントに移動し、作成したストレージアカウントを選択します
    <br>
2. [セキュリティとネットワーク]>[アクセスキー]より、キーの一つを控えておきます
    <br>
3. App Serviceへ移動し、作成したApp Serviceを選択します
    <br>
4. [設定]>[環境変数] にてWebアプリのプログラムで指定した任意の名前の環境変数を設定します
今回はストレージアカウントのアクセスキー、ストレージアカウント名、コンテナー名を設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/40f7879f-6f16-2c6e-b117-20bf8a1eaaa2.png)


### プライベートエンドポイントの作成
1. Azure Potalからプライベートエンドポイントに移動します
    <br>
2. 作成を選択します
    <br>
3. 必要情報を入力し、[作成]します
    今回は以下のように入力しました

    - 基本
      - サブスクリプション：任意
      - リソースグループ：任意
      - 名前：任意
      - ネットワークインターフェース名：任意
      - 地域：Japan East
    - リソース
      - 接続方法：マイディレクトリ内のAzureリソースに接続します
      - サブスクリプション：任意
      - リソースの種類：Microsoft.Storage/storageAccounts
      - リソース：<上記で作成したストレージアカウント>
      - 対象サブリソース：blob
    - 仮想ネットワーク
      - 仮想ネットワーク：＜上記で作成した仮想ネットワーク＞
      - サブネット：＜上記で作成したプライベートエンドポイント用のサブネット＞
      - プライベートエンドポイントのネットワークポリシー：無効
      - プライベートIP構成：IPアドレスを動的に割り当てる
      - アプリケーションセキュリティグループ：（空欄）
    - DNS
      - プライベートDNS統合と統合する：はい
      - サブスクリプション：任意
      - リソースグループ：任意
    - タグ
      - 名前：（空欄）
      - 値：（空欄）
    <br>
    以上でリソース作成は終了です


# 手順２（ローカルGit経由でのWebアプリのデプロイ）
ここからはGitを用いたWebアプリのデプロイに移ります。
1. 作成したApp Serviceにて[デプロイ]>[デプロイセンター]を選択し、ソースを『ローカルGit』に設定し、保存します。保存後、Git Clone URIが表示されるのでメモ等に控えておきます<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/616f7062-03b0-6cca-bc1f-0c58853d803a.png)

    :::note info
    ここでSCM及びFTP基本認証がオフになっていると注意が表示された場合は [設定]>[構成]からSCM基本認証の発行資格情報とFTP基本認証の発行資格情報をオンにしてください
        :::
    <br>
2. ［デプロイセンター］上部にある［ローカルGitまたはFTPSの資格情報］を選択し、ユーザースコープの項目で任意のユーザー名、パスワードを入力し、保存します。ユーザー名とパスワードは控えておきます
    <br>
3. Git Bashを開き、任意のディレクトリでWebアプリのリモートリポジトリをgit cloneし、ローカルにもってきます
    ```
      git clone <GitHub URL>
    ```
    :::note info
    Webアプリの準備がない場合はMicrosoftが提供している[サンプル](https://learn.microsoft.com/ja-jp/azure/app-service/deploy-local-git?tabs=cli)を使用することもできます
        :::
    <br>
4. クローンしてきたWebアプリのルートディレクトリに移動し、先ほど控えたGit Clone URIを用いてAzureのリモートリポジトリを追加します
    ```
      git remote add azure <Git Clone URI>
    ```
    <br>
5. 以下のコードを入力し、Azureのリモートリポジトリにプッシュします。ここではGitリポジトリがmainとなっているのに対し、デプロイ先はmasterであるため、明示的にデプロイしています
    ```
    git push azure main:master
    ```
    <br>
6. ユーザー名とパスワードが聞かれるので、控えていたものを使用します
    <br> 
7. Azure Potalに戻り、作成したApp Serviceの概要から既定のドメインの欄に表示されているURLよりWebアプリを確認し、デプロイは終了です<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893228/45d36966-a354-d10b-3ff6-0e3593c911f0.png)
ストレージに格納していたファイル名が無事表示されました！

## 参考資料
[Azure App Service へのローカル Git デプロイ](https://learn.microsoft.com/ja-jp/azure/app-service/deploy-local-git?tabs=cli)