次の方法で共有


チュートリアル: マウントされた Azure Files 共有で FFmpeg を使用してイメージを処理する

このチュートリアルでは、マウントされた Azure Files 共有に ffmpeg バイナリを使用して Azure Functions のイメージを処理する Python アプリをデプロイします。 イメージをコンテナーにアップロードすると、関数がトリガーされ、マウントから ffmpeg が呼び出されてイメージが変換され、結果がストレージに保存されます。 デプロイ パッケージではなく、マウントされた共有で ffmpeg などの大きなバイナリをホストすることで、デプロイを小さくし、コールド スタートを高速に保ちます。

このチュートリアルでは、次の操作を行います。

  • Azure Developer CLI を使用してマウントされた Azure Files 共有を使用して Flex Consumption 関数アプリをデプロイする
  • BLOB ベースの処理をトリガーするサンプル イメージをアップロードする
  • マウントから ffmpeg という関数が呼び出され、変換されたイメージが保存されたことを確認します

この記事のコード サンプルは、 Azure Files OS マウント サンプル GitHub リポジトリの Azure Functions Flex Consumption で入手できます。

前提条件

このチュートリアルの CLI の例では、Bash 構文を使用し、 Azure Cloud Shell (Bash) および Linux/macOS ターミナルでテストされています。

サンプル プロジェクトを初期化する

このチュートリアルのサンプル コードは、 Azure Files OS Mount Samples GitHub リポジトリの Azure Functions Flex Consumption にあります。 ffmpeg-image-processing フォルダーには、関数アプリ コード、必要な Azure リソースをプロビジョニングする Bicep テンプレート、ffmpeg バイナリをアップロードするデプロイ後スクリプトが含まれています。

  1. ターミナルを開き、リポジトリを複製するディレクトリに移動します。

  2. リポジトリを複製します。

    git clone https://github.com/Azure-Samples/Azure-Functions-Flex-Consumption-with-Azure-Files-OS-Mount-Samples.git
    
  3. プロジェクト フォルダーに移動します。

    cd Azure-Functions-Flex-Consumption-with-Azure-Files-OS-Mount-Samples/ffmpeg-image-processing
    
  4. azd環境を初期化します。 メッセージが表示されたら、 ffmpeg-processingなどの環境名を入力します。

    azd init
    

コードの確認

OS マウント ベースの処理を行う 3 つの重要な部分は、マウントを作成するインフラストラクチャ、バイナリをアップロードするスクリプト、およびそれを呼び出す関数コードです。

mounts.bicep モジュールは、関数アプリで Azure Files SMB マウントを構成します。 mountPath値は、実行時にファイルが表示されるローカル パスを決定します。 ストレージ アカウントのアクセス キーをパラメーターとして渡すと、プラットフォームは実行時に Key Vault 参照を介して解決します。

@description('Function app name')
param functionAppName string

@description('Storage account name')
param storageAccountName string

@description('Storage account access key or app setting reference for Azure Files SMB mount')
param accessKey string

@description('Array of mount configurations')
param mounts array

// Function app reference
resource functionApp 'Microsoft.Web/sites@2023-12-01' existing = {
  name: functionAppName
}

// Azure Files OS mount configuration
// Deploys azureStorageAccounts site config with all mounts in one shot
resource mountConfig 'Microsoft.Web/sites/config@2023-12-01' = {
  parent: functionApp
  name: 'azurestorageaccounts'
  properties: reduce(mounts, {}, (cur, mount) => union(cur, {
    '${mount.name}': {
      type: 'AzureFiles'
      shareName: mount.shareName
      mountPath: mount.mountPath
      accountName: storageAccountName
      accessKey: accessKey
    }
  }))
}

output mountPaths array = [for mount in mounts: mount.mountPath]

Azure Files SMB マウントはまだマネージド ID 認証をサポートしていないため、ストレージ アカウント キーが必要です。 ベスト プラクティスとして、このキーを Azure Key Vault に格納し、アプリ設定で Key Vault 参照 を使用します。 マウント構成では、 @AppSettingRef()を使用してそのアプリ設定が参照されるため、Bicep テンプレートにキーが表示されることはありません。 keyvault.bicep モジュールは、ボールトを作成し、キーを格納し、RBAC ロールを付与します。

@description('Key Vault name')
param name string

@description('Location')
param location string

@description('Tags')
param tags object = {}

@description('Storage account name')
param storageAccountName string

@description('Principal ID of the function app identity (receives Key Vault Secrets User role)')
param functionAppPrincipalId string

@description('Principal ID of the deploying user (receives Key Vault Secrets Officer role)')
param deployerPrincipalId string = ''

// Storage account reference
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
  name: storageAccountName
}

// Key Vault with RBAC authorization
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: name
  location: location
  tags: tags
  properties: {
    sku: {
      family: 'A'
      name: 'standard'
    }
    tenantId: tenant().tenantId
    enableRbacAuthorization: true
    enabledForTemplateDeployment: true
    enableSoftDelete: true
    softDeleteRetentionInDays: 7
  }
}

// Store storage account key as a secret (Azure Files mounts require shared key)
resource storageKeySecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
  parent: keyVault
  name: 'storageAccountKey'
  properties: {
    value: storage.listKeys().keys[0].value
    contentType: 'Storage account access key for Azure Files SMB mount'
  }
}

// Built-in Key Vault RBAC role IDs
var roles = {
  KeyVaultSecretsOfficer: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')
  KeyVaultSecretsUser: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
}

// Grant the function app identity read access to secrets
resource functionAppSecretsUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(keyVault.id, functionAppPrincipalId, roles.KeyVaultSecretsUser)
  scope: keyVault
  properties: {
    roleDefinitionId: roles.KeyVaultSecretsUser
    principalId: functionAppPrincipalId
    principalType: 'ServicePrincipal'
  }
}

// Grant the deployer manage access to secrets
resource deployerSecretsOfficer 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (!empty(deployerPrincipalId)) {
  name: guid(keyVault.id, deployerPrincipalId, roles.KeyVaultSecretsOfficer)
  scope: keyVault
  properties: {
    roleDefinitionId: roles.KeyVaultSecretsOfficer
    principalId: deployerPrincipalId
    principalType: 'User'
  }
}

output name string = keyVault.name
output uri string = keyVault.properties.vaultUri
output storageKeySecretUri string = storageKeySecret.properties.secretUri

main.bicep ファイルは、マウント モジュールと Key Vault モジュールを呼び出します。


// Key Vault for secure storage of Azure Files access key
module keyVault './app/keyvault.bicep' = {
  name: 'keyVault'
  scope: rg
  params: {
    name: !empty(keyVaultName) ? keyVaultName : '${abbrs.keyVaultVaults}${resourceToken}'
    location: location
    tags: tags
    storageAccountName: storage.outputs.name
    functionAppPrincipalId: processorIdentity.outputs.principalId
    deployerPrincipalId: principalId
  }
}

// Azure Files mount configuration (access key resolved via Key Vault reference)
module azureFilesMount './app/mounts.bicep' = {
  name: 'azureFilesMount'
  scope: rg
  params: {
    functionAppName: functionApp.outputs.name
    storageAccountName: storage.outputs.name
    accessKey: '@AppSettingRef(MOUNT_SECRET_REFERENCE)'
    mounts: [
      {
        name: 'tools'
        shareName: 'tools'
        mountPath: '/mounts/tools/'
      }
    ]
  }
  dependsOn: [
    functionAppRoleAssignments
  ]
}

Azure Developer CLI を使用してデプロイする

このサンプルは 、Azure Developer CLI (azd) テンプレートです 。 1 つの azd up コマンドによってインフラストラクチャがプロビジョニングされ、関数コードがデプロイされ、ffmpeg バイナリが Azure Files にアップロードされ、BLOB トリガー用の Event Grid サブスクリプションが作成されます。

  1. Azure にサインインします。 デプロイ後スクリプトでは Azure CLI コマンドが使用されるため、両方のツールを使用して認証する必要があります。

    azd auth login
    az login
    
  2. すべてをプロビジョニングしてデプロイします。

    azd up
    

    メッセージが表示されたら、使用する Azure サブスクリプションと場所を選択します。 その後、次のコマンドを実行します。

    • リソース グループ、ストレージ アカウント、Key Vault、Flex Consumption 関数アプリ、Application Insights インスタンス、およびマネージド ID を作成します。
    • Python 関数コードをデプロイします。
    • ffmpeg バイナリをダウンロードして Azure Files 共有にアップロードします。
    • Blob アップロードによって関数が起動するように Event Grid サブスクリプションを作成します。
    • 正常性チェックを実行します。

    Azure Files SMB マウントはまだマネージド ID 認証をサポートしていないため、ストレージ アカウント キーが必要です。 ベスト プラクティスとして、デプロイではこのキーが Azure Key Vault に格納され、 Key Vault 参照 が使用されるため、キーはアプリ設定で公開されません。 このアプローチでは、キーローテーションの一元化されたシークレット管理、監査、およびサポートが提供されます。

    デプロイには数分かかります。 完了すると、作成されたリソースの概要が表示されます。

  3. 残りの手順では、リソース名をシェル変数として保存します。

    RESOURCE_GROUP=$(azd env get-value AZURE_RESOURCE_GROUP)
    STORAGE_ACCOUNT=$(azd env get-value AZURE_STORAGE_ACCOUNT_NAME)
    FUNCTION_APP_NAME=$(azd env get-value AZURE_FUNCTION_APP_NAME)
    INPUT_CONTAINER=$(azd env get-value AZURE_STORAGE_INPUT_CONTAINER)
    OUTPUT_CONTAINER=$(azd env get-value AZURE_STORAGE_OUTPUT_CONTAINER)
    

イメージを処理する

  1. リポジトリに含まれているサンプル イメージを入力コンテナーにアップロードします。 デプロイ中に作成された Event Grid サブスクリプションは、BLOB のアップロード時に関数を自動的にトリガーします。

    az storage blob upload \
      --container-name $INPUT_CONTAINER \
      --name sample_image.png \
      --file sample_image.png \
      --account-name $STORAGE_ACCOUNT \
      --auth-mode login
    

    ヒント

    トリガーがすぐに起動しない場合は、10 ~ 15 秒待ってから、Azure portal で関数の実行ログを確認します。

  2. 出力コンテナー内の BLOB を一覧表示して、関数がイメージを処理したことを確認します。

    az storage blob list \
      --container-name $OUTPUT_CONTAINER \
      --account-name $STORAGE_ACCOUNT \
      --auth-mode login \
      -o table
    

    出力コンテナーに sample_image.jpg が表示されます。

  3. 変換されたイメージをダウンロードします。

    az storage blob download \
      --container-name $OUTPUT_CONTAINER \
      --name sample_image.png \
      --file ./output_image.png \
      --account-name $STORAGE_ACCOUNT \
      --auth-mode login
    

最初の実行が少し遅くなる可能性があります (コールド スタート)。 関数コンテナーはウォームのままであり、ffmpeg はキャッシュされるため、後続の呼び出しは高速です。 コールド スタートを最小限に抑えるには、 常時対応のインスタンスを有効にすることを検討してください。

リソースをクリーンアップする

継続的な料金を回避するには、このチュートリアルで作成したすべてのリソースを削除します。

azd down --purge

Warnung

このコマンドは、リソース グループとその中のすべてのリソース (関数アプリ、ストレージ アカウント、Application Insights インスタンスを含む) を削除します。