Azure App Service のデプロイ スロットを試す

# 概要
Azure App Serviceのデプロイスロットを使用し、運用環境とステージング環境を使い分けられるようにする。以下の操作ができるようになることを目指す。

- デプロイスロットを使用した、固有ホスト名を持つアプリのデプロイ
- 運用環境とステージング環境のスワップ

# デプロイスロットとは
> デプロイ スロットは、固有のホスト名を持つライブ アプリです。 アプリのコンテンツと構成の要素は、運用スロットを含む 2 つのデプロイ スロットの間でスワップすることができます。

1つのApp Serviceに複数の環境をデプロイすることが出来る機能。これにより、本番環境のリソース上にステージング環境を配置することが出来る。

:::note warn
デプロイスロットを使用する場合は、使用しているApp Serviceプランのサービスレベルが Standard、Premium、または Isolatedである必要があります。
:::

参考：[MS Learn ステージング環境を設定する](https://learn.microsoft.com/ja-jp/azure/app-service/deploy-staging-slots?tabs=portal)

# デプロイスロットを使用してみる

## 準備

#### Azure上でApp Serviceの構築
まずはPremiumでリソースを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/ceacd9cd-df57-7a66-e027-87c6e926a8c7.png)

#### Nuxtアプリケーションのデプロイ
続いてローカル上でNuxtアプリケーションを作成、App Serviceにデプロイ

アクセスを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/5e442a5a-b5b0-ee49-4c42-f0d7d8e5e4fb.png)

## デプロイ スロットの作成

Azure Portalから[デプロイ スロット] > [追加]でスロット追加ドロワーを表示、
下記の項目を入力して作成

| 項目 | 説明 |
|:-:|:-:|
| Name | スロットを識別する名前。本スロット上のサイトはホスト末尾にNameが追加される。 |
| Clone settings from: | デプロイするソース。今回はオリジナルのソースをそのまま流用した。 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/034a4ba9-1f2e-09d1-bc25-1861ea0f0e5d.png)

作成後、スロット一覧に作成したステージング用デプロイが追加される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/2b420f33-b0ab-599e-bc93-041e0a4e1c80.png)

ステージング用デプロイを押下するとApp Serviceのリソースページが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/5e34b0e0-2486-04c4-87a2-9afc97ac5d71.png)

## ソースコードを一部修正しデプロイ

今回GitHub Actionsを使用し継続的デプロイの設定をしていたため、
本番用ワークフローを元にステージング用ワークフローを作成

<details><summary>ステージング用ワークフロー (長いため省略)</summary>

```yml: staging-deploy.yml
name: Build and deploy Node.js app to Azure Web App

on:
  push:
    branches:
      - staging # ステージングスロットにデプロイする用のブランチを指定
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: '20.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build
  
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: node-app
          path: .output
          include-hidden-files: true

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'staging' # デプロイ先をstagingに修正
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: node-app

      - name: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v3
        with:
          app-name: 'sample-app'
          slot-name: 'staging' # 同様にデプロイ先をstagingに修正
          package: .
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX }} # デプロイ先のprofileに修正
```
</details>

## 実際に表示されていることを確認

雑に作成したページがステージング用URLに表示されていることが確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/abfc60b3-6e89-bb73-3428-ac53a4018eb2.png)


# スワッピングをしてみる

### Portal操作 
Azure Portalのデプロイ スロットのページから[Swap]を選択し、ドロワーを表示
Sourceにステージング用スロットを、Targetに本番用スロットを設定し、[Start Swap]を押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/219cffbe-44f4-721d-f634-2fe6f5f7e494.png)

### 入れ替わっている事を確認

本番用のURLに雑ページが、ステージング用のURLにデフォルトページが表示されていることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072221/0ca61513-4da3-4a0f-f7e7-3337ed508b5c.png)

# まとめ
少し前まで検証用のサーバーとして別リソースを作成していたため、今回デプロイ スロットという便利な機能を知ることが出来て良かったです。
アプリケーション設定等も環境別に使い分けられそうなので、更に調べていきたいです。