しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure App Service の .NET 6 Early Access と Azure Functions v4 の Early Preview が開始

相変わらず Build 2021 といった大型イベントと関係なくアップデートが行われる App Service と Azure Functions ですが、以前にブログで予告されていた通り夏前に .NET 6 Preview 4 と Azure Functions v4 の Early Preview が開始されました。

App Service としては .NET 6 Preview 4 の Early Access が全てのパブリックリージョンで開始され、Azure Functions は .NET 6 Preview 4 に対応した v4 Runtime が公開されたという話になります。従って Azure Functions v4 には .NET 6 の Early Access が必要です。

.NET 6 Preview 4 on App Service

既に .NET 6 Preview 4 の Early Access は Windows / Linux 両方で利用可能になっています。App Service チームのブログに書いてあるようにプレリリース版が利用可能になったのは確かに今回が初めてだと思います。

App Service の Early Access に関しては .NET 5 と同じなので、以前書いたエントリを参照してください。

有効化は Azure Portal などから .NET バージョンを 6 にするだけで終わります。.NET 6 は GA された後は LTS になるはずなので、将来的には LTS ラベルも付くはずです。

f:id:shiba-yan:20210610210229p:plain

設定保存して暫く待てば .NET 6 Preview 4 のインストールが完了して使えるようになります。

f:id:shiba-yan:20210610210323p:plain

Early Access 中は App Service がホストされている VM に対して JIT で該当のランタイムがインストールされるので、コールドスタートには多少時間がかかる点にだけは注意が必要です。

Azure Functions v4 (.NET 6)

App Service の .NET 6 Early Access は実際のところ Azure Functions v4 のためという感じしかしないので、Azure Functions に関してはしっかりと Azure へデプロイまで行って確認しておきました。

公式アナウンスや GitHub Wiki にもあるように、現時点では Azure Functions Core Tools を使った CLI ベースでのローカル実行と、Windows の Azure Functions へのデプロイがサポートされています。Linux 向けにはイメージがまだ公開されていませんでした。*1

In-Process の Azure Functions v4 を使う限りは、ランタイムが .NET Core 3.1 から .NET 6 になるぐらいで、今のところは大きな変更点は無さそうです。予め .NET 6 Preview 4 のインストールを行った上で、npm で Core Tools v4 をインストールすれば開発可能になります。

Core Tools v4 のインストール後に func を実行すれば 4.0.0.x になっていることが確認できます。

f:id:shiba-yan:20210610205710p:plain

そのまま func new を実行して Azure Functions のプロジェクトを作成すれば、自動的に .NET 6 向けで作成されますが AzureFunctionsVersion が何故か v3 のままになったので手動で v4 に直しておきました。

ついでに Azure Functions SDK も最新に更新すると以下のようなプロジェクトになります。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.13" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

現時点の Azure Functions SDK はビルド時に .NET Core 3.1 を要求するので、CI 環境などで .NET 6 Preview 4 のみ入っている場合にはエラーとなります。将来的には直るはずですが、現時点での制約となります。

Function の実装は実行環境が分かりやすいように FrameworkDescription を返すようにしました。

using System.Runtime.InteropServices;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            return new OkObjectResult($"Hello Azure Function v4! Running on {RuntimeInformation.FrameworkDescription}");
        }
    }
}

ここまで出来た状態で func start --build を実行すると v4 として起動します。ここでは省略していますが、HttpTrigger を実行するとちゃんと .NET 6 Preview 4 で動いていることが確認できます。

f:id:shiba-yan:20210610210737p:plain

ちなみに Visual Studio でもコードを書いてビルドするところまでは問題ないですが、デバッグ実行しようとすると該当のランタイムが見つからないというエラーになります。

f:id:shiba-yan:20210610211646p:plain

ローカル環境での動作確認は問題なかったので、そのまま Azure 上にデプロイして確認していきます。Azure Functions を Portal から新規作成する場合には、.NET バージョンとして 3.1 しか選べないため、とりあえずは 3.1 のまま作成しておきます。

Visual Studio からのデプロイは当然ながらまだ行えないので、Core Tools v4 を使ってデプロイを行います。この時に --force オプションを付けると、既存の Azure Functions のバージョンを適切なもので再設定してくれるので楽が出来ます。

func azure functionapp publish <FUNCTION_APP_NAME> --force

最初の実行例のように --force オプションを付けない場合は、ランタイムバージョンのミスマッチによってデプロイエラーとなりますが、オプションを付けた場合は netFrameworkVersion 自体も 6.0 で再設定されているのが分かります。

f:id:shiba-yan:20210610212542p:plain

初回のデプロイ時には Early Access によって .NET 6 Preview 4 が JIT インストールされるため少し時間がかかりますが、それ以降はこれまでぐらいの待ち時間でデプロイ可能です。

デプロイ完了後に表示された URL にアクセスすると HttpTrigger が実行できるので、Azure 上でも .NET 6 Preview 4 と Azure Functions v4 で動作していることが確認できました。

f:id:shiba-yan:20210610212706p:plain

この例では非常に単純な HttpTrigger でしたが、Azure Functions v3 で一番問題となっていた .NET 5 系のライブラリが使えない件については、代表的な Entity Framework Core を使って Azure へデプロイして確認をしたところ v4 では問題なく動作しました。

Azure Functions v4 でようやく Entity Framework Core 5.0 から追加された Many-to-Many サポートを使えるようになって嬉しいです。Azure Functions では .NET の LTS バージョンを待つのが正解な気がしています。

*1:ロードマップが公開された時点では Linux のが先にサポートされると書いてあった気もするが…