Azure Functions の機能である Durable Functions を使用して、サーバーレス環境でステートフル関数を記述します。 Durable Functions はアプリケーションの状態、チェックポイント、再起動を管理します。
Durable Functions では、オーケストレーションとエンティティのランタイム状態を格納するための複数の ストレージ プロバイダー ( バックエンドとも呼ばれます) がサポートされています。 このクイック スタートでは、Visual Studio Code を使用して Microsoft SQL Server (MSSQL) ストレージ プロバイダーを使用する Durable Functions アプリを作成します。
このクイック スタートでは、デモンストレーション用の .NET (分離モデル) アプリを作成します。 この記事で提供されるコンテンツは、同様の方法で他の言語に適用されます。
注
MSSQL バックエンドは、アプリケーションの移植性を最大化し、データを制御するように設計されています。 これは Microsoft SQL Server を使用してすべてのタスク ハブ データを保持し、ユーザーが最新のエンタープライズグレードのデータベース管理システム (DBMS) インフラストラクチャの利点を活用できるようにします。 MSSQL ストレージ プロバイダーを使用するべきタイミングの詳細については、「ストレージ プロバイダーの概要」を参照してください。
ストレージ プロバイダー間でのタスク ハブ データの移行は、現在サポートされていません。 既存のランタイム データを持つ関数アプリは、MSSQL バック エンドへの切り替え後、新しい空のタスク ハブから開始されます。 同様に、別のストレージ プロバイダーに切り替える場合は、MSSQL を使用して作成されたタスク ハブの内容を保持することはできません。
前提条件
このクイック スタートを完了するには、次のものが必要です。
Visual Studio Code がインストールされました。
Azure Functions Visual Studio Code 拡張機能 がインストールされています。
最新バージョンの Azure Functions Core Tools がインストールされていること。
.NET 8.0 SDK がインストールされています。
Docker がインストールされています。
データをセキュリティで保護する HTTP テスト ツール。 詳細については、「HTTP テスト ツール」を参照してください。
Azure Functions プロジェクトを作成する
Visual Studio Code で Azure Functions プロジェクトを作成します。
[表示] メニューで [コマンドパレット] を選択します (または Ctrl + Shift + P を選択します)。
プロンプトで (
>
)、入力して [Azure Functions: 新しいプロジェクトを作成する] を選択します。を選択し、を参照します。 [フォルダーの選択] ダイアログで、プロジェクトに使用するフォルダーに移動し、[選択] を選択します。
プロンプトで、次の値を選択または入力します。
プロンプト アクション 説明 関数アプリ プロジェクトの言語を選択してください .NET を選択する ローカルの C# Functions プロジェクトを作成します Select a .NET runtime (.NET ランタイムを選択してください) [.NET 8.0 (分離)] を選択します。 分離されたワーカー プロセスで実行される .NET 8 と Azure Functions Runtime 4.0 をサポートする Functions プロジェクトを作成します。 Select a template for your project's first function (プロジェクトの最初の関数のテンプレートを選択してください) [Durable Functions オーケストレーション トレース] を選択します。 Durable Functions オーケストレーションを作成します。 永続ストレージの種類を選択してください [MSSQL] を選択します。 MSSQL ストレージ プロバイダーを選択します。 Provide a function name (関数名を指定してください) 「HelloOrchestration」と入力します。 オーケストレーション関数の名前。 Provide a namespace (名前空間を指定してください) 「Company.Function」と入力します。 生成されるクラスの名前空間。 Select how you would like to open your project (プロジェクトを開く方法を選択してください) [Open in current window] (現在のウィンドウで開く) を選択します。 選択したフォルダーで Visual Studio Code を開きます。
Visual Studio Code により、Azure Functions Core Tools がインストールされます (プロジェクトの作成が必要な場合)。 また、関数アプリ プロジェクトがフォルダーに作成されます。 このプロジェクトには、host.json および local.settings.json 構成ファイルが含まれています。
HelloOrchestration.cs という別のファイルには、Durable Functions アプリの基本的な構成要素が含まれています。
メソッド | 説明 |
---|---|
HelloOrchestration |
Durable Functions アプリのオーケストレーションを定義します。 このケースでは、オーケストレーションが起動し、一覧が作成され、3 つの関数呼び出しの結果が一覧に追加されます。 3 つの関数呼び出しが完了すると、一覧が返されます。 |
SayHello |
hello を返す単純な関数アプリ。 この関数には、調整されたビジネス ロジックが含まれています。 |
HelloOrchestration_HttpStart |
オーケストレーションのインスタンスを開始し、チェック状態の応答を返す、HTTP によってトリガーされる関数。 |
Durable Functions について詳しくは、Durable Functions の種類と機能に関するページを参照してください。
データベースを設定する
注
MSSQL 互換データベースを既にお持ちの場合は、このセクションと Docker ベースのローカル データベースの設定に関する次のサブセクションはスキップして構いません。
MSSQL バックエンドは移植性を目的として設計されているため、バッキング データベースを設定するためのオプションがいくつかあります。 たとえば、オンプレミスの SQL Server インスタンスを設定したり、Azure SQL Database のフル マネージド インスタンスを使用したり、その他の SQL Server 互換ホスティングの選択肢を使用したりできます。
また、ローカルの Windows マシンで SQL Server Express を使用することでローカルのオフライン開発を行ったり、Docker コンテナー内で実行される SQL Server Docker イメージを使用したりすることもできます。
このクイックスタートでは、SQL Server Docker イメージの使用に焦点を当てます。
ローカルの Docker ベース SQL Server インスタンスを設定する
次の PowerShell コマンドを使用して、Docker でローカル SQL Server データベースを設定します。 PowerShell は、Windows、macOS、Linux にインストールできます。
# primary parameters
$pw = "yourStrong(!)Password"
$edition = "Developer"
$port = 1433
$tag = "2019-latest"
$dbname = "DurableDB"
$collation = "Latin1_General_100_BIN2_UTF8"
# pull the image from the Microsoft container registry
docker pull mcr.microsoft.com/mssql/server:$tag
# run the image and provide some basic setup parameters
docker run --name mssql-server -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$pw" -e "MSSQL_PID=$edition" -p ${port}:1433 -d mcr.microsoft.com/mssql/server:$tag
# wait a few seconds for the container to start...
# create the database with strict binary collation
docker exec -it mssql-server /opt/mssql-tools/bin/sqlcmd -S . -U sa -P "$pw" -Q "CREATE DATABASE [$dbname] COLLATE $collation"
# if sqlcmd is in the mssql-tools18 folder
# docker exec -it mssql-server /opt/mssql-tools18/bin/sqlcmd -C -S . -U sa -P "$pw" -Q "CREATE DATABASE [$dbname] COLLATE $collation"
これで、ローカル SQL Server が Docker で実行され、ポート 1443
でリッスンしている必要があります。 ポート 1443
が別のサービスと競合する場合は、変数 $port
を別の値に変更した後、これらのコマンドを再実行します。
データベースのインストールを検証するには、新しい SQL データベースに対してクエリを実行します。
docker exec -it mssql-server /opt/mssql-tools/bin/sqlcmd -S . -U sa -P "$pw" -Q "SELECT name FROM sys.databases"
データベースのセットアップが正常に完了している場合は、以下のようにコマンドライン出力にデータベースの名前 (たとえば、DurableDB など) が表示されます。
name
--------------------------------------------------------------
master
tempdb
model
msdb
DurableDB
注
実行中のコンテナーを停止および削除するには、それぞれ docker stop <containerName>
および docker rm <containerName>
を使用できます。 これらのコマンドを使用することで、コンテナーを再作成し、このクイックスタートを完了したときにコンテナーを停止できます。 さらにサポートが必要な場合は、docker --help
を実行してください。
トラブルシューティング
を実行してデータベースをdocker exec
するときに "デーモンからのエラー応答: OCI ランタイム exec が失敗しました" というエラーが発生した場合は、/opt/mssql-tools/bin/sqlcmd
フォルダーが存在しない可能性があります。 Docker Desktop を開き、SQL Server Docker コンテナーを選択し、[ファイル] を選択して mssql-tools フォルダーを参照します。 このフォルダーに別の名前 ( /opt/mssql-tools18/bin/sqlcmd
など) があるかどうかを確認します。 それに応じてコマンドを更新します。
ODBC Driver 18 for SQL Server では、暗号化接続オプションは既定で true に設定されています。 データベース操作を実行するために を実行した時に、docker exec
というエラーが発生した場合は、ADO.net オプション -C
と同等の TRUSTSERVERCERTIFICATE = true
を追加してください。
local.settings.json に SQL 接続文字列を追加する
MSSQL バックエンドには、データベースにアクセスするための接続文字列が必要です。 接続文字列を取得する方法は、ご利用の MSSQL サーバー プロバイダーによって大きく異なります。
上記の Docker コマンドをパラメーター変更なしで使用する場合、接続文字列は次のようになります。
Server=localhost,1433;Database=DurableDB;User Id=sa;Password=yourStrong(!)Password;
local.settings.jsonで、Docker ベースの SQL Server インスタンスの接続文字列をSQLDB_Connection
に割り当てます。 この変数は、Durable Functions アプリのバックエンドとして MSSQL を選択したときに Visual Studio Code によって追加されました。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"SQLDB_Connection": "Server=localhost,1433;Database=DurableDB;User Id=sa;Password=yourStrong(!)Password;",
"FUNCTIONS_WORKER_RUNTIME": "<dependent on your programming language>"
}
}
ローカルでテストする
アプリのルート フォルダーでターミナル ウィンドウを開き、 azurite start
実行します。 Azurite は、関数アプリを実行するために必要な Azure Storage エミュレーターです。
アプリのルート フォルダーで別のターミナル ウィンドウを開き、 func host start
を実行して Function アプリを起動します。
ターミナル ウィンドウで、HTTP によってトリガーされる関数の URL エンドポイントをコピーします。
HTTP テスト ツールを使用して URL エンドポイントに HTTP POST 要求を送信します。
応答は、HTTP 関数の最初の結果です。 これにより、Durable Functions オーケストレーションが正常に開始されたことがわかります。 オーケストレーションの最終的な結果はまだ表示されません。 応答には、いくつかの便利な URL が含まれています。
statusQueryGetUri
の URL 値をコピーし、それをブラウザーのアドレス バーに貼り付け、要求を実行します。 または、HTTP テスト ツールを引き続き使用して GET 要求を発行することもできます。この要求によって、オーケストレーション インスタンスの状態が照会されます。 次の例のように、インスタンスが完了し、Durable Functions アプリの出力または結果が内部に含まれていることを確認できます。
{ "name":"HelloCities", "instanceId":"7f99f9474a6641438e5c7169b7ecb3f2", "runtimeStatus":"Completed", "input":null, "customStatus":null, "output":"Hello, Tokyo! Hello, London! Hello, Seattle!", "createdTime":"2023-01-31T18:48:49Z", "lastUpdatedTime":"2023-01-31T18:48:56Z" }
Azure でアプリを実行する
Azure でアプリを実行するには、さまざまなリソースを作成する必要があります。 後で簡単にクリーンアップするために、同じリソース グループ内にすべてのリソースを作成します。
Azure SQL データベースの作成
注
Azure SQL データベースや使用したい他のパブリックにアクセス可能な SQL Server インスタンスが既にある場合は、次のセクションに進んで構いません。
運用環境のシナリオでは、 Azure のサービスとリソースがこの [SQL] サーバー設定にアクセスすることを許可 しないようにします。 実際のアプリケーションでは、より強力なファイアウォール制限や仮想ネットワーク構成など、より安全なアプローチを実装する必要があります。
Azure portal では、Azure SQL データベースを作成できます。 作成時:
- Azure サービスとリソースがこのサーバーにアクセスできるようにする ( [ネットワーク] の下)
-
[データベースの照合順序] の値 ([追加設定] の下) を
Latin1_General_100_BIN2_UTF8
に設定します。
Azure Functions アプリとサポート リソースを作成する
ターミナル ウィンドウを開き、Azure にサインインします。
az login
SQL データベースと同じリソース グループとリージョンに次のリソースを作成します。
- アプリケーション コード自体などの重要なアプリ データを格納するために使用される汎用ストレージ アカウント。 ストレージ アカウント名には、3 ~ 24 文字の数字と小文字のみを含める必要があります。
- プレミアム関数アプリ プラン
- 関数アプリ
# Variables ___location=<REGION> resourceGroup=<RESOURCE_GROUP_NAME> storage=<STORAGE_NAME> planName=<PREMIUM_PLAN_NAME> functionApp=<APP_NAME> skuStorage="Standard_LRS" skuPlan="EP1" functionsVersion="4" # Create an Azure storage account echo "Creating $storage" az storage account create --name $storage --___location "$___location" --resource-group $resourceGroup --sku $skuStorage --allow-blob-public-access false # Create a premium plan echo "Creating $premiumPlan" az functionapp plan create --name $planName --resource-group $resourceGroup --___location "$___location" --sku $skuPlan # Create a function app hosted in the premium plan echo "Creating $functionApp" az functionapp create --name $functionApp --storage-account $storage --plan $planName --resource-group $resourceGroup --functions-version $functionsVersion
Azure マネージド ID を作成する
マネージド ID は、接続文字列内の資格情報など、アプリからシークレットを排除することで、アプリの安全性を高めます。 システム割り当てマネージド ID とユーザー割り当てマネージド ID を選択できます。 このクイック スタートでは、ユーザー割り当てマネージド ID を設定する方法について説明します。これは、アプリのライフサイクルに関連付けられていないため、推奨されるオプションです。
次のコマンドは、ID リソースを作成し、アプリに割り当てます。
# Variables
subscription=<SUBSCRIPTION_ID>
identity=<IDENTITY_NAME>
# Create a managed identity resource
echo "Creating $identity"
az identity create -g $resourceGroup -n $identity --___location "$___location"
# Construct the identity resource ID
resourceId="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$identity"
# Assign the identity to the Azure Functions app
echo "Assigning $identity to app"
az functionapp identity assign -g $resourceGroup -n $functionApp --identities "$resourceId"
# Get the identity's ClientId and PrincipalId (also called ObjectId) for a later step.
clientId=$(az identity show --name $identity --resource-group $resourceGroup --query 'clientId' --output tsv)
principalId=$(az identity show --name $identity --resource-group $resourceGroup --query 'principalId' --output tsv)
Azure Storage と Azure SQL Database へのアクセスを許可する
Azure Storage
ストレージ アカウントにアクセスするための ID ストレージ BLOB データ所有者 ロールを割り当てます。
# Set the scope of the access
scope="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.Storage/storageAccounts/$storage"
# Assign the role
echo "Assign Storage Blob Data Owner role to identity"
az role assignment create --assignee "$clientId" --role "Storage Blob Data Owner" --scope "$scope"
Azure SQL データベース
注
Flex Consumption プランで Durable Functions アプリをホストする場合、マネージド ID を使用した Azure SQL データベースへの認証はサポート されません 。 アプリが Flex 従量課金プランでホストされている場合は、「 アプリ設定の設定 」セクションに進んでください。
まず、開発者 ID をデータベースの管理者として設定します。
担当者はあなたのIDなので、あなたのメールアドレスに変更してください。
assignee=$(az ad user show --id "someone@example.com" --query "id" --output tsv)
Azure SQL データベースの管理者として担当者を設定します。
az sql server ad-admin create --resource-group $resourceGroup --server-name <SQL_SERVER_NAME> --display-name ADMIN --object-id "$assignee"
Azure Data Studio や SQL Management Server Studio などのツールを使用して、以前に作成した SQL データベースに接続します。 または、次の SQLCMD コマンドを実行して接続できます。
sqlcmd -S <SQL_SERVER_NAME>.database.windows.net -d <DATABASE_NAME> -U <someone@example.com> -P "ACCOUNT_PASSWORD" -G -l 30
データベースに対して次のクエリを実行して、ID db_owner アクセス権を付与します。
IDENTITY_OBJECT_ID
は、ID 作成手順の PrincipalId です。CREATE USER "<IDENTITY_NAME>" FROM EXTERNAL PROVIDER With OBJECT_ID='<IDENTITY_OBJECT_ID>' ALTER ROLE db_owner ADD MEMBER "<IDENTITY_NAME>"; GO
master
データベースに接続し、ID dbmanager アクセス権を付与します。CREATE USER "<IDENTITY_NAME>" FROM EXTERNAL PROVIDER With OBJECT_ID='<IDENTITY_OBJECT_ID>' ALTER ROLE dbmanager ADD MEMBER "<IDENTITY_NAME>"; GO
必須のアプリ設定を設定する
次のアプリ設定をアプリに追加する必要があります。
-
AzureWebJobsStorage__accountName
: Azure Storage アカウント名 -
AzureWebJobsStorage__clientId
: マネージドIDのクライアントID -
AzureWebJobsStorage__credential
: 資格情報の種類 ( マネージド ID) -
SQLDB_Connection
: SQL データベースの接続文字列
ユーザー割り当てマネージド ID を使用して SQL データベースに対する認証を行う場合、接続文字列は次のようになります。
dbserver=<SQL_SERVER_NAME>
sqlDB=<SQL_DB_NAME>
clientId=<IDENTITY_CLIENT_ID>
sqlconnstr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$clientId;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Authentication='Active Directory Managed Identity';"
Flex Consumption アプリの場合は、接続文字列を使用して今のところ認証を行います。 これを見つけるには、Azure portal の SQL データベース リソースに移動し、[ 設定] タブに移動し、[ 接続文字列] をクリックします。
接続文字列の形式は次のとおりです。
dbserver=<SQL_SERVER_NAME>
sqlDB=<SQL_DB_NAME>
username=<DB_USER_LOGIN>
password=<DB_USER_PASSWORD>
sqlconnstr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$username;Password=$password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
次のコマンドを実行して設定を設定します。
az functionapp config appsettings set --name $functionApp --resource-group $resourceGroup --settings AzureWebJobsStorage__accountName="$storage" AzureWebJobsStorage__clientId="$clientId" AzureWebJobsStorage__credential="managedidentity" SQLDB_Connection=$sqlconnstr
既存の AzureWebJobsStorage
設定を削除します。
az functionapp config appsettings delete --name $functionApp --resource-group $resourceGroup --setting-names "AzureWebJobsStorage"
ローカル プロジェクトを Azure にデプロイしてテストする
最後に、ルート プロジェクト フォルダーで、次を実行してアプリを Azure にデプロイします。
func azure functionapp publish $functionApp
デプロイが完了したら、次を実行して HTTP トリガー URL を取得します。
az functionapp function list --resource-group $resourceGroup --name $functionApp --query '[].{Function:name, URL:invokeUrlTemplate}' --output json
HTTP テスト ツールを使用して ローカル開発 時と同じようにテストします。
タスク ハブ データのデータベースに対してクエリを実行することで、MSSQL バックエンドが正しく構成されていることを検証することもできます。
たとえば、SQL データベースの概要ペインでオーケストレーション インスタンスのクエリを実行できます。 [クエリ エディター] を選択して、認証を行った後、次のクエリを実行します。
SELECT TOP 5 InstanceID, RuntimeStatus, CreatedTime, CompletedTime FROM dt.Instances
単純なオーケストレーターを実行すると、次の例に示すように、少なくとも 1 つの結果が表示されるはずです。
次のステップ
- Azure Container Apps で MSSQL バックエンドを使用して Durable Functions アプリをホストします。
- このバックエンドのアーキテクチャ、構成、ワークロードの動作の詳細については、 MSSQL ストレージ プロバイダーのドキュメント を参照してください。