Esercizio - Distribuire un'applicazione Web
Nell'azienda di giocattoli, il team di sviluppo di siti Web ha eseguito il commit della versione più recente del sito Web nel repository Git. È ora possibile aggiornare il flusso di lavoro per compilare il sito Web e distribuirlo nel Servizio app di Azure.
Operazioni che verranno eseguite durante il processo:
- Aggiungere un nuovo flusso di lavoro denominato per il processo di compilazione.
- Aggiornare il flusso di lavoro per includere il processo di compilazione.
- Aggiungere un nuovo smoke test.
- Aggiornare il processo di distribuzione per distribuire l'applicazione.
- Eseguire il flusso di lavoro.
Aggiungere un flusso di lavoro riutilizzabile per il processo di compilazione
In questo caso si aggiunge una nuova definizione del processo che contiene i passaggi necessari per compilare l'applicazione del sito Web.
Aprire Visual Studio Code.
Creare un nuovo file denominato build.yml nella cartella .github/workflows.
Aggiungere il contenuto seguente al file del flusso di lavoro build.yml:
name: build-website on: workflow_call: jobs: build-application: name: Build application runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install .NET Core uses: actions/setup-dotnet@v3 with: dotnet-version: 3.1 - name: Build publishable website run: | dotnet publish --configuration Release working-directory: ./src/ToyCompany/ToyCompany.Website - name: Zip publishable website run: | zip -r publish.zip . working-directory: ./src/ToyCompany/ToyCompany.Website/bin/Release/netcoreapp3.1/publish - name: Upload website as workflow artifact uses: actions/upload-artifact@v3 with: name: website path: ./src/ToyCompany/ToyCompany.Website/bin/Release/netcoreapp3.1/publish/publish.zip
Il processo installa .NET SDK per compilare la soluzione. Esegue quindi un passaggio di compilazione per trasformare il codice sorgente dell'applicazione del sito Web in un file compilato pronto per l'esecuzione in Azure. Il processo comprime poi l'artefatto compilato e lo carica come artefatto del flusso di lavoro.
Salvare le modifiche apportate al file .
Aggiungere il processo di compilazione al flusso di lavoro
Aprire il file workflow.yml.
Sotto la riga processi: e prima del processo linting aggiungere un nuovo processo denominato compilazione che usa il flusso di lavoro riutilizzabile appena definito:
name: deploy-toy-website-end-to-end concurrency: toy-company on: push: branches: - main workflow_dispatch: permissions: id-token: write contents: read jobs: # Build the application and database. build: uses: ./.github/workflows/build.yml # Lint the Bicep file. lint: uses: ./.github/workflows/lint.yml
Aggiornare il processo deploy-test in modo che dipenda dal nuovo processo di compilazione:
# Deploy to the test environment. deploy-test: uses: ./.github/workflows/deploy.yml needs: [build, lint] with: environmentType: Test resourceGroupName: ToyWebsiteTest reviewApiUrl: https://sandbox.contoso.com/reviews secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} reviewApiKey: ${{ secrets.REVIEW_API_KEY_TEST }}
Aggiornare il processo di distribuzione e produzione in modo da dipendere anche dai processi di compilazione e lint.
# Deploy to the production environment. deploy-production: uses: ./.github/workflows/deploy.yml needs: - lint - build - deploy-test with: environmentType: Production resourceGroupName: ToyWebsiteProduction reviewApiUrl: https://api.contoso.com/reviews secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} reviewApiKey: ${{ secrets.REVIEW_API_KEY_PRODUCTION }}
Poiché la distribuzione di produzione dipende dalla distribuzione di test, non è strettamente necessario specificare le dipendenze. È tuttavia consigliabile essere espliciti, per evitare che il flusso di lavoro venga eseguito in modo errato se si riordinano o rimuovono i processi o gli ambienti.
Si noti che si specifica l'elenco
needs
in due modi diversi: le dipendenze della distribuzione dell'ambiente di test sono elencate in una sola riga e quelle dell'ambiente di produzione tramite un elenco su più righe. I due approcci sono equivalenti.Salvare le modifiche apportate al file.
Aggiornare il file di smoke test
Gli sviluppatori del sito Web hanno aggiunto un endpoint di integrità al sito Web. Questo endpoint verifica che il sito Web sia online e che possa raggiungere il database. In questo caso si aggiunge un nuovo smoke test per richiamare il controllo di integrità dal flusso di lavoro di distribuzione.
Aprire il file Website.Tests.ps1 nella cartella deploy.
Aggiungere un nuovo test case che richiama il controllo di integrità. Il test case ha esito negativo se il codice di risposta è diverso da 200, che indica l'esito positivo:
param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $HostName ) Describe 'Toy Website' { It 'Serves pages over HTTPS' { $request = [System.Net.WebRequest]::Create("https://$HostName/") $request.AllowAutoRedirect = $false $request.GetResponse().StatusCode | Should -Be 200 -Because "the website requires HTTPS" } It 'Does not serves pages over HTTP' { $request = [System.Net.WebRequest]::Create("http://$HostName/") $request.AllowAutoRedirect = $false $request.GetResponse().StatusCode | Should -BeGreaterOrEqual 300 -Because "HTTP is not secure" } It 'Returns a success code from the health check endpoint' { $response = Invoke-WebRequest -Uri "https://$HostName/health" -SkipHttpErrorCheck Write-Host $response.Content $response.StatusCode | Should -Be 200 -Because "the website and configuration should be healthy" } }
Salvare le modifiche apportate al file.
Aggiungere l'output al file Bicep
Si aggiungerà presto un passaggio di distribuzione che pubblica il sito Web nel Servizio app di Azure. Il passaggio di pubblicazione richiede il nome dell'app del Servizio app. Si espone quindi il nome dell'app come output del file Bicep.
Aprire il file main.bicep nella cartella deploy.
Alla fine del contenuto del file aggiungere il nome dell'app del Servizio app come output:
output appServiceAppName string = appServiceApp.name output appServiceAppHostName string = appServiceApp.properties.defaultHostName
Salvare le modifiche apportate al file .
Aggiornare il processo di distribuzione per propagare l'output
A questo punto, è necessario aggiornare il processo di distribuzione per accettare il valore dell'output dalla distribuzione Bicep e renderlo disponibile per il resto del flusso di lavoro.
Aprire il file deploy.yml nella cartella .github/workflows.
Nella definizione del processo di distribuzione aggiungere un nuovo output per
appServiceAppName
:deploy: needs: validate environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest outputs: appServiceAppName: ${{ steps.deploy.outputs.appServiceAppName }} appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }} steps:
Nota
Quando si inizia a usare il file YAML in Visual Studio Code, è possibile che vengano visualizzate alcune righe ondulate rosse che segnalano un problema. Ciò è dovuto al fatto che l'estensione Visual Studio Code per i file YAML talvolta ipotizza in modo errato lo schema del file.
È possibile ignorare i problemi segnalati dall'estensione. In alternativa, se lo si desidera è possibile aggiungere il codice seguente all'inizio del file per evitare che l'estensione venga ipotizzata:
# yaml-language-server: $schema=./deploy.yml
Aggiungere un processo per distribuire il sito Web
Sotto la definizione del processo di distribuzione e sopra la definizione del processo smoke test definire un nuovo processo per distribuire il sito Web in Servizio app:
deploy-website: needs: deploy environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/webapps-deploy@v2 name: Deploy website with: app-name: ${{ needs.deploy.outputs.appServiceAppName }} package: website/publish.zip
Nota
Prestare attenzione ai rientri del file YAML, assicurandosi che il rientro del nuovo processo sia allo stesso livello del processo
deploy
. Se non si è sicuri, copiare l'intero contenuto del file deploy.yml dall'esempio nel passaggio successivo.Si noti che il processo dipende dal processo di distribuzione usando la parola chiave
needs
. Questa dipendenza garantisce che il sito Web non venga distribuito finché l'infrastruttura non è pronta. Ciò consente inoltre al processo di accedere all'outputappServiceAppName
del processo di distribuzione.Si noti anche che questo processo include passaggi per scaricare gli artefatti del flusso di lavoro e accedere ad Azure. Ogni processo viene eseguito nel proprio strumento di esecuzione, quindi deve essere autonomo.
Salvare le modifiche apportate al file .
Verificare il contenuto del file deploy.yml ed eseguire il commit delle modifiche
Verificare che il file deploy.yml sia simile all'esempio seguente:
name: deploy on: workflow_call: inputs: environmentType: required: true type: string resourceGroupName: required: true type: string reviewApiUrl: required: true type: string secrets: AZURE_CLIENT_ID: required: true AZURE_TENANT_ID: required: true AZURE_SUBSCRIPTION_ID: required: true reviewApiKey: required: true jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - if: inputs.environmentType != 'Production' uses: azure/arm-deploy@v1 name: Run preflight validation with: deploymentName: ${{ github.run_number }} resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} reviewApiUrl=${{ inputs.reviewApiUrl }} reviewApiKey=${{ secrets.reviewApiKey }} deploymentMode: Validate - if: inputs.environmentType == 'Production' uses: azure/arm-deploy@v1 name: Run what-if with: failOnStdErr: false resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} reviewApiUrl=${{ inputs.reviewApiUrl }} reviewApiKey=${{ secrets.reviewApiKey }} additionalArguments: --what-if deploy: needs: validate environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest outputs: appServiceAppName: ${{ steps.deploy.outputs.appServiceAppName }} appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }} steps: - uses: actions/checkout@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/arm-deploy@v1 id: deploy name: Deploy Bicep file with: failOnStdErr: false deploymentName: ${{ github.run_number }} resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} reviewApiUrl=${{ inputs.reviewApiUrl }} reviewApiKey=${{ secrets.reviewApiKey }} deploy-website: needs: deploy environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/webapps-deploy@v2 name: Deploy website with: app-name: ${{ needs.deploy.outputs.appServiceAppName }} package: website/publish.zip smoke-test: runs-on: ubuntu-latest needs: deploy steps: - uses: actions/checkout@v3 - run: | $container = New-PesterContainer ` -Path 'deploy/Website.Tests.ps1' ` -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' } Invoke-Pester ` -Container $container ` -CI name: Run smoke tests shell: pwsh
Salvare le modifiche apportate al file.
Nel terminale di Visual Studio Code eseguire il commit e il push delle modifiche nel repository Git usando i comandi seguenti:
git add . git commit -m "Build and deploy website application" git push
Questa è la prima volta che si esegue il push in questo repository, quindi è possibile che venga richiesto di accedere.
In Windows digitare 1 per eseguire l'autenticazione usando un Web browser e premere INVIO.
In macOS selezionare Autorizza.
Verrà visualizzata una finestra del browser. Potrebbe essere necessario accedere di nuovo a GitHub. Seleziona Autorizza.
Eseguire il flusso di lavoro
Nel browser passare ad Azioni.
La prima esecuzione del flusso di lavoro, denominata Initial commit, viene visualizzata come errore. GitHub ha eseguito automaticamente il flusso di lavoro al momento della creazione del repository. L'operazione non è riuscita perché i segreti non erano pronti in quel momento. È possibile ignorare questo errore.
Selezionare il flusso di lavoro deploy-toy-website-end-to-end.
Selezionare l'esecuzione più recente del flusso di lavoro.
Attendere il completamento del processo di compilazione.
Attendere il corretto completamento del processo deploy-test / deploy.
Alcuni avvisi sono elencati nel pannello Annotazioni. Tutti questi avvisi sono dovuti al modo in cui Bicep scrive i messaggi informativi nel log del flusso di lavoro. È possibile ignorare questi avvisi.
Il flusso di lavoro esegue quindi il processo deploy-test / smoke-test ma lo smoke test ha esito negativo:
Selezionare il processo deploy-test / smoke-test per aprire il log del flusso di lavoro.
Selezionare il passaggio Run smoke tests per visualizzare la sezione associata del log del flusso di lavoro:
Si noti che il log del flusso di lavoro indica che il sito Web e la configurazione non sono integri. Si è verificato un problema di comunicazione dell'applicazione con il database SQL di Azure. Non è stato ancora distribuito o configurato un database, motivo per cui il sito Web non può accedervi. Questo problema verrà risolto a breve.