1. はじめに
こんにちは、井村です。
前回の記事では Azure Functions の基本構造やトリガーについて学びました。今回はその続きとして、Azure Functions の「バインディング」機能に焦点を当てて、簡単な事例を通して理解を深めていきます。
2. バインディングとは?
Azure Functions のバインディングとは、関数と外部サービス(Storage, Cosmos DB, Service Busなど)との連携を簡単にする仕組みです。コード内で明示的に API を呼び出す必要がなく、設定ファイル(function.json)で連携を定義できます。
今回は「Output Binding」を使って、HTTPリクエストで受け取ったテキストを Azure Blob Storage に保存する関数を作成します。
3. 実装概要
3.1 処理の流れ
- ユーザーが HTTP リクエストで text パラメータを送信
- 関数がそのテキストを受け取り
- Blob Storage に .txt ファイルとして保存
3.2 プロジェクト構成
azure-functions-python2/
├── SaveToBlob/ # 関数ごとのディレクトリ
│ ├── __init__.py # 関数のエントリポイント
│ └── function.json # バインディング設定
├── local.settings.json # ローカル実行用の設定ファイル(AzureWebJobsStorageなど)
├── requirements.txt # Python依存ライブラリの一覧(必須)
└── host.json # (任意)関数全体の設定ファイル
3.3 関数コード(init.py)
import azure.functions as func
def main(req: func.HttpRequest, outputBlob: func.Out[str]) -> func.HttpResponse:
text = req.params.get('text')
if not text:
return func.HttpResponse("Please pass text in the query string", status_code=400)
outputBlob.set(text)
return func.HttpResponse(f"Text saved to blob: {text}")
3.4 バインディング設定(function.json)
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get"]
},
{
"type": "blob",
"direction": "out",
"name": "outputBlob",
"path": "samples-output/{rand-guid}.txt",
"connection": "AzureWebJobsStorage"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
3.5 requirements.txt
# Uncomment to enable Azure Monitor OpenTelemetry
# Ref: aka.ms/functions-azure-monitor-python
# azure-monitor-opentelemetry
azure-functions
4. 構築
4.1 Azureリソースの構築
各種リソースを作成します。
リソースデプロイはBicepテンプレートを利用します。
main.bicep
@description('作成するシステム名を指定します。')
param systemName string = 'demo'
@description('リソースグループのロケーション。今回は東日本リージョン (Japan East) を指定します。')
param location string = 'japaneast'
@description('環境を指定します。dev, stg, pro のいずれかを選択してください。')
@allowed([
'dev'
'stg'
'pro'
])
param env string = 'dev'
@description('ランダムなサフィックスを生成します。')
param random string = newGuid()
var randomSuffix = toLower(substring(random, 0, 5)) // GUIDの先頭5文字を小文字で取得
@description('Funtionsの名前。')
var funcName = 'func-${systemName}-${env}-${randomSuffix}'
@description('ストレートアカウントの名前。')
var stName = toLower('st${systemName}${env}${randomSuffix}')
@description('App Serviceプランの名前。')
var appServicePlanName = 'asp-${systemName}-${env}-${randomSuffix}'
@description('ストレージアカウントの接続文字列。')
var storageConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value};EndpointSuffix=core.windows.net'
@description('ストレージアカウントを作成します。')
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: stName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
supportsHttpsTrafficOnly: true
}
}
@description('Blobコンテナを作成します。')
resource blobContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
name: '${storageAccount.name}/default/samples-output'
properties: {
publicAccess: 'None'
}
}
@description('App Serviceプランを作成します。')
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
name: appServicePlanName
location: location
sku: {
name: 'B1'
tier: 'Basic'
}
properties: {
reserved: true // Windowsの場合はfalse、Linuxの場合はtrue
}
}
@description('Azure Functionsを作成します。')
resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
name: funcName
location: location
kind: 'functionapp,linux'
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: 'PYTHON|3.12' // 使用するランタイムに応じて変更(例:NODE|14, DOTNET|6など)
appSettings: [
{
name: 'AzureWebJobsStorage'
value: storageConnectionString
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python' // 使用するランタイムに応じて変更(例:node, python, dotnetなど)
}
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
]
}
httpsOnly: true
}
}
# Azureへログイン
az login
# リソースグループの作成
az group create --name rg-demo-dev --location japaneast
# Azureリソースの作成
az deployment group create --template-file main.bicep --resource-group rg-demo-dev
4.2 ローカル実行用の設定ファイル(local.settings.json)
リソースの作成後、 local.settings.json ファイルを作成するためストレージアカウントの接続文字列を取得します。
以下の2通りのコマンドで取得可能ですが、取得内容は同じです。
# Azure AD 認証で Blob コンテナを確認するコマンド(Bicepテンプレートで作成済みの確認)
az storage container list --account-name stdemodevd400c --auth-mode login --output table
# ストレートアカウントから接続文字列を取得
az storage account show-connection-string --resource-group rg-demo-dev --name stdemodevd400c --output tsv
# Azure Functionsの環境変数のアプリ設定から接続文字列を取得
az functionapp config appsettings list --name func-demo-dev-d400c --resource-group rg-demo-dev --query "[?name=='AzureWebJobsStorage'].value" --output tsv
接続文字列を "local.settings.json" に追記する。
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=~省略~.table.core.windows.net/"
}
}
5. 検証
5.1 ローカル環境の検証
接続文字列を追記したら、ローカル環境でAzure Functions起動した状態からBlobストレージにアクセスできます。
# 移動
cd .\azure-functions-python2\
# Azure Functions起動
func start
# 以下URLが出力されることを確認
SaveToBlob: [GET] http://localhost:7071/api/SaveToBlob
# ブラウザに以下を貼り付け
http://localhost:7071/api/SaveToBlob?text=こんにちはAzure
ブラウザの出力結果は以下の通りです。
Blobコンテナにはテキストファイルが作成されました。
ブラウザに貼り付けた内容が確認できました。
5.2 Azure環境の検証
ローカル環境で動作確認できましたのでAzure上へアプリをデプロイします。
# デプロイコマンド
func azure functionapp publish func-demo-dev-d400c
動作確認を行うため、ブラウザに貼り付けるURLを確認します。
概要タブからデプロイしたSaveToBlobを選択します。
関数のURLの取得を選択します。
URLをコピーします。
取得したURLにnameをプラスしてブラウザに貼り付けます。
https://<関数URL>?text=おやすみAzure
ローカル環境検証同様にBlobストレージにテキストが格納されていることが確認できました。
6. 終わりに
Azure Functions のバインディングを使うことで、コードをほとんど書かずに外部サービスと連携できることが分かりました。
次回は、Queue Storage や Cosmos DB との連携にも挑戦してみたいと考えています。







