Azure App ServiceではFTPデプロイよりZipデプロイを使おう

こんにちは。神田です。
今回はApp ServiceのFTPデプロイとZipデプロイについて書いていきます。

App ServiceのFTPデプロイについて

App ServiceにはFTPデプロイが提供されており、
Azureポータルから[デプロイセンター] > [FTPS資格情報]にアクセスすることで、
FTPエンドポイントと認証情報が確認でき、WinSCPなどのクライアントを利用することで、
FTP接続ができます。

App ServiceのFTPS資格情報

また、[構成] > [全般設定] > [FTPの状態]で受け入れる接続の制限ができます。
既定では「すべて許可」になっており、「FTPSのみ」「無効」に変更できます。

App ServiceのFTPの状態

上記の手順でFTP接続し、アプリケーションを配置することで、
App Serviceへアプリケーションをデプロイすることができます。

WinSCPでApp ServiceにFTP接続した状態

App ServiceのFTPにはアクセス制限をかけることはできない

App Serviceには単純なIP制限や、App Serviceを仮想ネットワーク内に閉じ込めてしまうプライベートエンドポイントといった機能やサービスが用意されていますが、
これらの機能を用いても例えばオフィスやデプロイ用のサーバからのみFTPでアクセスできる、といった
アクセス元の制限はできません。

こちらの理由ですが、
App Serviceにアクセスした際、通常はフロントに配置されたロードバランサーを経由して、
アプリケーションが実行されているワーカーへとアクセスしますが、
FTPでのアクセス(とVisual StudioでのWebデプロイ)はフロントを経由せず、
パブリッシャーというロールを経由して、App Serviceにアタッチされたファイルサーバにアクセスします。
このようなアーキテクチャのため、App ServiceのFTPデプロイはパブリックIPによって提供され、
IP制限やプライベートエンドポイントを用いてもアクセス元の制御はできません。

参考 : Inside the Azure App Service Architecture
https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/february/azure-inside-the-azure-app-service-architecture

対応策

FTPは暗号化されない通信プロトコルであり、上記の通りアクセス元を制限することもできません。
また、FTPデプロイではアプリケーションのバージョン管理ができないといった欠点もあります。

Azure DevOps PipelineやGitHubを用いてデプロイを自動化してしまうのがイマ風ですが、
様々な制約によってデプロイは手動で行いたい、というケースもあるかと思います。

そのような場合は、Zipデプロイを利用することができます。

Zipデプロイについて

ZipデプロイはプロジェクトのZipアーカイブを作成し、
App Serviceの管理サイト(SCMサイト)にアップロードすることでデプロイする方法です。

こちらの場合、SCMサイトへのアクセスはIP制限やプライベートエンドポイントを用いて
仮想ネットワーク内に閉じ込めることができるのでセキュリティ面で優れています。

また、前回デプロイと比較して削除されたファイルやディレクトリを自動で削除してくれるので、
FTPよりもアプリケーションの整合性が失われる可能性が低いです。

デプロイ方法もGUIとAPIの2パターンが用意されています。
※Linux App serviceではAPIのみ

参考 : ZIP または WAR ファイルを使用した Azure App Service へのアプリのデプロイ
https://docs.microsoft.com/ja-jp/azure/app-service/deploy-zip#deploy-zip-file

参考 : Deploying from a zip file or url
https://github.com/projectkudu/kudu/wiki/Deploying-from-a-zip-file-or-url

Zipデプロイを実際に行う

Visual Studio 2019で.NET 5のWebアプリケーションを作成している場合の
Zipデプロイ手順を紹介します。

ローカルで作成したWebアプリケーション

まずは[パッケージマネージャコンソール]で下記コマンドを実行し、アプリを発行します。
下記コマンドは.NET 5での「フレームワークに依存する展開」の場合のコマンドです。
バージョンが違ったり、展開方法を「自己完結」にしたい場合はオプションを適宜変更してください。

参考 : .NET CLI を使用した .NET アプリの発行
https://docs.microsoft.com/ja-jp/dotnet/core/deploying/deploy-with-cli

dotnet publish -c Release -p:UseAppHost=false
Visual Studioでのアプリの発行

プロジェクト内の bin\Release\net5.0\publish にファイル一式が作成されるので、
下記コマンドを実行し、Zipアーカイブを作成します。

Compress-Archive -Path * -DestinationPath {ファイル名}.zip
PowerShellでのZipアーカイブの作成

AzureポータルからApp Serviceの[高度なツール]> [移動]を押下し、
SCMサイトに移動します。

App ServiceのSCMサイト

SCMサイトのURLの末尾に「/ZipDeployUI」を追記し、Zipデプロイ用のページに移動します。

SCMサイトのZipデプロイページ

先ほど作成したZipファイルをエクスプローラからドラッグして配置し、
デプロイが完了するまで待機します。

ブラウザでのZipデプロイ

ページ下部にデプロイの進捗状況が表示され、最後に「Deployment successful.」と表示されればデプロイ成功です。

デプロイの進捗状況

App Serviceにアクセスすると、アプリケーションがデプロイされています。

デプロイ完了後のApp Service

最後に

App ServiceでFTPデプロイを使ってるケースは少ないとは思いますが、
もし使っているのであればZipデプロイへの切り替えを検討するのがよいかと思います。

また、App Serviceの[FTPの状態]は[無効]にしておきましょう。