Kurz: Zpracování imagí pomocí FFmpeg na připojené sdílené složce Azure Files

V tomto kurzu nasadíte aplikaci v Pythonu, která používá binární soubor ffmpeg na připojené sdílené složce Azure Files ke zpracování imagí ve službě Azure Functions. Když nahrajete obrázek do kontejneru, funkce se aktivuje, zavolá ffmpeg z připojeného úložiště a převede obrázek, poté uloží výsledek zpět do úložiště. Hostováním velkých binárních souborů, jako je ffmpeg, na připojeném sdíleném úložišti namísto v balíčku pro nasazení, udržíte balíčky malé a urychlíte rychlost prvních spuštění.

V tomto kurzu se naučíte:

  • Nasazení aplikace funkcí Flex Consumption s připojenou sdílenou složkou Azure Files pomocí Azure Developer CLI
  • Nahrání ukázkového obrázku pro aktivaci zpracování založeného na objektech blob
  • Ověřte, že funkce nazvaná ffmpeg z mountu uložila převedený obrázek.

Poznámka:

Ukázky kódu pro tento článek jsou k dispozici v úložišti Azure Functions Flex Consumption s využitím azure Files OS Mount Samples na GitHubu.

Předpoklady

Příklady rozhraní příkazového řádku v tomto kurzu používají syntaxi Bash a testují se v terminálech Azure Cloud Shell (Bash) a Linux/macOS.

Inicializace ukázkového projektu

Ukázkový kód pro tento kurz je v úložišti Azure Functions Flex Consumption with Azure Files OS Mount Samples na GitHubu. Složka ffmpeg-image-processing obsahuje kód aplikace funkcí, šablonu Bicep, která zřídí požadované prostředky Azure, a skript po nasazení, který nahraje binární soubor ffmpeg.

  1. Otevřete terminál a přejděte do adresáře, do kterého chcete úložiště naklonovat.

  2. Naklonujte úložiště:

    git clone https://github.com/Azure-Samples/Azure-Functions-Flex-Consumption-with-Azure-Files-OS-Mount-Samples.git
    
  3. Přejděte do složky projektu:

    cd Azure-Functions-Flex-Consumption-with-Azure-Files-OS-Mount-Samples/ffmpeg-image-processing
    
  4. Inicializujte azd prostředí Po zobrazení výzvy zadejte název prostředí, například ffmpeg-processing:

    azd init
    

Kontrola kódu

Tři klíčové části, které umožňují zpracování založené na připojení operačního systému, jsou infrastruktura, která vytvoří mount, skript, který nahraje binární soubor, a kód funkce, který ho volá.

Modul mounts.bicep nakonfiguruje SMB připojení služby Azure Files na funkční aplikaci. Hodnota mountPath určuje místní cestu, kde se soubory zobrazují za běhu. Přístupový klíč účtu úložiště předáte jako parametr a platforma ho vyřeší za běhu prostřednictvím odkazu na 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]

Vzhledem k tomu, že připojení SMB služby Azure Files zatím nepodporují ověřování pomocí spravovaných identit, potřebujete klíč k účtu úložiště. Osvědčeným postupem je uložit tento klíč ve službě Azure Key Vault a použít odkaz služby Key Vault v nastavení aplikace. Konfigurace připojení odkazuje na nastavení aplikace pomocí @AppSettingRef(), takže klíč se nikdy nezobrazí v šablonách Bicep. Modul keyvault.bicep vytvoří trezor, uloží klíč a udělí role 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

Soubor main.bicep spustí moduly mount a 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
  ]
}

Nasazení pomocí Azure Developer CLI

Tato ukázka je šablona Azure Developer CLI (azd ). Jeden azd up příkaz zřídí infrastrukturu, nasadí kód funkce, nahraje binární soubor ffmpeg do služby Azure Files a vytvoří odběr služby Event Grid pro triggery objektů blob.

  1. Přihlaste se k Azure. Skript po nasazení používá příkazy Azure CLI, takže je potřeba provést ověření pomocí obou nástrojů:

    azd auth login
    az login
    
  2. Zřízení a nasazení všeho:

    azd up
    

    Po zobrazení výzvy vyberte předplatné Azure a umístění, které chcete použít. Příkaz pak:

    • Vytvoří skupinu prostředků, účet úložiště, Key Vault, aplikaci funkcí typu Flex Consumption, instanci Application Insights a spravovanou identitu.
    • Nasadí kód funkce Pythonu.
    • Stáhne a nahraje binární soubor ffmpeg do sdílené složky Azure Files.
    • Vytvoří odběr služby Event Grid, aby nahrávání objektů blob spustilo vaši funkci.
    • Spustí kontrolu stavu.

    Poznámka:

    Vzhledem k tomu, že SMB připojení služby Azure Files zatím nepodporují autentizaci pomocí spravovaných identit, je vyžadován klíč účtu úložiště. Osvědčeným postupem je, že nasazení uloží tento klíč do služby Azure Key Vault a použije odkaz služby Key Vault , takže klíč se nikdy nezpřístupní v nastavení aplikace. Tento přístup poskytuje centralizovanou správu tajných kódů, auditování a podporu rotace klíčů.

    Nasazení trvá několik minut. Po dokončení se zobrazí souhrn vytvořených prostředků.

  3. Názvy prostředků uložte jako shellové proměnné pro zbývající kroky:

    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)
    

Zpracování obrázku

  1. Nahrajte ukázkovou image obsaženou v úložišti do vstupního kontejneru. Odběr služby Event Grid vytvořený během nasazení automaticky aktivuje vaši funkci při nahrání objektu blob.

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

    Návod

    Pokud se trigger neaktivuje okamžitě, počkejte 10 až 15 sekund a pak zkontrolujte protokoly spuštění funkce na webu Azure Portal.

  2. Ověřte, že funkce zpracovala obraz výpisem blobů ve výstupním kontejneru:

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

    Měli byste vidět sample_image.jpg ve výstupním kontejneru.

  3. Stáhněte převedený obrázek:

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

Poznámka:

První spuštění může být o něco pomalejší (studený start). Následné vyvolání je rychlejší, protože kontejner funkcí zůstává teplý a ffmpeg se ukládá do mezipaměti. Pokud chcete minimalizovat studené starty, zvažte zapnutí vždy připravených instancí.

Vyčistěte zdroje

Pokud se chcete vyhnout průběžným poplatkům, odstraňte všechny prostředky vytvořené v tomto kurzu:

azd down --purge

Výstraha

Tento příkaz odstraní skupinu prostředků a všechny prostředky v ní, včetně aplikace funkcí, účtu úložiště a instance Application Insights.