PowerShell Azure Functions をローカル環境でデバッグする
Azure Functions では、関数を PowerShell スクリプトとして開発することができます。
次の標準的な開発ツールを使用する PowerShell スクリプトと同様、PowerShell 関数をローカル環境でデバッグできます。
- Visual Studio Code:Microsoft の無料で軽量のオープンソース テキスト エディターであり、PowerShell の完全な開発エクスペリエンスを提供する PowerShell 拡張機能を備えています。
- PowerShell コンソール: 他の PowerShell プロセスのデバッグに使うものと同じコマンドを使ってデバッグします。
Azure Functions Core Tools では、PowerShell 関数を含む Azure Functions のローカル デバッグがサポートされています。
関数アプリの例
この記事で使う関数アプリには、1 つの HTTP によってトリガーされる関数と、次のファイルが含まれます。
PSFunctionApp
| - HttpTriggerFunction
| | - run.ps1
| | - function.json
| - local.settings.json
| - host.json
| - profile.ps1
この関数アプリは、PowerShell のクイックスタートを完了したときに作成されるものと似ています。
run.ps1
の関数のコードは、次のようなスクリプトです。
param($Request)
$name = $Request.Query.Name
if($name) {
$status = 200
$body = "Hello $name"
}
else {
$status = 400
$body = "Please pass a name on the query string or in the request body."
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $status
Body = $body
})
アタッチ ポイントを設定する
どのような PowerShell 関数でも、デバッグするには、デバッガーをアタッチするために停止する必要があります。 Wait-Debugger
コマンドレットは実行を停止して、デバッガーを待機します。
Note
PowerShell 7 を使用するとき、コードに Wait-Debugger
呼び出しを追加する必要はありません。
開発者が行う必要があるのは、次のように、if
ステートメントのすぐ上に Wait-Debugger
コマンドレットの呼び出しを追加することだけです。
param($Request)
$name = $Request.Query.Name
# This is where we will wait for the debugger to attach
Wait-Debugger
if($name) {
$status = 200
$body = "Hello $name"
}
# ...
if
ステートメントでデバッグが開始されます。
Wait-Debugger
を配置した後は、Visual Studio Code または PowerShell コンソールを使って関数をデバッグできます。
Visual Studio Code でのデバッグ
Visual Studio Code で PowerShell 関数をデバッグするには、以下がインストール済みである必要があります。
- Visual Studio Code 用 PowerShell 拡張機能
- Visual Studio Code 用 Azure Functions 拡張機能
- PowerShell Core 6.2 以降
これらの依存関係をインストールした後、既存の PowerShell 関数プロジェクトを読み込むか、Azure で初めての PowerShell 関数を作成します。
Note
プロジェクトに必要な構成ファイルがない場合は、追加を求めるメッセージが表示されます。
PowerShell のバージョンを設定する
PowerShell Core は、Windows PowerShell とサイドバイサイドでインストールされます。 Visual Studio Code 用 PowerShell 拡張機能を使用するには、PowerShell のバージョンとして Visual Studio Code を 設定します。
F1 キーを押してコマンド パレットを表示し、
Session
を検索します。[PowerShell:Show Session Menu]\(PowerShell: セッション メニューを表示\) をクリックします。
[現在のセッション] が [PowerShell Core 6] になっていない場合は、 [切り替え:PowerShell Core 6] を選択します。
PowerShell ファイルが開いている場合は、ウィンドウの右下に緑色で表示されているバージョンを確認します。 このテキストの選択でも、セッション メニューが表示されます。 詳細については、「拡張機能で使用する PowerShell のバージョンの選択」を参照してください。
関数アプリを開始する
デバッガーをアタッチしたい関数に、Wait-Debugger
を設定したことを確認します。 Wait-Debugger
を追加したら、Visual Studio Code を使って関数アプリをデバッグできます。
[デバッグ] ウィンドウを選択し、 [Attach to PowerShell function]\(PowerShell 関数にアタッチする\) を選択します。
F5 キーを押してデバッグを開始することもできます。
デバッグ開始操作では、次のタスクが行われます。
- ターミナルで
func extensions install
が実行され、関数アプリで必要なすべての Azure Functions 拡張機能がインストールされます。 - ターミナルで
func host start
が実行され、Functions ホストで関数アプリが起動されます。 - Functions ランタイム内の PowerShell 実行空間に、PowerShell デバッガーがアタッチされます。
Note
Visual Studio Code で正しいデバッグのエクスペリエンスを実現するには、PSWorkerInProcConcurrencyUpperBound が 1 に設定されていることを確認する必要があります。 これは既定値です。
関数アプリが実行されたら、別の PowerShell コンソールを開いて、HTTP によってトリガーされる関数を呼び出す必要があります。
この場合は、PowerShell コンソールがクライアントです。 関数をトリガーするには Invoke-RestMethod
を使います。
PowerShell コンソールで次のコマンドを実行します。
Invoke-RestMethod "http://localhost:7071/api/HttpTrigger?Name=Functions"
応答がすぐに返されないことがわかります。 これは、Wait-Debugger
でデバッガーがアタッチされていて、PowerShell の実行は可能になるとすぐに中断モードに移行したためです。 これは、後で説明する BreakAll の概念によるものです。 continue
ボタンをクリックした後、デバッガーは Wait-Debugger
の直後の行で中断しています。
この時点で、デバッガーがアタッチされ、デバッガーでの通常の操作をすべて行うことができます。 Visual Studio Code でのデバッガーの使用に関して詳しくは、公式ドキュメントをご覧ください。
続行してスクリプトを完全に呼び出すと、次のことがわかります。
Invoke-RestMethod
を行った PowerShell コンソールで、結果が返されています- Visual Studio Code の PowerShell 統合コンソールで、スクリプトの実行が待機されています
その後、同じ関数を呼び出すと、PowerShell 拡張機能のデバッガーは Wait-Debugger
の直後で中断します。
PowerShell コンソールでのデバッグ
Note
このセクションを読む前に、Azure Functions Core Tools のドキュメントを読み、func host start
コマンドを使って関数アプリを起動する方法を理解しておく必要があります。
コンソールを開き、関数アプリのディレクトリに cd
で移動して、次のコマンドを実行します。
func host start
関数アプリが実行され、Wait-Debugger
が配置されていると、プロセスにアタッチできます。 さらに 2 つの PowerShell コンソールが必要です。
コンソールの 1 つは、クライアントとして機能します。 ここから、Invoke-RestMethod
を呼び出して、関数をトリガーします。 たとえば、次のコマンドを実行できます。
Invoke-RestMethod "http://localhost:7071/api/HttpTrigger?Name=Functions"
応答が返されないことがわかります。これは Wait-Debugger
の結果です。 PowerShell の実行空間では、デバッガーがアタッチされることが待機されています。 それではアタッチしてみましょう。
他の PowerShell コンソールで次のコマンドを実行します。
Get-PSHostProcessInfo
このコマンドレットでは、次の出力のようなテーブルが返されます。
ProcessName ProcessId AppDomainName
----------- --------- -------------
dotnet 49988 None
pwsh 43796 None
pwsh 49970 None
pwsh 3533 None
pwsh 79544 None
pwsh 34881 None
pwsh 32071 None
pwsh 88785 None
テーブルで ProcessName
が dotnet
である項目の ProcessId
を書き留めておきます。 このプロセスが関数アプリです。
次に、以下のスニペットを実行します。
# This enters into the Azure Functions PowerShell process.
# Put your value of `ProcessId` here.
Enter-PSHostProcess -Id $ProcessId
# This triggers the debugger.
Debug-Runspace 1
開始されたデバッガーは中断し、次のような出力が表示されます。
Debugging Runspace: Runspace1
To end the debugging session type the 'Detach' command at the debugger prompt, or type 'Ctrl+C' otherwise.
At /Path/To/PSFunctionApp/HttpTriggerFunction/run.ps1:13 char:1
+ if($name) { ...
+ ~~~~~~~~~~~
[DBG]: [Process:49988]: [Runspace1]: PS /Path/To/PSFunctionApp>>
この時点では、PowerShell デバッガーのブレークポイントで停止しています。 ここからは、ステップ オーバー、ステップ イン、続行、終了など、通常のすべてのデバッグ操作を行うことができます。 コンソールで使用できるデバッグ コマンドの完全なセットを表示するには、h
または ?
コマンドを実行します。
Set-PSBreakpoint
コマンドレットを使って、このレベルでブレークポイントを設定することもできます。
続行してスクリプトを完全に呼び出すと、次のことがわかります。
Invoke-RestMethod
を実行した PowerShell コンソールに、結果が返されています。Debug-Runspace
を実行した PowerShell コンソールでは、スクリプトの実行が待機されています。
同じ関数をもう一度呼び出すことができ (たとえば、Invoke-RestMethod
を使って)、デバッガーは Wait-Debugger
コマンドの直後で中断されます。
デバッグに関する考慮事項
Functions のコードをデバッグするときは、次の問題に注意してください。
BreakAll
を使うと、デバッガーが予期しない場所で中断される可能性があります
PowerShell 拡張機能では Debug-Runspace
が使われており、それはさらに PowerShell の BreakAll
機能に依存しています。 この機能では、PowerShell は実行された最初のコマンドで停止するよう指示されます。 この動作により、デバッグ対象の実行空間内にブレークポイントを設定する機会ができます。
Azure Functions ランタイムでは、run.ps1
スクリプトが実際に呼び出される前にいくつかのコマンドが実行されるため、デバッガーが Microsoft.Azure.Functions.PowerShellWorker.psm1
または Microsoft.Azure.Functions.PowerShellWorker.psd1
の中で中断される可能性があります。
この中断が発生した場合は、continue
または c
コマンドを実行して、このブレークポイントをスキップします。 その後は、予期されるブレークポイントで停止します。
トラブルシューティング
デバッグ中に問題が発生した場合は、次の点を確認する必要があります。
○ | アクション |
---|---|
ターミナルから func --version を実行します。 func が見つからないというエラーが表示される場合は、ローカルの path 変数に Core Tools (func.exe) がない可能性があります。 |
Core Tools を再インストールします。 |
Visual Studio Code では、既定のターミナルが func.exe にアクセスできる必要があります。 Linux 用 Windows サブシステム (WSL) などの Core Tools がインストールされていない既定のターミナルを使用していないことを確認します。 | Visual Studio Code の既定のシェルを PowerShell 7 (推奨) または Windows PowerShell 5.1 に設定します。 |
次のステップ
PowerShell を使用した Functions の開発の詳細については、「Azure Functions PowerShell developer guide (Azure Functions PowerShell 開発者ガイド)」をご覧ください。