Condividi tramite


Guida introduttiva: Ridimensionare i servizi distribuiti con i modelli Web azd Python con Bicep

I modelli Web azd Python consentono di creare rapidamente una nuova applicazione Web e di distribuirla in Azure. I azd modelli sono stati progettati per usare opzioni di servizio di Azure a basso costo. Senza dubbio, è consigliabile modificare i livelli di servizio (o sku) per ognuno dei servizi definiti nel modello per lo scenario.

In questa guida introduttiva si aggiorneranno i file di modello bicep appropriati per aumentare le prestazioni dei servizi esistenti e aggiungere nuovi servizi alla distribuzione. Si eseguirà quindi il azd provision comando e si visualizzerà la modifica apportata alla distribuzione di Azure.

Prerequisiti

Una sottoscrizione di Azure: creare un account gratuitamente

Nel computer locale è installato quanto segue:

Distribuire un modello

Per iniziare, è necessaria una distribuzione funzionante azd . Dopo averlo creato, è possibile modificare i file Bicep generati dal azd modello.

  1. Seguire i passaggi da 1 a 7 nell'articolo Avvio rapido. Nel passaggio 2 usare il azure-django-postgres-flexible-appservice modello. Per praticità, ecco l'intera sequenza di comandi da eseguire dalla riga di comando:

    mkdir azdtest
    cd azdtest
    azd init --template azure-django-postgres-flexible-appservice
    azd auth login
    azd up
    

    Al azd up termine, aprire il portale di Azure, passare al servizio app Azure distribuito nel nuovo gruppo di risorse e prendere nota del piano tariffario servizio app (vedere la pagina Panoramica del piano di servizio app, la sezione Informazioni di base, il valore "Piano tariffario").

  2. Nel passaggio 1 dell'articolo Avvio rapido è stato richiesto di creare la cartella azdtest . Aprire la cartella in Visual Studio Code.

  3. Nel riquadro Explorer passare alla cartella infra . Osservare le sottocartelle e i file nella cartella infra .

    Il file main.bicep orchestra la creazione di tutti i servizi distribuiti durante l'esecuzione di un azd up oggetto o azd provision. Chiama in altri file, ad esempio db.bicep e web.bicep, che a loro volta chiamano in file contenuti nella sottocartella \core.

    La sottocartella \core è una struttura di cartelle profondamente annidata contenente modelli bicep per molti servizi di Azure. Alcuni dei file nella sottocartella \core fanno riferimento ai tre file bicep di primo livello (main.bicep, db.bicep e web.bicep) e alcuni non vengono usati affatto in questo progetto.

Ridimensionare un servizio modificando le relative proprietà Bicep

È possibile ridimensionare una risorsa esistente nella distribuzione modificandone lo SKU. Per dimostrare questo problema, si modificherà il piano servizio app dal "piano di servizio di base" (progettato per le app con requisiti di traffico inferiori e non sono necessarie funzionalità avanzate di scalabilità automatica e gestione del traffico) al "piano di servizio Standard", progettato per l'esecuzione di carichi di lavoro di produzione.

Nota

Non tutte le modifiche dello SKU possono essere apportate dopo il fatto. Alcune ricerche potrebbero essere necessarie per comprendere meglio le opzioni di ridimensionamento.

  1. Aprire il file web.bicep e individuare la definizione del appService modulo. In particolare, cercare l'impostazione della proprietà:

       sku: {
          name: 'B1'
       }
    

    Modificare il valore da B1 a S1 come indicato di seguito:

       sku: {
          name: 'S1'
       }
    

    Importante

    In seguito a questa modifica, il prezzo all'ora aumenterà leggermente. I dettagli sui diversi piani di servizio e sui relativi costi associati sono disponibili nella pagina dei prezzi di servizio app.

  2. Supponendo che l'applicazione sia già stata distribuita in Azure, usare il comando seguente per distribuire le modifiche all'infrastruttura senza ridistribuire il codice dell'applicazione stesso.

    azd provision
    

    Non è consigliabile richiedere un percorso e una sottoscrizione. Tali valori vengono salvati nel file .azure<environment-name.env>, dove <environment-name> è il nome dell'ambiente specificato durante azd init.

  3. Al azd provision termine, verificare che l'applicazione Web funzioni ancora. Trovare anche il piano di servizio app per il gruppo di risorse e verificare che il piano tariffario sia impostato sul piano di servizio Standard (S1).

Aggiungere una nuova definizione di servizio con Bicep

È possibile aggiungere una nuova risorsa alla distribuzione apportando modifiche più grandi a Bicep nel progetto. Per dimostrare questo problema, si aggiungerà un'istanza di cache di Azure per Redis alla distribuzione esistente in preparazione di una nuova funzionalità fittizia che si prevede di aggiungere in una data futura.

Importante

In seguito a questa modifica, si pagherà un'istanza di cache di Azure per Redis finché non si elimina la risorsa nel portale di Azure o si usa azd down. I dettagli sui diversi piani di servizio e sui relativi costi associati sono disponibili nella pagina dei prezzi di cache di Azure per Redis.

  1. Creare un nuovo file nella cartella infra denominata redis.bicep. Copiare e incollare il codice seguente nel nuovo file:

    param name string
    param location string = resourceGroup().location
    param tags object = {}
    param keyVaultName string
    param connStrKeyName string
    param passwordKeyName string
    param primaryKeyKeyName string
    
    @allowed([
      'Enabled'
      'Disabled'
    ])
    param publicNetworkAccess string = 'Enabled'
    
    @allowed([
      'C'
      'P'
    ])
    param skuFamily string = 'C'
    
    @allowed([
      0
      1
      2
      3
      4
      5
      6
    ])
    param skuCapacity int = 1
    @allowed([
      'Basic'
      'Standard'
      'Premium'
    ])
    param skuName string = 'Standard'
    
    param saveKeysToVault bool = true
    
    resource redis 'Microsoft.Cache/redis@2020-12-01' = {
      name: name
      location: location
      properties: {
        sku: {
          capacity: skuCapacity
          family: skuFamily
          name: skuName
        }
        publicNetworkAccess: publicNetworkAccess
        enableNonSslPort: true    
      }
      tags: tags
    }
    
    resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
      name: keyVaultName
    }
    
    resource redisKey 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = if (saveKeysToVault) {
      name: primaryKeyKeyName
      parent: keyVault
      properties: {
        value: redis.listKeys().primaryKey
      }
    }
    
    resource redisConnStr 'Microsoft.KeyVault/vaults/secrets@2018-02-14' = if (saveKeysToVault) {
      name: connStrKeyName
      parent: keyVault
      properties: {
        value: '${name}.redis.cache.windows.net,abortConnect=false,ssl=true,password=${redis.listKeys().primaryKey}'
      }
    }
    resource redisPassword 'Microsoft.KeyVault/vaults/secrets@2018-02-14' = if (saveKeysToVault) {
      name: passwordKeyName
      parent: keyVault
      properties: {
        value: redis.listKeys().primaryKey
      }
    }
    
    output REDIS_ID string = redis.id
    output REDIS_HOST string = redis.properties.hostName
    
  2. Modificare il file main.bicep per creare un'istanza della risorsa "redis".

    Nel file main.bicep aggiungere il codice seguente sotto le parentesi graffe finali associate alla sezione front-end Web e sopra la sezione secrets.

    // Caching server
    module redis 'redis.bicep' = {
      name: 'redis'
      scope: resourceGroup
      params: {
        name: replace('${take(prefix, 19)}-rds', '--', '-')
        location: location
        tags: tags
        keyVaultName: keyVault.outputs.name
        connStrKeyName: 'RedisConnectionString'
        passwordKeyName: 'RedisPassword'
        primaryKeyKeyName: 'RedisPrimaryKey'
        publicNetworkAccess: 'Enabled'
        skuFamily: 'C'
        skuCapacity: 1
        skuName: 'Standard'
        saveKeysToVault: true
      }
    }
    
  3. Aggiungere i valori di output nella parte inferiore del file:

    output REDIS_ID string = redis.outputs.REDIS_ID
    output REDIS_HOST string = redis.outputs.REDIS_HOST
    
  4. Verificare che l'intero file main.bicep sia identico al codice seguente:

    targetScope = 'subscription'
    
    @minLength(1)
    @maxLength(64)
    @description('Name which is used to generate a short unique hash for each resource')
    param name string
    
    @minLength(1)
    @description('Primary location for all resources')
    param location string
    
    @secure()
    @description('DBServer administrator password')
    param dbserverPassword string
    
    @secure()
    @description('Secret Key')
    param secretKey string
    
    @description('Id of the user or app to assign application roles')
    param principalId string = ''
    
    var resourceToken = toLower(uniqueString(subscription().id, name, location))
    var prefix = '${name}-${resourceToken}'
    var tags = { 'azd-env-name': name }
    
    resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
      name: '${name}-rg'
      location: location
      tags: tags
    }
    
    // Store secrets in a keyvault
    module keyVault './core/security/keyvault.bicep' = {
      name: 'keyvault'
      scope: resourceGroup
      params: {
        name: '${take(replace(prefix, '-', ''), 17)}-vault'
        location: location
        tags: tags
        principalId: principalId
      }
    }
    
    module db 'db.bicep' = {
      name: 'db'
      scope: resourceGroup
      params: {
        name: 'dbserver'
        location: location
        tags: tags
        prefix: prefix
        dbserverDatabaseName: 'relecloud'
        dbserverPassword: dbserverPassword
      }
    }
    
    // Monitor application with Azure Monitor
    module monitoring 'core/monitor/monitoring.bicep' = {
      name: 'monitoring'
      scope: resourceGroup
      params: {
        location: location
        tags: tags
        applicationInsightsDashboardName: '${prefix}-appinsights-dashboard'
        applicationInsightsName: '${prefix}-appinsights'
        logAnalyticsName: '${take(prefix, 50)}-loganalytics' // Max 63 chars
      }
    }
    
    // Web frontend
    module web 'web.bicep' = {
      name: 'web'
      scope: resourceGroup
      params: {
        name: replace('${take(prefix, 19)}-appsvc', '--', '-')
        location: location
        tags: tags
        applicationInsightsName: monitoring.outputs.applicationInsightsName
        keyVaultName: keyVault.outputs.name
        appCommandLine: 'entrypoint.sh'
        pythonVersion: '3.12'
        dbserverDomainName: db.outputs.dbserverDomainName
        dbserverUser: db.outputs.dbserverUser
        dbserverDatabaseName: db.outputs.dbserverDatabaseName
      }
    }
    
    // Caching server
    module redis 'redis.bicep' = {
      name: 'redis'
      scope: resourceGroup
      params: {
        name: replace('${take(prefix, 19)}-rds', '--', '-')
        location: location
        tags: tags
        keyVaultName: keyVault.outputs.name
        connStrKeyName: 'RedisConnectionString'
        passwordKeyName: 'RedisPassword'
        primaryKeyKeyName: 'RedisPrimaryKey'
        publicNetworkAccess: 'Enabled'
        skuFamily: 'C'
        skuCapacity: 1
        skuName: 'Standard'
        saveKeysToVault: true
      }
    }
    
    var secrets = [
      {
        name: 'DBSERVERPASSWORD'
        value: dbserverPassword
      }
      {
        name: 'SECRETKEY'
        value: secretKey
      }
    ]
    
    @batchSize(1)
    module keyVaultSecrets './core/security/keyvault-secret.bicep' = [for secret in secrets: {
      name: 'keyvault-secret-${secret.name}'
      scope: resourceGroup
      params: {
        keyVaultName: keyVault.outputs.name
        name: secret.name
        secretValue: secret.value
      }
    }]
    
    output AZURE_LOCATION string = location
    output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.endpoint
    output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name
    output APPLICATIONINSIGHTS_NAME string = monitoring.outputs.applicationInsightsName
    output BACKEND_URI string = web.outputs.uri
    
    output REDIS_ID string = redis.outputs.REDIS_ID
    output REDIS_HOST string = redis.outputs.REDIS_HOST
    
  5. Assicurarsi che tutte le modifiche vengano salvate, quindi usare il comando seguente per aggiornare le risorse di cui è stato effettuato il provisioning in Azure:

    azd provision
    

    Nota

    A seconda di molti fattori, l'aggiunta di un'istanza di cache di Azure per Redis alla distribuzione esistente potrebbe richiedere molto tempo. Nei test si sono verificati tempi di esecuzione superiori a 20 minuti. Finché non vengono visualizzati errori, consentire al processo di continuare fino al completamento.

  6. Al azd provision termine, aprire il portale di Azure, passare al gruppo di risorse per la distribuzione e nell'elenco dei servizi verificare di disporre di un'istanza di cache di Azure per Redis.

Questo conclude la guida introduttiva, tuttavia sono disponibili molti servizi di Azure che consentono di creare applicazioni più scalabili e pronte per la produzione. Un ottimo punto di partenza è conoscere Azure Gestione API, Frontdoor di Azure, Rete CDN di Azure e Azure Rete virtuale, per citarne alcuni.

Pulire le risorse

Pulire le risorse create dal modello eseguendo il comando azd down .

azd down

Il azd down comando elimina le risorse di Azure e il flusso di lavoro di GitHub Actions. Quando richiesto, accettare di eliminare tutte le risorse associate al gruppo di risorse.

È anche possibile eliminare la cartella azdtest oppure usarla come base per la propria applicazione modificando i file del progetto.