Руководство. Обработка образов с помощью FFmpeg в подключенной общей папке файлов Azure

В этом учебном пособии вы развертываете приложение на Python, которое использует двоичный файл ffmpeg на подключенной общей папке файлов Azure для обработки изображений в Azure Functions. При отправке образа в контейнер функция активирует функцию, вызывает ffmpeg из подключения для преобразования образа и сохраняет результат обратно в хранилище. Размещая такие крупные двоичные файлы, как ffmpeg, в подключённой общей папке, а не в пакете развертывания, вы позволяете уменьшить объем развертываний и ускорить процесс запуска.

Изучив это руководство, вы:

  • Развертывание приложения-функции Flex Consumption с подключенной общей папкой файлов Azure с помощью Интерфейса командной строки разработчика Azure
  • Отправка примера образа для активации обработки BLOB-объектов
  • Убедитесь, что функция, называемая ffmpeg, была запущена из точки монтирования и сохранила преобразованное изображение.

Замечание

Примеры кода, приведенные в этой статье, доступны в репозитории GitHub Azure Functions Flex Consumption with Azure Files OS Mount Samples.

Необходимые условия

Примеры интерфейса командной строки в этом руководстве используют синтаксис Bash и тестируются в терминалах Azure Cloud Shell (Bash) и Linux/macOS.

Инициализация примера проекта

Пример кода для этого учебника находится в репозитории GitHub Azure Functions Flex Consumption with Azure Files OS Mount Samples. Папка ffmpeg-image-processing содержит код приложения-функции, шаблон Bicep, который подготавливает необходимые ресурсы Azure и скрипт после развертывания, который отправляет двоичный файл 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
    

Просмотр кода

Три ключевых элемента, которые обеспечивают работу обработки на основе монтирования ОС, — это инфраструктура, которая создает монтирование, скрипт, который загружает двоичный файл, и код функции, который выполняет его.

Модуль mounts.bicep настраивает подключение SMB файлов Azure к приложению-функции. Значение 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]

Поскольку точки монтирования SMB для Azure Files еще не поддерживают проверку подлинности с использованием управляемых удостоверений, вам необходим ключ учетной записи хранения. Рекомендуется сохранить этот ключ в 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

Этот пример представляет собой шаблон интерфейса командной строки разработчика Azure (azd). azd up Одна команда подготавливает инфраструктуру, развертывает код функции, отправляет двоичный файл ffmpeg в Файлы Azure и создает подписку на Event Grid для триггеров объектов BLOB.

  1. Войдите в Azure. Скрипт после развертывания использует команды Azure CLI, поэтому необходимо пройти проверку подлинности с помощью обоих средств:

    azd auth login
    az login
    
  2. Подготовка и развертывание всего:

    azd up
    

    При появлении запроса выберите подписку Azure и расположение для использования. Затем выполните следующую команду:

    • Создает группу ресурсов, учетную запись хранения, Key Vault, приложение-функцию Flex Consumption, экземпляр Application Insights и управляемое удостоверение.
    • Развертывает код функции Python.
    • Загружает и отправляет двоичный файл ffmpeg в общую папку файлов Azure.
    • Создает подписку на события Event Grid, чтобы загрузки блобов запускали вашу функцию.
    • Выполняет проверку работоспособности.

    Замечание

    Так как подключения SMB для файлов Azure еще не поддерживают проверку подлинности с управляемыми удостоверениями, требуется ключ учетной записи хранилища. В качестве рекомендации развертывание сохраняет этот ключ в 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.

  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

Предупреждение

Эта команда удаляет группу ресурсов и все ресурсы в ней, включая приложение-функцию, учетную запись хранения и экземпляр Application Insights.