Azure Functions をwindows の IIS へ Deploy して動かす


はじめに

基本は この記事 にかいてるけど、オレも含めて一度は失敗してハマるから覚書する

それと、そんな必要あんの?と思うけど、functionsで処理が閉じていれば必要ないが、その向こう側に作成する予定の別APIを開発者がローカルで一気通貫テストしたいと要望あって、ここに行きついた

ただ、ひっくるめて、ソースもらってデバックするのが一番早いかもね

インストールするもの

  • ASP.Net Core Runtime
  • Hosting Bundle

の二つ

ダウンロードして、インストールする。

ダウンロードするもの

  • Functions.3.0.14191.zip

Functions.3.0.14191.zipをダウンロードした後、IISのサイトフォルダに解凍する
たとえば、こんな感じ

F:\WebApp\hosting
に解凍

正直、解凍するフォルダはどこでもよくて C:\Toolsなんて自分専用のツール格納群フォルダでもいいけど、あとでFunctionsをデプロイした後に、このフォルダの中にある Microsoft.Azure.WebJobs.Script.WebHost.exe へのパスを web.config ファイルへ記述する作業が出てくる。
その際に、絶対パスで記述する事になるが、後々面倒を起こす(開発者毎に設定する必要があって、たいてい一人くらいは動かないと手を挙げる人が出てくる)から、最初からWEBフォルダの中につっこんでおいて、web.config に相対パスで記述して配布すると、面倒が出なくていい。今回は web 用のフォルダに突っ込んでおく。

ちなみに、Microsoft.Azure.WebJobs.Script.WebHost.exe は

ここにあるけど、今どきのPCは 64bit なので、次のパスをメモ帳あたりにメモっておく

  • F:\WebApp\hosting\3.0.14191\64bit\Microsoft.Azure.WebJobs.Script.WebHost.exe

次に、ここに site フォルダ作成

site フォルダの中に次の空のフォルダを作成

  • CSharp
  • Java
  • Node
  • powershell
  • Python

各言語で作成した functions をここに配置するため。

次にローカルIISにデプロイしたい対象のFunctionsプロジェクトから、フォルダーにPublishする
たとえば、VisualStudioだと、発行ツール経由で、フォルダにPublishできる

今回、適当な httptrigger の get要求で文字返すAPIをC#で作った。
↑の中で作成した空フォルダの中では、CSharpフォルダへデプロイする

無事デプロイできた

host.json が設定ファイルになる。
各種設定があるなら、ここで編集して設定する。
たとえば、AzureWebJobsStorageみたいな設定のこと

web.config の作成

先ほどデプロイしたフォルダに web.config ファイルを新規作成

中身はコレをコピペで張り付け

web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- To customize the asp.net core module uncomment and edit the following section. 
  For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
  <system.webServer>
    <handlers>
      <remove name="aspNetCore" />
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="..\..\3.0.14191\64bit\Microsoft.Azure.WebJobs.Script.WebHost.exe" 
      arguments="" stdoutLogEnabled="false" startupTimeLimit="3600" 
      stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
    <httpProtocol>
      <customHeaders>
        <remove name="X-Powered-By" />
      </customHeaders>
    </httpProtocol>
    <security>
      <requestFiltering allowDoubleEscaping="true" removeServerHeader="true">
        <requestLimits maxQueryString="4096" maxUrl="8192" maxAllowedContentLength="104857600" />
      </requestFiltering>
    </security>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.0.2.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

aspNetCore の prosessPath がキモで、これがさっきメモ帳に退避した、Microsoft.Azure.WebJobs.Script.WebHost.exeへのパスになる。

開発者にフォルダ毎配ると面倒がないので、相対パスで記述できるようにした方がよいと思う。

windows IIS の設定

さっきのweb.config見るとわかるけど、InProcessで exe を動かすことになるので、アプリケーションプールには管理者権限が必要になる。

アプリケーションプールの追加

IISマネージャーを起動して、アプリケーションプールを右クリック、プールの追加を選択

名前はなんでもいいから適当につけて追加

作ったプールの詳細設定から、

プロセスモデルのIDをデフォルトのApplicationPoolIdentityから、...を元に

ビルトインアカウントをカスタムアカウントに変えて、

自分のローカルPCの管理者権限のあるユーザーに変更する

FunctionsはEXE経由で実行することになるから、IISの権限だと動かない

次に、Default WebSite を右クリックしてアプリケーションの追加

エイリアス名は適当に付けて、アプリケーションプールはさっき作成した管理者権限のあるプールを選択

物理パスは、さっき functions をデプロイして、web.configを配置したパスを指定

設定はこれで全て完了。

サイトもローカルIISにできた

URLは Azure Functions と同じで、api/xxx になる

補足

Functions の authLevel が anonymous 以外だと動かないと思うので、デプロイした フォルダの中にある function.json を直接編集して、anonymous にするとよい