Condividi tramite


Automatizzare tutto (creazione di app cloud Real-World con Azure)

di Rick Anderson, Tom Dykstra

Scaricare correzione del progetto o scaricare E-book

L'e-book Building Real World Cloud Apps with Azure è basato su una presentazione sviluppata da Scott Guthrie. Spiega 13 modelli e procedure che consentono di sviluppare app Web per il cloud con successo. Per un'introduzione al e-book, vedere il primo capitolo.

I primi tre modelli verranno effettivamente applicati a qualsiasi progetto di sviluppo software, ma soprattutto ai progetti cloud. Questo modello riguarda l'automazione delle attività di sviluppo. È un argomento importante perché i processi manuali sono lenti e soggetti a errori; l'automazione del numero più elevato possibile consente di configurare un flusso di lavoro veloce, affidabile e agile. È particolarmente importante per lo sviluppo del cloud perché è possibile automatizzare facilmente molte attività difficili o impossibili da automatizzare in un ambiente locale. Ad esempio, è possibile configurare ambienti di test interi, tra cui il nuovo server Web e le macchine virtuali back-end, i database, l'archiviazione BLOB (archiviazione file), le code e così via.

Flusso di lavoro DevOps

Sempre più si sente il termine "DevOps". Il termine sviluppato da un riconoscimento che è necessario integrare attività di sviluppo e operazioni per sviluppare software in modo efficiente. Il tipo di flusso di lavoro che si vuole abilitare è quello in cui è possibile sviluppare un'app, distribuirla, apprendere dall'utilizzo di produzione, modificarla in risposta a ciò che si è appreso e ripetere il ciclo in modo rapido e affidabile.

Alcuni team di sviluppo cloud riusciti distribuiscono più volte al giorno in un ambiente live. Il team di Azure ha usato per distribuire un aggiornamento principale ogni 2-3 mesi, ma ora rilascia aggiornamenti secondari ogni 2-3 giorni e versioni principali ogni 2-3 settimane. Entrare in questa cadenza aiuta davvero a essere reattivo al feedback dei clienti.

A tale scopo, è necessario abilitare un ciclo di sviluppo e distribuzione ripetibile, affidabile, prevedibile e con tempo di ciclo ridotto.

Flusso di lavoro DevOps

In altre parole, il periodo di tempo compreso tra quando si ha un'idea per una funzionalità e quando i clienti lo usano e fornire feedback devono essere il più breve possibile. I primi tre modelli, automatizzare tutto, controllo del codice sorgente e integrazione continua e recapito, sono tutte procedure consigliate per abilitare tale tipo di processo.

Script di gestione di Azure

Nell'introduzione a questo e-book è stata visualizzata la console basata sul Web, il portale di gestione di Azure. Il portale di gestione consente di monitorare e gestire tutte le risorse distribuite in Azure. È un modo semplice per creare ed eliminare servizi come app Web e macchine virtuali, configurare tali servizi, monitorare l'operazione del servizio e così via. È un ottimo strumento, ma l'uso è un processo manuale. Se si sviluppa un'applicazione di produzione di qualsiasi dimensione e in particolare in un ambiente team, è consigliabile passare attraverso l'interfaccia utente del portale per apprendere ed esplorare Azure e automatizzare i processi che si eseguiranno ripetitivamente.

Quasi tutto ciò che è possibile eseguire manualmente nel portale di gestione o da Visual Studio può essere eseguito anche chiamando l'API di gestione REST. È possibile scrivere script usando Windows PowerShell oppure è possibile usare un framework open source, ad esempio Chef o Puppet. È anche possibile usare lo strumento da riga di comando Bash in un ambiente Mac o Linux. Azure dispone di API di scripting per tutti gli ambienti diversi e include un'API di gestione .NET nel caso in cui si voglia scrivere codice anziché script.

Per l'app Correzione dell'app sono stati creati alcuni script Windows PowerShell che automatizzano i processi di creazione di un ambiente di test e la distribuzione del progetto in tale ambiente e verranno esaminati alcuni dei contenuti di tali script.

Script di creazione dell'ambiente

Il primo script che verrà esaminato è denominato New-AzureWebsiteEnv.ps1. Crea un ambiente di Azure in cui è possibile distribuire l'app Correzione it per il test. Le attività principali eseguite da questo script sono le seguenti:

  • Creare un'app Web.
  • Creare un account di archiviazione. Obbligatorio per i BLOB e le code, come si vedrà nei capitoli successivi.
  • Creare un server database SQL e due database: un database applicazione e un database di appartenenza.
  • Archiviare le impostazioni in Azure che l'app userà per accedere all'account di archiviazione e ai database.
  • Creare file di impostazioni che verranno usati per automatizzare la distribuzione.

Eseguire lo script

Nota

Questa parte del capitolo mostra esempi di script e comandi immessi per eseguirli. Questa demo e non fornisce tutto ciò che è necessario conoscere per eseguire gli script. Per istruzioni dettagliate su come eseguire le operazioni, vedere Appendice: Correzione dell'applicazione di esempio.

Per eseguire uno script di PowerShell che gestisce i servizi di Azure, è necessario installare la console di Azure PowerShell e configurarla per usare la sottoscrizione di Azure. Dopo aver configurato, è possibile eseguire lo script di creazione dell'ambiente Correzione it con un comando simile al seguente:

.\New-AzureWebsiteEnv.ps1 -Name <websitename> -SqlDatabasePassword <password>

Il Name parametro specifica il nome da usare quando si creano gli account di database e di archiviazione e il SqlDatabasePassword parametro specifica la password per l'account amministratore che verrà creato per database SQL. Esistono altri parametri che è possibile usare in un secondo momento.

Finestra di PowerShell

Al termine dello script, è possibile visualizzare nel portale di gestione ciò che è stato creato. Sono disponibili due database:

Database

Un account di archiviazione:

Account di archiviazione

E un'app Web:

Sito Web

Nella scheda Configura per l'app Web è possibile notare che include le impostazioni dell'account di archiviazione e le stringhe di connessione del database SQL configurate per l'app Correzione it.

appSettings e connectionStrings

La cartella Di automazione contiene ora anche un <file websitename.pubxml>. Questo file archivia le impostazioni che MSBuild userà per distribuire l'applicazione nell'ambiente di Azure appena creato. Ad esempio:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <SiteUrlToLaunchAfterPublish>http://fixitdemo.azurewebsites.net</SiteUrlToLaunchAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <MSDeployServiceURL>waws-prod-bay-003.publish.azurewebsites.windows.net:443</MSDeployServiceURL>
    <DeployIisAppPath>fixitdemo</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
    <EnableMSDeployBackup>True</EnableMSDeployBackup>
    <UserName>$fixitdemo</UserName>
    <PublishDatabaseSettings></PublishDatabaseSettings>
  </PropertyGroup>
</Project>

Come si può notare, lo script ha creato un ambiente di test completo e l'intero processo viene eseguito in circa 90 secondi.

Se un altro utente del team vuole creare un ambiente di test, può solo eseguire lo script. Non solo è veloce, ma anche possono essere sicuri che usano un ambiente identico a quello usato. Non è stato possibile essere abbastanza sicuri di che se tutti gli elementi sono stati configurato manualmente usando l'interfaccia utente del portale di gestione.

Un'occhiata agli script

Esistono in realtà tre script che eseguono questo lavoro. Si chiama una dalla riga di comando e usa automaticamente le altre due per eseguire alcune delle attività:

  • New-AzureWebSiteEnv.ps1 è lo script principale.

    • New-AzureStorage.ps1 crea l'account di archiviazione.
    • New-AzureSql.ps1 crea i database.

Parametri nello script principale

Lo script principale, New-AzureWebSiteEnv.ps1, definisce diversi parametri:

[CmdletBinding(PositionalBinding=$True)]
Param(
    [Parameter(Mandatory = $true)]
    [ValidatePattern("^[a-z0-9]*$")]
    [String]$Name,                             
    [String]$Location = "West US",             
    [String]$SqlDatabaseUserName = "dbuser",   
    [String]$SqlDatabasePassword,              
    [String]$StartIPAddress,                   
    [String]$EndIPAddress                      
    )

Sono necessari due parametri:

  • Nome dell'app Web creata dallo script. Viene usato anche per l'URL: <name>.azurewebsites.net.)
  • Password per il nuovo utente amministrativo del server di database creato dallo script.

I parametri facoltativi consentono di specificare il percorso del data center (impostazione predefinita su "Stati Uniti occidentali"), il nome amministratore del server di database (impostazione predefinita "dbuser") e una regola del firewall per il server di database.

Creare l'app Web

La prima cosa che lo script crea l'app Web chiamando il New-AzureWebsite cmdlet, passando il nome dell'app Web e i valori dei parametri di posizione:

# Create a new website
$website = New-AzureWebsite -Name $Name -Location $Location -Verbose

Creare l'account di archiviazione

Lo script principale esegue quindi lo script New-AzureStorage.ps1 , specificando "*<websitename>*storage" per il nome dell'account di archiviazione e la stessa posizione del data center dell'app Web.

$storageAccountName = $Name + "storage"
 
$storage = $scriptPath\New-AzureStorage.ps1" -Name $storageAccountName -Location $Location

New-AzureStorage.ps1 chiama il cmdlet per creare l'account New-AzureStorageAccount di archiviazione e restituisce il nome dell'account e i valori delle chiavi di accesso. L'applicazione richiederà questi valori per accedere ai BLOB e alle code nell'account di archiviazione.

# Create a new storage account
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
 
# Get the access key of the storage account
$key = Get-AzureStorageKey -StorageAccountName $Name
 
# Generate the connection string of the storage account
$connectionString = "BlobEndpoint=http://$Name.blob.core.windows.net/;QueueEndpoint=http://$Name.queue.core.windows.net/;TableEndpoint=http://$Name.table.core.windows.net/;AccountName=$Name;AccountKey=$primaryKey"
 
#Return a hashtable of storage account values
Return @{AccountName = $Name; AccessKey = $key.Primary; ConnectionString = $connectionString}

Potrebbe non essere sempre necessario creare un nuovo account di archiviazione; è possibile migliorare lo script aggiungendo un parametro che lo indirizza facoltativamente all'uso di un account di archiviazione esistente.

Creare i database

Lo script principale esegue quindi lo script di creazione del database, New-AzureSql.ps1, dopo aver configurato i nomi delle regole del database e del firewall predefiniti:

$sqlAppDatabaseName = "appdb"
$sqlMemberDatabaseName = "memberdb"
$sqlDatabaseServerFirewallRuleName = $Name + "rule"
# Create a SQL Azure database server, app and member databases
$sql = $scriptPath\New-AzureSql.ps1 `
    -AppDatabaseName $sqlAppDatabaseName `
    -MemberDatabaseName $sqlMemberDatabaseName `
    -UserName $SqlDatabaseUserName `
    -Password $SqlDatabasePassword `
    -FirewallRuleName $sqlDatabaseServerFirewallRuleName `
    -StartIPAddress $StartIPAddress `
    -EndIPAddress $EndIPAddress `
    -Location $Location

Lo script di creazione del database recupera l'indirizzo IP del computer di sviluppo e imposta una regola del firewall in modo che il computer di sviluppo possa connettersi e gestire il server. Lo script di creazione del database esegue quindi diversi passaggi per configurare i database:

  • Crea il server usando il New-AzureSqlDatabaseServer cmdlet.

    $databaseServer = New-AzureSqlDatabaseServer -AdministratorLogin $UserName -AdministratorLoginPassword $Password -Location $Location
    
  • Crea regole del firewall per abilitare il computer di sviluppo per gestire il server e consentire all'app Web di connettersi.

    # Create a SQL Azure database server firewall rule for the IP address of the machine in which this script will run
    # This will also allowlist all the Azure IP so that the website can access the database server
    New-AzureSqlDatabaseServerFirewallRule -ServerName $databaseServerName -RuleName $FirewallRuleName -StartIpAddress $StartIPAddress 
    -EndIpAddress $EndIPAddress -Verbose
    New-AzureSqlDatabaseServerFirewallRule -ServerName $databaseServer.ServerName -AllowAllAzureServices 
    -RuleName "AllowAllAzureIP" -Verbose
    
  • Crea un contesto di database che include il nome e le credenziali del server usando il New-AzureSqlDatabaseServerContext cmdlet.

    # Create a database context which includes the server name and credential
    # These are all local operations. No API call to Azure
    $credential = New-PSCredentialFromPlainText -UserName $UserName -Password $Password
    $context = New-AzureSqlDatabaseServerContext -ServerName $databaseServer.ServerName -Credential $credential
    

    New-PSCredentialFromPlainText è una funzione nello script che chiama il ConvertTo-SecureString cmdlet per crittografare la password e restituisce un PSCredential oggetto, lo stesso tipo restituito dal Get-Credential cmdlet.

  • Crea il database dell'applicazione e il database di appartenenza usando il New-AzureSqlDatabase cmdlet .

    # Use the database context to create app database
    New-AzureSqlDatabase -DatabaseName $AppDatabaseName -Context $context -Verbose
     
    # Use the database context to create member database
    New-AzureSqlDatabase -DatabaseName $MemberDatabaseName -Context $context -Verbose
    
  • Chiama una funzione definita localmente per creare una stringa di connessione per ogni database. L'applicazione userà queste stringhe di connessione per accedere ai database.

    $appDatabaseConnectionString = Get-SQLAzureDatabaseConnectionString -DatabaseServerName $databaseServerName -DatabaseName $AppDatabaseName -UserName $UserName -Password $Password
    $memberDatabaseConnectionString = Get-SQLAzureDatabaseConnectionString -DatabaseServerName $databaseServerName -DatabaseName $MemberDatabaseName -UserName $UserName -Password $Password
    

    Get-SQLAzureDatabaseConnectionString è una funzione definita nello script che crea la stringa di connessione dai valori dei parametri forniti.

    Function Get-SQLAzureDatabaseConnectionString
    {
        Param(
            [String]$DatabaseServerName,
            [String]$DatabaseName,
            [String]$UserName,
            [String]$Password
        )
    
        Return "Server=tcp:$DatabaseServerName.database.windows.net,1433;Database=$DatabaseName;User ID=$UserName@$DatabaseServerName;Password=$Password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;"
    }
    
  • Restituisce una tabella hash con il nome del server di database e le stringhe di connessione.

    Return @{ `
        Server = $databaseServer.ServerName; UserName = $UserName; Password = $Password; `
        AppDatabase = @{Name = $AppDatabaseName; ConnectionString = $appDatabaseConnectionString}; `
        MemberDatabase = @{Name = $MemberDatabaseName; ConnectionString = $memberDatabaseConnectionString} `
    }
    

L'app Fix It usa l'appartenenza separata e i database dell'applicazione. È anche possibile inserire sia l'appartenenza che i dati dell'applicazione in un singolo database.

Impostazioni dell'app store e stringhe di connessione

Azure offre una funzionalità che consente di archiviare le impostazioni e le stringhe di connessione che eseguono automaticamente l'override di ciò che viene restituito all'applicazione quando tenta di leggere le appSettings raccolte o connectionStrings nel file Web.config. Si tratta di un'alternativa all'applicazione di trasformazioniWeb.config durante la distribuzione. Per altre informazioni, vedere Archiviare i dati sensibili in Azure più avanti in questo e-book.

Lo script di creazione dell'ambiente archivia in Azure tutti i appSettings valori e connectionStrings che l'applicazione deve accedere all'account di archiviazione e ai database quando viene eseguito in Azure.

# Configure app settings for storage account and New Relic
$appSettings = @{ `
    "StorageAccountName" = $storageAccountName; `
    "StorageAccountAccessKey" = $storage.AccessKey; `
    "COR_ENABLE_PROFILING" = "1"; `
    "COR_PROFILER" = "{71DA0A04-7777-4EC6-9643-7D28B46A8A41}"; `
    "COR_PROFILER_PATH" = "C:\Home\site\wwwroot\newrelic\NewRelic.Profiler.dll"; `
    "NEWRELIC_HOME" = "C:\Home\site\wwwroot\newrelic" `
}
# Configure connection strings for appdb and ASP.NET member db
$connectionStrings = ( `
    @{Name = $sqlAppDatabaseName; Type = "SQLAzure"; ConnectionString = $sql.AppDatabase.ConnectionString}, `
    @{Name = "DefaultConnection"; Type = "SQLAzure"; ConnectionString = $sql.MemberDatabase.ConnectionString}
)
# Add the connection string and storage account name/key to the website
Set-AzureWebsite -Name $Name -AppSettings $appSettings -ConnectionStrings $connectionStrings

New Relic è un framework di telemetria illustrato nel capitolo Monitoraggio e telemetria . Lo script di creazione dell'ambiente riavvia anche l'app Web per assicurarsi che selezioni le impostazioni di New Relic.

# Restart the website to let New Relic hook kick in
Restart-AzureWebsite -Name $websiteName

Preparazione per la distribuzione

Al termine del processo, lo script di creazione dell'ambiente chiama due funzioni per creare file che verranno usati dallo script di distribuzione.

Una di queste funzioni crea un profilo di pubblicazione (<file websitename.pubxml>). Il codice chiama l'API REST di Azure per ottenere le impostazioni di pubblicazione e salva le informazioni in un file con estensione publishsettings . Usa quindi le informazioni del file insieme a un file modello (pubxml.template) per creare il file .pubxml che contiene il profilo di pubblicazione. Questo processo in due passaggi simula le operazioni eseguite in Visual Studio: scaricare un file con estensione publishsettings e importarlo per creare un profilo di pubblicazione.

L'altra funzione usa un altro file modello (website-environment.template) per creare un file diwebsite-environment.xml che contiene le impostazioni che verranno usate dallo script di distribuzione insieme al file .pubxml .

Risoluzione dei problemi e gestione degli errori

Gli script sono come programmi: possono avere esito negativo e quando vogliono sapere quanto si può sapere sull'errore e su cosa ha causato. Per questo motivo, lo script di creazione dell'ambiente modifica il valore della VerbosePreference variabile da SilentlyContinue a Continue in modo che vengano visualizzati tutti i messaggi dettagliati. Modifica anche il valore della ErrorActionPreference variabile da Continue a Stop, in modo che lo script si arresti anche quando rileva errori non irreversibili:

# Set the output level to verbose and make the script stop on error
$VerbosePreference = "Continue"
$ErrorActionPreference = "Stop"

Prima di eseguire qualsiasi operazione, lo script archivia l'ora di inizio in modo che possa calcolare il tempo trascorso al termine:

# Mark the start time of the script execution
$startTime = Get-Date

Al termine del lavoro, lo script visualizza il tempo trascorso:

# Mark the finish time of the script execution
$finishTime = Get-Date
# Output the time consumed in seconds
Write-Output ("Total time used (seconds): {0}" -f ($finishTime - $startTime).TotalSeconds)

E per ogni operazione chiave lo script scrive messaggi dettagliati, ad esempio:

Write-Verbose "[Start] creating $websiteName website in $Location location"
$website = New-AzureWebsite -Name $websiteName -Location $Location -Verbose
Write-Verbose "[Finish] creating $websiteName website in $Location location"

Script di distribuzione

Che cosa fa lo script New-AzureWebsiteEnv.ps1 per la creazione dell'ambiente, lo script Publish-AzureWebsite.ps1 viene usato per la distribuzione dell'applicazione.

Lo script di distribuzione ottiene il nome dell'app Web dal file website-environment.xml creato dallo script di creazione dell'ambiente.

[Xml]$envXml = Get-Content "$scriptPath\website-environment.xml"
$websiteName = $envXml.environment.name

Ottiene la password dell'utente di distribuzione dal file con estensione publishsettings :

[Xml]$xml = Get-Content $scriptPath\$websiteName.publishsettings 
$password = $xml.publishData.publishProfile.userPWD[0]
$publishXmlFile = Join-Path $scriptPath -ChildPath ($websiteName + ".pubxml")

Esegue il comando MSBuild che compila e distribuisce il progetto:

& "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" $ProjectFile `
    /p:VisualStudioVersion=12.0 `
    /p:DeployOnBuild=true `
    /p:PublishProfile=$publishXmlFile `
    /p:Password=$password

E se è stato specificato il Launch parametro nella riga di comando, chiama il cmdlet per aprire il Show-AzureWebsite browser predefinito all'URL del sito Web.

If ($Launch)
{
    Show-AzureWebsite -Name $websiteName
}

È possibile eseguire lo script di distribuzione con un comando simile al seguente:

.\Publish-AzureWebsite.ps1 ..\MyFixIt\MyFixIt.csproj -Launch

Al termine, il browser si apre con il sito in esecuzione nel cloud all'URL <websitename>.azurewebsites.net .

Correzione dell'app distribuita in Windows Azure

Riepilogo

Con questi script è possibile assicurarsi che gli stessi passaggi vengano sempre eseguiti nello stesso ordine usando le stesse opzioni. In questo modo, ogni sviluppatore del team non perde qualcosa o crea qualcosa o distribuisce qualcosa di personalizzato nel proprio computer che in realtà non funzionerà allo stesso modo nell'ambiente di un altro membro del team o nell'ambiente di produzione.

In modo analogo, è possibile automatizzare la maggior parte delle funzioni di gestione di Azure che è possibile eseguire nel portale di gestione usando l'API REST, gli script Windows PowerShell, un'API del linguaggio .NET o un'utilità Bash che è possibile eseguire in Linux o Mac.

Nel capitolo successivo verrà esaminato il codice sorgente e verrà spiegato perché è importante includere gli script nel repository del codice sorgente.

Risorse