Azure Functions の PowerShell 開発者向けガイド

この記事では、PowerShell を使用して Azure Functions を作成する方法について詳しく説明します。

PowerShell Azure Functions (関数) は、トリガーされた時点で実行される PowerShell スクリプトとして表されます。 それぞれの関数スクリプトには、関連する function.json ファイルが存在し、関数の動作 (トリガー方法や入力および出力パラメーターなど) が定義されています。 詳細については、トリガーとバインディングに関する記事を参照してください。

他の種類の関数と同様、PowerShell スクリプト関数も、function.json ファイルで定義されているすべての入力バインディングの名前に対応したパラメーターを受け入れます。 また、関数を開始したトリガーに関する追加情報を含む TriggerMetadata パラメーターも渡されます。

この記事では、「Azure Functions の開発者向けガイド」を既に読んでいることを前提としています。 また、Functions の PowerShell 向けクイックスタートで、初めての PowerShell 関数を作成しておく必要があります。

フォルダー構造

PowerShell プロジェクトに必要なフォルダー構造は次のようになります。 この既定値は変更可能です。 詳しくは、後の scriptFile に関するセクションをご覧ください。

PSFunctionApp
 | - MyFirstFunction
 | | - run.ps1
 | | - function.json
 | - MySecondFunction
 | | - run.ps1
 | | - function.json
 | - Modules
 | | - myFirstHelperModule
 | | | - myFirstHelperModule.psd1
 | | | - myFirstHelperModule.psm1
 | | - mySecondHelperModule
 | | | - mySecondHelperModule.psd1
 | | | - mySecondHelperModule.psm1
 | - local.settings.json
 | - host.json
 | - requirements.psd1
 | - profile.ps1
 | - extensions.csproj
 | - bin

プロジェクトのルートには、関数アプリの構成に使用できる共有 host.json ファイルがあります。 各関数には、独自のコード ファイル (.ps1) とバインディング構成ファイル (function.json) が含まれるフォルダーがあります。 function.json ファイルの親ディレクトリの名前は常に関数の名前です。

特定のバインディングには、extensions.csproj ファイルが必要になります。 Functions ランタイムのバージョン 2.x 以降に必要なバインド拡張機能は extensions.csproj ファイルで定義されており、実際のライブラリ ファイルは bin フォルダーにあります。 ローカルで開発する場合は、バインド拡張機能を登録する必要があります。 Azure portal 上で関数を開発するときに、この登録が実行されます。

PowerShell 関数アプリには、必要に応じて profile.ps1 を含めることができます。これは、関数アプリの実行開始時 ("コールド スタート" とも呼ばれます) に実行されます。 詳細については、「PowerShell プロファイル」を参照してください。

PowerShell スクリプトを関数として定義する

既定では、Functions ランタイムは run.ps1 で関数を検索します。run.ps1 は、対応する function.json と同じ親ディレクトリを共有します。

スクリプトは、実行時に多数の引数が渡されます。 それらのパラメーターを処理するには、次の例のように、スクリプトの先頭に param ブロックを追加します。

# $TriggerMetadata is optional here. If you don't need it, you can safely remove it from the param block
param($MyFirstInputBinding, $MySecondInputBinding, $TriggerMetadata)

TriggerMetadata パラメーター

TriggerMetadata パラメーターは、トリガーに関する追加情報を指定するために使用されます。 追加のメタデータはバインディングによって異なりますが、いずれにも、次のデータが格納される sys プロパティが含まれています。

$TriggerMetadata.sys
プロパティ 説明 Type
UtcNow 関数がトリガーされた日時 (UTC) DateTime
MethodName トリガーされた関数の名前 string
RandGuid この関数の実行に対して一意の GUID string

トリガーの種類ごとに、異なる一連のメタデータがあります。 たとえば、QueueTrigger$TriggerMetadata には、数ある中でも InsertionTimeIdDequeueCount が格納されます。 キュー トリガーのメタデータの詳細については、キュー トリガーの公式ドキュメントを参照してください。 実際に使用しているトリガーのドキュメントを確認すると、そのトリガーのメタデータに含まれるものがわかります。

バインド

PowerShell では、バインディングの構成と定義が関数の function.json に記述されます。 関数は、さまざまな方法でバインドを操作します。

トリガーと入力データの読み取り

トリガーと入力バインディングは、関数に渡されたパラメーターとして読み取られます。 入力バインディングの direction は、function.json で in に設定されています。 function.json で定義された name プロパティは、param ブロックにおけるパラメーターの名前です。 PowerShell ではバインディングに名前付きパラメーターが使用されるため、パラメーターの順序は重要ではありません。 ただし、function.json で定義されているバインディングの順序に従うことをお勧めします。

param($MyFirstInputBinding, $MySecondInputBinding)

出力データの書き込み

Functions では、出力バインディングの direction が function.json で out に設定されています。 出力バインディングに書き込むには、Push-OutputBinding コマンドレットを使用します。このコマンドレットは、Functions ランタイムから利用できます。 どのような場合も、function.json で定義されたバインディングの name プロパティは、Push-OutputBinding コマンドレットの Name パラメーターに対応します。

関数スクリプトから Push-OutputBinding を呼び出す方法を次に示します。

param($MyFirstInputBinding, $MySecondInputBinding)

Push-OutputBinding -Name myQueue -Value $myValue

特定のバインディングの値をパイプラインを介して渡すこともできます。

param($MyFirstInputBinding, $MySecondInputBinding)

Produce-MyOutputValue | Push-OutputBinding -Name myQueue

Push-OutputBinding の動作は、-Name に指定された値に応じて異なります。

  • 指定された名前を有効な出力バインディングに解決できない場合は、エラーがスローされます。

  • 出力バインディングが値のコレクションを受け入れると、Push-OutputBinding を繰り返し呼び出して複数の値をプッシュすることができます。

  • 出力バインディングがシングルトン値しか受け入れない場合は、2 回目に Push-OutputBinding を呼び出した時点でエラーが発生します。

Push-OutputBinding の構文

Push-OutputBinding の呼び出しに使用できる有効なパラメーターを次に示します。

名前 Type [位置] 説明
-Name String 1 設定する出力バインディングの名前。
-Value Object 2 設定する出力バインディングの値。パイプライン ByValue から受け取ります。
-Clobber SwitchParameter named (省略可能) 指定した場合は、指定した出力バインディングに対して値が強制的に設定されます。

以下の共通パラメーターもサポートされています。

  • Verbose
  • Debug
  • ErrorAction
  • ErrorVariable
  • WarningAction
  • WarningVariable
  • OutBuffer
  • PipelineVariable
  • OutVariable

詳細については、「About CommonParameters (共通パラメーターについて)」を参照してください。

Push-OutputBinding の例: HTTP 応答

HTTP トリガーは、response という名前の出力バインディングを使用して応答を返します。 次の例では、出力バインディング response に値 "output #1" が設定されます。

PS >Push-OutputBinding -Name response -Value ([HttpResponseContext]@{
    StatusCode = [System.Net.HttpStatusCode]::OK
    Body = "output #1"
})

出力先は HTTP ですが、シングルトン値しか受け入れないため、Push-OutputBinding が 2 回呼び出されると、エラーがスローされます。

PS >Push-OutputBinding -Name response -Value ([HttpResponseContext]@{
    StatusCode = [System.Net.HttpStatusCode]::OK
    Body = "output #2"
})

出力がシングルトン値しか受け入れない場合は、-Clobber パラメーターを使用すると、コレクションへの追加を試みる代わりに古い値をオーバーライドすることができます。 次の例では、既に値が追加されていることを前提としています。 -Clobber を使用することで、次の例からの応答では、既存の値がオーバーライドされ、"output #3" という値が返されます。

PS >Push-OutputBinding -Name response -Value ([HttpResponseContext]@{
    StatusCode = [System.Net.HttpStatusCode]::OK
    Body = "output #3"
}) -Clobber

Push-OutputBinding の例: キュー出力バインディング

Push-OutputBinding は、出力バインディング (Azure Queue storage 出力バインディングなど) にデータを送信するために使用されます。 次の例では、キューに書き込まれるメッセージの値は "output #1" です。

PS >Push-OutputBinding -Name outQueue -Value "output #1"

ストレージ キューの出力バインディングは、複数の出力値を受け入れます。 この場合、次の例を 1 つ目の例の後に呼び出すと、"output #1" と "output #2" の 2 つの項目を含むリストがキューに書き込まれます。

PS >Push-OutputBinding -Name outQueue -Value "output #2"

次の例は、前述の 2 つを呼び出した後に呼び出すと、さらに 2 つの値が出力コレクションに追加されます。

PS >Push-OutputBinding -Name outQueue -Value @("output #3", "output #4")

キューへの書き込み時には、メッセージに "output #1"、"output #2"、"output #3"、"output #4" という 4 つの値が格納されます。

Get-OutputBinding コマンドレット

出力バインディングに現在設定されている値を取得するには、Get-OutputBinding コマンドレットを使用できます。 このコマンドレットは、出力バインディングの名前とそれぞれに対応する値を含んだハッシュテーブルを取得します。

Get-OutputBinding を使用して現在のバインディング値を返す例を次に示します。

Get-OutputBinding
Name                           Value
----                           -----
MyQueue                        myData
MyOtherQueue                   myData

Get-OutputBinding にも -Name というパラメーターがあります。これを使用すると、次の例に示すように、返されたバインディングをフィルター処理することができます。

Get-OutputBinding -Name MyQ*
Name                           Value
----                           -----
MyQueue                        myData

Get-OutputBinding では、ワイルドカード (*) がサポートされます。

ログ記録

PowerShell 関数におけるログは、通常の PowerShell のログと同様に機能します。 各出力ストリームへの書き込みには、ログ コマンドレットを使用できます。 各コマンドレットは、Functions で使用されるログ レベルに対応します。

Functions のログ レベル ログ コマンドレット
エラー Write-Error
警告 Write-Warning
Information Write-Information
Write-Host
Write-Output
Information ログ レベルに書き込みます。
デバッグ Write-Debug
Trace Write-Progress
Write-Verbose

これらのコマンドレットに加え、パイプラインに書き込まれた内容はすべて Information ログ レベルにリダイレクトされ、PowerShell の既定の書式で表示されます。

重要

Write-Verbose または Write-Debug コマンドレットを使用するだけでは、詳細およびデバッグ レベルのログを表示するには不十分です。 ログ レベルのしきい値も構成して、実際に注目するログのレベルを宣言する必要があります。 詳細については、「関数アプリのログ レベルの構成」を参照してください。

関数アプリのログ レベルの構成

Azure Functions では、しきい値レベルを定義することで、関数によるログへの書き込み方法を簡単に制御することができます。 コンソールに書き込まれるすべてのトレースのしきい値を設定するには、host.json ファイルlogging.logLevel.default プロパティを使用します。 この設定は、関数アプリのすべての関数に適用されます。

次の例では、すべての関数の詳細ログが有効になるようしきい値を設定しますが、MyFunction という名前の関数についてはデバッグ ログが有効になるようしきい値を設定しています。

{
    "logging": {
        "logLevel": {
            "Function.MyFunction": "Debug",
            "default": "Trace"
        }
    }
}  

詳細については、host.json のリファレンスを参照してください。

ログの表示

Azure 内で実行されている関数アプリは、Application Insights を使用して監視することができます。 関数のログの表示とクエリについて詳しくは、「Azure Functions を監視する」をご覧ください。

開発のために関数アプリをローカルで実行している場合、ログの既定の出力先はファイル システムとなります。 コンソールでログを確認するには、AZURE_FUNCTIONS_ENVIRONMENT 環境変数を Development に設定してから関数アプリを開始してください。

トリガーとバインディングの種類

関数アプリで使用できるトリガーとバインディングは多数あります。 トリガーとバインディングの全一覧は、こちらを参照してください

コード内では、すべてのトリガーとバインディングが、以下に示した少数の実数データ型として表現されます。

  • Hashtable
  • string
  • byte[]
  • INT
  • double
  • HttpRequestContext
  • HttpResponseContext

この一覧の最初の 5 つの型は、標準 .NET 型です。 最後の 2 つは、HttpTrigger トリガーのみで使用されます。

関数に含まれる各バインディング パラメーターは、これらの型のいずれかにする必要があります。

HTTP トリガーとバインディング

HTTP、webhook トリガー、および HTTP 出力バインディングでは、要求オブジェクトと応答オブジェクトを使用して HTTP メッセージングを表します。

要求オブジェクト

スクリプトに渡される要求オブジェクトは HttpRequestContext 型で、次のプロパティを持ちます。

プロパティ 説明 Type
Body 要求の本文を格納するオブジェクト。 Body は、データに基づいて最適な型にシリアル化されます。 たとえば、データが JSON である場合はハッシュテーブルとして渡されます。 データが文字列の場合は文字列として渡されます。 object
Headers 要求ヘッダーを格納するディクショナリ。 Dictionary<string,string>*
Method 要求の HTTP メソッド。 string
Params 要求のルーティング パラメーターを格納するオブジェクト。 Dictionary<string,string>*
Query クエリ パラメーターを格納するオブジェクト。 Dictionary<string,string>*
Url 要求の URL。 string

*Dictionary<string,string> のキーはすべて、大文字と小文字が区別されません。

応答オブジェクト

返すべき応答オブジェクトは HttpResponseContext 型で、次のプロパティを持ちます。

プロパティ 説明 Type
Body 応答の本文を格納するオブジェクト。 object
ContentType 応答のコンテンツ タイプを設定するための省略表現。 string
Headers 応答ヘッダーを格納するオブジェクト。 ディクショナリまたはハッシュテーブル
StatusCode 応答の HTTP 状態コード。 文字列または整数

要求と応答へのアクセス

HTTP トリガーを使用する場合、他の入力バインディングと同じ方法で HTTP 要求にアクセスできます。 これは param ブロックにあります。

応答を返すには、次に示すように、HttpResponseContext オブジェクトを使用します。

function.json

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "authLevel": "anonymous"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}

run.ps1

param($req, $TriggerMetadata)

$name = $req.Query.Name

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [System.Net.HttpStatusCode]::OK
    Body = "Hello $name!"
})

この関数を呼び出した結果は次のとおりです。

PS > irm http://localhost:5001?Name=Functions
Hello Functions!

トリガーとバインドの型キャスト

BLOB バインディングなど、いくつかのバインディングでは、パラメーターの型を指定できます。

たとえば、Blob Storage のデータを文字列として指定するには、param ブロックに次の型キャストを追加します。

param([string] $myBlob)

PowerShell プロファイル

PowerShell には、PowerShell プロファイルという概念があります。 PowerShell プロファイルに詳しくない場合は、「About profiles (プロファイルについて)」を参照してください。

PowerShell 関数では、プロファイル スクリプトは、最初のデプロイ時とアイドル状態からの復帰 (コールド スタート) 後にアプリの PowerShell worker インスタンスごとに 1 回実行されます。 PSWorkerInProcConcurrencyUpperBound 値を設定してコンカレンシーを有効にすると、作成された実行空間ごとにプロファイルスクリプトが実行されます。

Visual Studio Code や Azure Functions Core Tools などのツールを使用して関数アプリを作成すると、既定の profile.ps1 が自動的に作成されます。 既定のプロファイルは Core Tools GitHub リポジトリで保持されており、次の機能を備えています。

  • Azure に対する自動 MSI 認証。
  • 必要に応じて Azure PowerShell AzureRM PowerShell エイリアスを有効にする機能。

PowerShell のバージョン

次の表は、Functions ランタイムのメジャー バージョンと、それに必要な .NET バージョンごとに使用可能な PowerShell バージョンを示しています。

Functions バージョン PowerShell バージョン .NET バージョン
4.x PowerShell 7.2 .NET 6

現在のバージョンを確認するには、任意の関数から $PSVersionTable を出力します。

Azure Functions のランタイム サポート ポリシーの詳細については、こちらの記事を参照してください。

特定のバージョンでのローカルな実行

Azure Functions での PowerShell 7.0 のサポートは、2022 年 12 月 3 日に終了しました。 ローカルでの実行時に PowerShell 7.2 を使用するには、プロジェクト ルートにある local.setting.json ファイル内の Values 配列に設定 "FUNCTIONS_WORKER_RUNTIME_VERSION" : "7.2" を追加する必要があります。 PowerShell 7.2 を使用してローカルで実行する場合、local.settings.json ファイルは次の例のようになります。

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "powershell",
    "FUNCTIONS_WORKER_RUNTIME_VERSION" : "7.2"
  }
}

Note

PowerShell 関数では、FUNCTIONS_WORKER_RUNTIME_VERSION の値 "~7" は "7.0.x" を意味します。 "~7" の PowerShell 関数アプリは、"7.2" に自動的にアップグレードされません。 今後は、PowerShell 関数アプリの場合、対象とするメジャーとマイナーの両方のバージョンをアプリで指定することが必要になります。 したがって、"7.2.x" を対象にする場合は、"7.2" を指定する必要があります

PowerShell のバージョンの変更

Azure Functions での PowerShell 7.0 のサポートは、2022 年 12 月 3 日に終了しました。 関数アプリを PowerShell 7.2 にアップグレードするには、FUNCTIONS_EXTENSION_VERSION の値が ~4 に設定されていることを確認してください。 これを行う方法については、「現在のランタイム バージョンの表示と更新」を参照してください。

関数アプリで使用される PowerShell のバージョンを変更するには、次のステップに従います。 これは、Azure portal または PowerShell を使用して行うことができます。

  1. Azure portal で、関数アプリに移動します。

  2. [設定][構成] を選択します。 [全般設定] タブで、PowerShell のバージョンを探します。

    image

  3. 目的の PowerShell Core のバージョンを選択し、 [保存] を選択します。 再起動の保留に関する警告が表示されたら、 [続行] を選択します。 関数アプリは、選択した PowerShell のバージョンで再起動します。

構成に変更が加えられると、関数アプリが再起動します。

依存関係管理

Functions では、依存関係の管理に PowerShell ギャラリーを使用できます。 依存関係の管理を有効になっていると、.psd1 ファイルを使って、必要なモジュールが自動的にダウンロードされます。 この動作を有効にするには、次の例のように、host.json ファイルのルートで managedDependency プロパティを true に設定します。

{
  "managedDependency": {
          "enabled": true
       }
}

新しい PowerShell 関数プロジェクトを作成すると、依存関係の管理が既定で有効になり、Az モジュールが組み込まれます。 現在サポートされているモジュールの最大数は 10 です。 サポートされている構文は、次の requirements.psd1 に示すように、MajorNumber.* または厳密なモジュール バージョンです。

@{
	Az = '1.*'
	SqlServer = '21.1.18147'
}

requirements.psd1 ファイルを更新すると、更新されたモジュールは、再起動後にインストールされます。

特定のバージョンをターゲットにする

requirements.psd1 ファイルで、モジュールの特定のバージョンをターゲットにすることが必要な場合があります。 たとえば、含まれている Az モジュールのものよりも古いバージョンの Az.Accounts を使用したい場合は、次の例に示すように、特定のバージョンをターゲットにする必要があります。

@{
	'Az.Accounts' = '1.9.5'
}

この場合、次の例のように、profile.ps1 ファイルの先頭に import ステートメントを追加する必要もあります。

Import-Module Az.Accounts -RequiredVersion '1.9.5'

このようにすると、関数の開始時に、古いほうのバージョンの Az.Account モジュールが最初に読み込まれます。

依存関係の管理に関する考慮事項

依存関係の管理を使用するときは、次の点を考慮してください。

  • 管理対象の依存関係では、モジュールをダウンロードするときに https://www.powershellgallery.com にアクセスする必要があります。 ローカルで実行する場合は、必要なファイアウォール規則を追加して、ランタイムがこの URL にアクセスできることを確認してください。

  • 現在、管理対象の依存関係では、対話形式、または Install-Module を呼び出すときに -AcceptLicense スイッチを指定する方法でライセンスを受け入れるモジュールをサポートしていません。

依存関係管理アプリの設定

次のアプリケーション設定を使用して、管理対象の依存関係をダウンロードしてインストールする方法を変更できます。

関数アプリ設定 既定値 説明
MDMaxBackgroundUpgradePeriod 7.00:00:00 (7 日) PowerShell 関数アプリのバックグラウンド更新期間を制御します。 詳細については、MDMaxBackgroundUpgradePeriod を参照してください。
MDNewSnapshotCheckPeriod 01:00:00 (1 時間) 管理対象の依存関係のアップグレードがインストールされているかどうかを各 PowerShell ワーカーが確認する頻度を指定します。 詳細については、MDNewSnapshotCheckPeriod を参照してください。
MDMinBackgroundUpgradePeriod 1.00:00:00 (1 日) 前回のアップグレード チェック後に次のアップグレード チェックが開始されるまでの期間。 詳細については、MDMinBackgroundUpgradePeriod を参照してください。

基本的に、アプリのアップグレードは MDMaxBackgroundUpgradePeriod 以内に開始され、アップグレード プロセスはほぼ MDNewSnapshotCheckPeriod 以内に完了します。

カスタム モジュール

Azure Functions で独自のカスタム モジュールを利用する方法は、PowerShell で利用する場合の通常の方法とは異なります。

ローカル コンピューターでは、モジュールは、$env:PSModulePath にあるグローバルに利用できるフォルダーのいずれかにインストールされます。 Azure で実行されているときは、お使いのマシンにインストールされたモジュールにアクセスできません。 つまり、PowerShell 関数アプリの $env:PSModulePath は、通常の PowerShell スクリプトの $env:PSModulePath とは異なります。

Functions では、PSModulePath に次の 2 つのパスが存在します。

  • 関数アプリのルートに存在する Modules フォルダー。
  • PowerShell 言語ワーカーによって制御される Modules フォルダーのパス。

関数アプリレベルの modules フォルダー

カスタム モジュールを使用するには、関数が依存しているモジュールを Modules フォルダーに置きます。 このフォルダーにあるモジュールは、自動的に Functions Runtime から利用できる状態になります。 関数アプリ内のどの関数でもこれらのモジュールを使用できます。

Note

requirements.psd1 ファイルで指定されているモジュールは、自動的にダウンロードされてパスに組み込まれるため、modules フォルダーに含める必要はありません。 これらは、ローカルでは $env:LOCALAPPDATA/AzureFunctions フォルダーに、クラウドで実行されるときは /data/ManagedDependencies フォルダーに格納されます。

カスタム モジュール機能を利用するには、関数アプリのルートに Modules フォルダーを作成します。 関数で使用したいモジュールをこの場所にコピーします。

mkdir ./Modules
Copy-Item -Path /mymodules/mycustommodule -Destination ./Modules -Recurse

Modules フォルダーでは、関数アプリのフォルダー構造が次のようになっている必要があります。

PSFunctionApp
 | - MyFunction
 | | - run.ps1
 | | - function.json
 | - Modules
 | | - MyCustomModule
 | | - MyOtherCustomModule
 | | - MySpecialModule.psm1
 | - local.settings.json
 | - host.json
 | - requirements.psd1

関数アプリを起動すると、PowerShell 言語ワーカーによりこの Modules フォルダーが $env:PSModulePath に追加されるため、通常の PowerShell スクリプトと同様に、モジュールの自動読み込みを利用できます。

言語ワーカー レベルの modules フォルダー

いくつかのモジュールは、PowerShell 言語ワーカーによってよく使用されます。 これらのモジュールは、PSModulePath の最後の位置で定義されます。

現在のモジュールの一覧は次のとおりです。

  • Microsoft.PowerShell.Archive: アーカイブ (.zip.nupkg など) に使用されるモジュール。
  • ThreadJob: PowerShell ジョブ API のスレッドベースの実装です。

既定では、Functions では、これらのモジュールの最新のバージョンが使用されます。 特定のバージョンを使用するには、関数アプリの Modules フォルダーにその特定のバージョンのモジュールを格納してください。

環境変数

Functions では、サービス接続文字列などのアプリ設定は、実行中に環境変数として公開されます。 次の例に示すように、これらの設定には $env:NAME_OF_ENV_VAR を使用してアクセスできます。

param($myTimer)

Write-Host "PowerShell timer trigger function ran! $(Get-Date)"
Write-Host $env:AzureWebJobsStorage
Write-Host $env:WEBSITE_SITE_NAME

関数アプリの設定は、いくつかの方法で追加、更新、削除できます。

関数アプリの設定に変更を加えるためには、関数アプリを再起動する必要があります。

ローカルで実行する場合、アプリ設定は local.settings.json プロジェクト ファイルから読み取られます。

コンカレンシー

既定では、Functions PowerShell ランタイムで一度に処理できる関数の呼び出しは 1 つだけです。 ただし、以下の状況では、このコンカレンシー レベルが十分でない場合があります。

  • 多数の呼び出しを同時に処理しようとした場合。
  • 他の関数を呼び出す関数が同じ関数アプリ内にある場合。

ワークロードの種類に応じて、いくつかのコンカレンシー モデルを調べることができます。

  • FUNCTIONS_WORKER_PROCESS_COUNT を増やします。 これにより、同じインスタンス内の複数のプロセスで関数の呼び出しを処理できますが、特定の CPU とメモリでオーバーヘッドが発生します。 一般に、I/O バインド関数は、このオーバーヘッドの影響を受けません。 CPU バインド関数の場合、影響が大きくなる可能性があります。

  • PSWorkerInProcConcurrencyUpperBound アプリの設定値を増やします。 これにより、同じプロセス内に複数の実行空間を作成できるため、CPU とメモリのオーバーヘッドが大幅に減少します。

この環境変数は、関数アプリのアプリ設定で設定します。

使い方によっては、Durable Functions によってスケーラビリティが大幅に向上する場合があります。 詳細については、Durable Functions のアプリケーション パターンに関する記事を参照してください。

Note

"使用可能な実行空間がないため、要求がキューに置かれています" という警告が表示される場合がありますが、これはエラーではありません。 このメッセージは、要求がキューに登録されていて、前の要求が完了したときに処理されることを通知するものです。

コンカレンシーの使用に関する注意点

PowerShell は、既定では "シングル スレッド" のスクリプト言語です。 ただし、同じプロセス内で複数の PowerShell 実行空間を使用することで、コンカレンシーを追加できます。 作成された実行空間の数、つまりワーカーごとの同時実行スレッドの数は、PSWorkerInProcConcurrencyUpperBound アプリケーション設定によって制限されます。 既定では、Functions ランタイムのバージョン 4.x では、実行空間の数は 1,000 に設定されています。 バージョン 3.x 以下では、実行空間の最大数は 1 に設定されています。 スループットは、選択したプランで使用可能な CPU とメモリの量によって影響を受けます。

開発者の入力の手間を軽減するために、Azure PowerShell では、"プロセスレベル" のコンテキストと状態が使用されています。 ただし、関数アプリでコンカレンシーを有効にし、状態の変更を伴うアクションを呼び出した場合は、最終的に競合状態に陥る可能性があります。 このような競合状態をデバッグするのは困難です。なぜなら、一方の呼び出しが特定の状態に依存しているのに、もう一方の呼び出しがその状態を変更したためです。

一部の操作にはかなりの時間がかかる可能性があるため、Azure PowerShell のコンカレンシーには非常に大きな価値があります。 しかし、実際に使用する場合には注意が必要です。 競合状態が発生していると思われる場合は、PSWorkerInProcConcurrencyUpperBound アプリ設定を 1 に設定し、代わりに、コンカレンシーに対して言語ワーカー プロセス レベルの分離を使用します。

関数の scriptFile を構成する

既定では、PowerShell 関数は run.ps1 から実行されます。これは、対応する function.json と同じ親ディレクトリを共有するファイルです。

function.jsonscriptFile プロパティを使用すると、次の例のようなフォルダー構造を取得できます。

FunctionApp
 | - host.json
 | - myFunction
 | | - function.json
 | - lib
 | | - PSFunction.ps1

この場合、myFunctionfunction.json には、実行するにあたってエクスポートされた関数のファイルを参照する scriptFile プロパティが含まれています。

{
  "scriptFile": "../lib/PSFunction.ps1",
  "bindings": [
    // ...
  ]
}

entryPoint を構成して PowerShell モジュールを使用する

この記事では、テンプレートによって生成される既定の run.ps1 スクリプト ファイル内の PowerShell 関数について説明してきました。 ただし、PowerShell モジュールには自作の関数を含めることもできます。 モジュールに含まれている特定の関数コードを参照するには、function.json 構成ファイル内の scriptFile フィールドと entryPoint フィールドを使用します。

この場合の entryPoint は、scriptFile で参照される PowerShell モジュール内の関数またはコマンドレットの名前です。

次のフォルダー構造を考えてみましょう。

FunctionApp
 | - host.json
 | - myFunction
 | | - function.json
 | - lib
 | | - PSFunction.psm1

この場合、PSFunction.psm1 の内容は次のとおりです。

function Invoke-PSTestFunc {
    param($InputBinding, $TriggerMetadata)

    Push-OutputBinding -Name OutputBinding -Value "output"
}

Export-ModuleMember -Function "Invoke-PSTestFunc"

この例の myFunction の構成には、PSFunction.psm1 (別のフォルダーにある PowerShell モジュール) を参照する scriptFile プロパティが含まれています。 entryPoint プロパティは、このモジュールのエントリ ポイントである Invoke-PSTestFunc 関数を参照します。

{
  "scriptFile": "../lib/PSFunction.psm1",
  "entryPoint": "Invoke-PSTestFunc",
  "bindings": [
    // ...
  ]
}

この構成では、run.ps1 の場合とまったく同じように Invoke-PSTestFunc が実行されます。

PowerShell 関数に関する注意点

PowerShell 関数を使用するときは、以下のセクションに記載されている事柄に注意してください。

コールド スタート

サーバーレス ホスティング モデルで Azure Functions を開発する際は、コールド スタートを避けて通ることはできません。 "コールド スタート" とは、関数アプリの実行が開始されて要求が処理されるまでにかかる時間のことを指します。 従量課金プランでは、非アクティブな期間中に関数アプリがシャットダウンされるため、コールド スタートの発生頻度が高くなります。

Install-Module を使用せずにモジュールをバンドルする

スクリプトは、呼び出しのたびに実行されます。 スクリプト内で Install-Module を使用することは避けてください。 その代わり、発行前に Save-Module を使用します。そうすれば、関数がモジュールをダウンロードする際に生じる無駄な時間をなくすことができます。 コールド スタートが関数に影響を及ぼす場合は、"常にオン" に設定された App Service プラン、または Premium プランに関数アプリをデプロイすることを検討してください。

次のステップ

詳細については、次のリソースを参照してください。