Kurz: Analýza odolného textu s připojenou sdílenou složkou Azure Files

V tomto kurzu nasadíte aplikaci Azure Functions v Pythonu, která používá Durable Functions k orchestraci paralelní analýzy textových souborů. Vaše funkční aplikace připojí sdílenou složku Azure Files, analyzuje několik textových souborů paralelně (fan-out), agreguje výsledky (fan-in) a vrací je volajícímu. Tento přístup ukazuje klíčovou výhodu připojení úložiště: sdílený přístup k souborům napříč několika instancemi funkcí bez režie na síť podle požadavků.

V tomto kurzu se naučíte:

  • Použití Azure Developer CLI k nasazení aplikace Durable Functions v plánu Flex Consumption s připojenou sdílenou složkou Azure Files
  • Aktivace orchestrace pro paralelní zpracování ukázkových textových souborů
  • Ověření agregovaných výsledků analýzy

Note

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 byly testovány v terminálech Azure Cloud Shell (Bash) a Linux/macOS.

Inicializace ukázkového projektu

Vzorový kód pro tento kurz najdete v úložišti Azure Functions Flex Consumption s namapováním Azure Files - ukázky GitHubu. Složka durable-text-analysis obsahuje kód aplikace funkcí, šablonu Bicep, která zřídí požadované prostředky Azure, a skript po nasazení, který nahraje ukázkové textové soubory.

  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/durable-text-analysis
    
  4. Inicializujte azd prostředí Po zobrazení výzvy zadejte název prostředí, například durable-text:

    azd init
    

Kontrola kódu

Tři klíčové části, které tvoří tuto ukázku, jsou infrastruktura, která vytváří připojení, skript, který nahrává ukázkové soubory, a kód funkce, který orchestruje analýzu.

Při spuštění orchestrace následuje tento tok:

  1. Příkaz HTTP POST pro /api/start-analysis spustí orchestraci Durable Functions.
  2. Orchestrátor volá list_text_files aktivitu, aby našel všechny .txt soubory na připojeném médiu.
  3. Orchestrátor se rozvětvuje a volá analyse_text_file pro každý soubor paralelně.
  4. Jakmile všechny paralelní úlohy dokončí, orchestrátor zavolá aggregate_results ke sloučení metrik jednotlivých souborů do jediného souhrnu.
  5. Agregovaný výsledek se vrátí jako výstup orchestrace.

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: 'data'
        shareName: 'data'
        mountPath: '/mounts/data/'
      }
    ]
  }
  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 a nahraje ukázkové textové soubory do sdílené složky Azure Files.

  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í Flex Consumption s konfigurací Durable Functions, instanci Application Insights a spravovanou identitu.
    • Nasadí kód funkce Pythonu.
    • Nahraje ukázkové textové soubory do sdílené složky Azure Files.
    • Spustí kontrolu stavu.

    Note

    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, ž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)
    FUNCTION_APP_NAME=$(azd env get-value AZURE_FUNCTION_APP_NAME)
    FUNCTION_APP_URL=$(azd env get-value AZURE_FUNCTION_APP_URL)
    

Spuštění orchestrace

  1. Získejte klíč hostitele funkce:

    HOST_KEY=$(az functionapp keys list \
      --resource-group $RESOURCE_GROUP \
      --name $FUNCTION_APP_NAME \
      --query "functionKeys.default" \
      -o tsv)
    
  2. Spusťte orchestraci. Můžete volitelně předat JSON text s {"mount_path": "/mounts/data/"} a přepsat výchozí cestu připojení.

    curl -s -X POST "${FUNCTION_APP_URL}/api/start-analysis?code=${HOST_KEY}" | jq .
    

    Odpověď obsahuje ID instance a správní URI, které můžete použít ke kontrole stavu, odesílání událostí nebo ukončení orchestrace.

    {
      "id": "abc123def456",
      "statusQueryGetUri": "https://<your-app>.azurewebsites.net/...",
      "sendEventPostUri": "https://...",
      "terminatePostUri": "https://..."
    }
    

Ověření výsledků

  1. Pomocí položky statusQueryGetUri z odpovědi spuštění zkontrolujte stav orchestrace:

    STATUS_URL="<statusQueryGetUri-from-trigger-response>"
    
    curl -s "${STATUS_URL}" | jq .
    

    Zatímco probíhá orchestrace, runtimeStatus je Running. Po dokončení bude odpověď vypadat takto:

    {
      "instanceId": "abc123def456",
      "runtimeStatus": "Completed",
      "output": {
        "total_files": 3,
        "total_words": 45,
        "total_lines": 12,
        "total_chars": 303,
        "overall_avg_word_length": 4.82,
        "overall_top_characters": [["e", 42], ["t", 38], ["a", 35]],
        "per_file": [
          {
            "file_path": "/mounts/data/sample1.txt",
            "word_count": 15,
            "line_count": 4,
            "char_count": 98,
            "avg_word_length": 5.1,
            "top_characters": [["e", 14], ["t", 12]]
          },
          {
            "file_path": "/mounts/data/sample2.txt",
            "word_count": 18,
            "line_count": 5,
            "char_count": 120,
            "avg_word_length": 4.6,
            "top_characters": [["a", 16], ["e", 15]]
          },
          {
            "file_path": "/mounts/data/sample3.txt",
            "word_count": 12,
            "line_count": 3,
            "char_count": 85,
            "avg_word_length": 4.9,
            "top_characters": [["e", 13], ["t", 11]]
          }
        ]
      }
    }
    

    Aplikace také zpřístupňuje praktický koncový bod na /api/status/{instance_id}, který vrací zjednodušenou odpověď na stav.

Tip

Aplikace funkcí přistupuje ke všem třem souborům paralelně prostřednictvím připojení úložiště. Aplikace nepotřebuje žádná síťová volání podle požadavků. Funkce je čte přímo z připojené sdílené složky pomocí standardních vstupně-výstupních operací souborů. Tento přístup ukazuje sílu připojení úložišť v kombinaci s Durable Functions.

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

Warning

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.