😀

Azure Functions 内に含まれるファイルを .NET から読み込む検証をやってみた

に公開

Azure Functions の環境変数に外出しでも良いのですが、情報量が多い場合プログラム本体とは別ファイルにしておきたくなります。そこで今回は、Azure Functions 内に含まれるファイルを .NET から読み込む検証をやってみました。

検証用 Azure Functions を作成

bash
func init test --dotnet

cd test

func new --name test --template HttpTrigger --authlevel anonymous

func start

Azure Functions にテキストファイルを含める

bash
echo sometext > test.txt

code test.csproj
変更前の test.csproj
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>
変更後の test.csproj
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
    <None Update="test.txt">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

ファイルが含まれる事を確認

bash
func start

cat bin/output/test.txt

Azure Functions コードを変更

変更前の test.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

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

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}
変更後の test.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace test
{
    public static class test
    {
        [FunctionName("test")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log, ExecutionContext context)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string test = File.ReadAllTextAsync(Path.Combine(context.FunctionAppDirectory, "test.txt")).Result;
            string responseMessage = $"test\n{test}";

            return new OkObjectResult(responseMessage);
        }
    }
}

ローカルで動作確認

bash
func start

Azure に検証環境を構築

bash
prefix=mnrdn
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az storage account create \
  --name ${prefix}stor \
  --resource-group ${prefix}-rg \
  --sku Standard_LRS

az functionapp create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --consumption-plan-location $region \
  --runtime dotnet \
  --runtime-version 6 \
  --functions-version 4 \
  --storage-account ${prefix}stor \
  --disable-app-insights \
  --https-only \
  --os-type Linux

func azure functionapp publish ${prefix}

Azure で動作検証

bash
curl https://${prefix}.azurewebsites.net/api/test

後片付け

bash
az group delete \
  --name ${prefix}-rg \
  --yes

参考

https://github.com/Azure/azure-functions-host/wiki/Retrieving-information-about-the-currently-running-function

Discussion