Exercício – implantar um aplicativo Web
Na sua empresa de brinquedos, a equipe de desenvolvimento do site confirmou a versão mais recente do site no seu repositório Git. Agora, você está pronto para atualizar seu pipeline para criar o site e para implantá-lo no Serviço de Aplicativo do Azure.
Nesse processo, execute as seguintes tarefas:
- Adicionar um modelo de pipeline para o trabalho de build.
- Atualize o pipeline para incluir o trabalho de build.
- Adicione um smoke test.
- Atualize a fase de implantação para implantar o aplicativo.
- Execute o pipeline.
Adicionar um modelo de pipeline para o trabalho de build
Adicione uma nova definição de trabalho que contém as etapas necessárias para criar o aplicativo de site.
Abra o Visual Studio Code.
Na pasta deploy/pipeline-templates, crie um arquivo chamado build.yml.
Adicione o seguinte conteúdo ao arquivo de modelo de pipeline build.yml:
jobs: - job: Build displayName: Build application and database pool: vmImage: windows-latest steps: # Build, copy, and publish the website. - task: DotNetCoreCLI@2 displayName: Build publishable website inputs: command: 'publish' publishWebProjects: true - task: CopyFiles@2 displayName: Copy publishable website inputs: sourceFolder: '$(Build.SourcesDirectory)/src/ToyCompany/ToyCompany.Website/bin' contents: '**/publish.zip' targetFolder: '$(Build.ArtifactStagingDirectory)/website' flattenFolders: true - task: PublishBuildArtifacts@1 displayName: Publish website as pipeline artifact inputs: pathToPublish: '$(Build.ArtifactStagingDirectory)/website' artifactName: 'website'
O trabalho executa uma etapa de build para transformar o código-fonte do aplicativo de site em um arquivo compilado pronto para ser executado no Azure. O trabalho então copia o artefato em uma pasta de preparo temporária e o publica como um artefato de pipeline.
Salve as alterações no arquivo.
Renomear a primeira fase do pipeline e adicionar um trabalho de build
Abra o arquivo azure-pipelines.yml na pasta deploy.
Modifique a fase lint. Renomeie-a para Build e adicione um trabalho de compilação que use o modelo de pipeline build.yml que você criou.
trigger: batch: true branches: include: - main pool: vmImage: ubuntu-latest stages: - stage: Build jobs: # Build the Visual Studio solution. - template: pipeline-templates/build.yml # Lint the Bicep file. - template: pipeline-templates/lint.yml # Deploy to the test environment. - template: pipeline-templates/deploy.yml parameters: environmentType: Test # Deploy to the production environment. - template: pipeline-templates/deploy.yml parameters: environmentType: Production
Salve as alterações no arquivo.
Atualizar o arquivo de smoke test
Os desenvolvedores do site adicionaram um ponto de extremidade de integridade ao site. Esse ponto de extremidade verifica se o site está online e se ele pode acessar o banco de dados. Aqui, você adiciona um smoke test para invocar a verificação de integridade do seu pipeline de implantação.
Abra o arquivo Website.Tests.ps1 na pasta implantar.
Adicione um caso de teste que invoca a verificação de integridade. O caso de teste falhará se o código de resposta não for 200, o que indica êxito.
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" } }
Salve as alterações no arquivo.
Adicionar saída ao arquivo Bicep
Você deseja adicionar uma etapa de implantação que publique seu site no Serviço de Aplicativo do Azure, mas a etapa de publicação requer o nome do aplicativo do Serviço de Aplicativo. Aqui, você expõe o nome do aplicativo como uma saída do arquivo Bicep.
Abra o arquivo main.bicep na pasta deploy.
No final do conteúdo do arquivo, adicione o nome do aplicativo do Serviço de Aplicativo como uma saída.
output appServiceAppName string = appServiceApp.name output appServiceAppHostName string = appServiceApp.properties.defaultHostName
Salve as alterações no arquivo.
Atualizar fase de implantação
Abra o arquivo deploy.yml na pasta deploy/pipeline-templates.
Na definição do trabalho de implantação da fase Implantar (próximo à linha 59), configure o trabalho para usar o pool de agentes hospedados do Windows:
- stage: Deploy_${{parameters.environmentType}} displayName: Deploy (${{parameters.environmentType}} Environment) jobs: - deployment: DeployWebsite displayName: Deploy website pool: vmImage: windows-latest variables: - group: ToyWebsite${{parameters.environmentType}} environment: ${{parameters.environmentType}} strategy:
Algumas das etapas do pipeline que posteriormente adicionadas para trabalhar com o banco de dados exigem a execução do sistema operacional Windows. Você pode usar pools de agente diferentes para trabalhos diferentes em seu pipeline para que os outros trabalhos continuem a usar o pool de agente de pipeline Ubuntu Linux.
Na etapa SaveDeploymentOutputs do trabalho Implantar, adicione uma variável de pipeline com o valor do nome do aplicativo da saída da implantação do Bicep:
- bash: | echo "##vso[task.setvariable variable=appServiceAppName]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppName.value')" echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')" name: SaveDeploymentOutputs displayName: Save deployment outputs into variables env: DEPLOYMENT_OUTPUTS: $(deploymentOutputs)
Observe que a variável
appServiceAppHostName
tem a propriedadeisOutput=true
aplicada a ela, pois essa variável é usada na fase de smoke test. A variávelappServiceAppName
é definida e usada na mesma fase do pipeline e no mesmo trabalho. Portanto, ela não precisa da configuraçãoisOutput=true
.No final do conteúdo do trabalho Implantar, adicione uma etapa para implantar o aplicativo no Serviço de Aplicativo do Azure:
steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: ToyWebsite${{parameters.environmentType}} deploymentName: $(Build.BuildNumber) location: ${{parameters.deploymentDefaultLocation}} resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) -reviewApiUrl $(ReviewApiUrl) -reviewApiKey $(ReviewApiKey) deploymentOutputs: deploymentOutputs - bash: | echo "##vso[task.setvariable variable=appServiceAppName]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppName.value')" echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')" name: SaveDeploymentOutputs displayName: Save deployment outputs into variables env: DEPLOYMENT_OUTPUTS: $(deploymentOutputs) - task: AzureRmWebAppDeployment@4 name: DeployWebsiteApp displayName: Deploy website inputs: appType: webApp ConnectionType: AzureRM azureSubscription: ToyWebsite${{parameters.environmentType}} ResourceGroupName: $(ResourceGroupName) WebAppName: $(appServiceAppName) Package: '$(Pipeline.Workspace)/website/publish.zip'
Observação
Tenha cuidado com o recuo do arquivo YAML, garantindo que a nova etapa de implantação seja recuada no mesmo nível que a etapa
DeployBicepFile
. Se você não tiver certeza, copie todo o conteúdo do arquivo deploy.yml do exemplo na próxima etapa.Observe que você não fez o download explicitamente do artefato na definição do pipeline. Como você usa um trabalho de implantação, o Azure Pipelines baixa automaticamente o artefato para você.
Verifique o conteúdo do arquivo deploy.yml e faça o commit de suas alterações
Verifique se o arquivo deploy.yml se parece com o seguinte exemplo:
parameters: - name: environmentType type: string - name: deploymentDefaultLocation type: string default: westus3 stages: - ${{ if ne(parameters.environmentType, 'Production') }}: - stage: Validate_${{parameters.environmentType}} displayName: Validate (${{parameters.environmentType}} Environment) jobs: - job: ValidateBicepCode displayName: Validate Bicep code variables: - group: ToyWebsite${{parameters.environmentType}} steps: - task: AzureResourceManagerTemplateDeployment@3 name: RunPreflightValidation displayName: Run preflight validation inputs: connectedServiceName: ToyWebsite${{parameters.environmentType}} location: ${{parameters.deploymentDefaultLocation}} deploymentMode: Validation resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) -reviewApiUrl $(ReviewApiUrl) -reviewApiKey $(ReviewApiKey) - ${{ if eq(parameters.environmentType, 'Production') }}: - stage: Preview_${{parameters.environmentType}} displayName: Preview (${{parameters.environmentType}} Environment) jobs: - job: PreviewAzureChanges displayName: Preview Azure changes variables: - group: ToyWebsite${{parameters.environmentType}} steps: - task: AzureCLI@2 name: RunWhatIf displayName: Run what-if inputs: azureSubscription: ToyWebsite${{parameters.environmentType}} scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | az deployment group what-if \ --resource-group $(ResourceGroupName) \ --template-file deploy/main.bicep \ --parameters environmentType=$(EnvironmentType) \ reviewApiUrl=$(ReviewApiUrl) \ reviewApiKey=$(ReviewApiKey) - stage: Deploy_${{parameters.environmentType}} displayName: Deploy (${{parameters.environmentType}} Environment) jobs: - deployment: DeployWebsite displayName: Deploy website pool: vmImage: windows-latest variables: - group: ToyWebsite${{parameters.environmentType}} environment: ${{parameters.environmentType}} strategy: runOnce: deploy: steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: ToyWebsite${{parameters.environmentType}} deploymentName: $(Build.BuildNumber) location: ${{parameters.deploymentDefaultLocation}} resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) -reviewApiUrl $(ReviewApiUrl) -reviewApiKey $(ReviewApiKey) deploymentOutputs: deploymentOutputs - bash: | echo "##vso[task.setvariable variable=appServiceAppName]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppName.value')" echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')" name: SaveDeploymentOutputs displayName: Save deployment outputs into variables env: DEPLOYMENT_OUTPUTS: $(deploymentOutputs) - task: AzureRmWebAppDeployment@4 name: DeployWebsiteApp displayName: Deploy website inputs: appType: webApp ConnectionType: AzureRM azureSubscription: ToyWebsite${{parameters.environmentType}} ResourceGroupName: $(ResourceGroupName) WebAppName: $(appServiceAppName) Package: '$(Pipeline.Workspace)/website/publish.zip' - stage: SmokeTest_${{parameters.environmentType}} displayName: Smoke Test (${{parameters.environmentType}} Environment) jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy_${{parameters.environmentType}}.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ] steps: - task: PowerShell@2 name: RunSmokeTests displayName: Run smoke tests inputs: targetType: inline script: | $container = New-PesterContainer ` -Path 'deploy/Website.Tests.ps1' ` -Data @{ HostName = '$(appServiceAppHostName)' } Invoke-Pester ` -Container $container ` -CI - task: PublishTestResults@2 name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'
Salve as alterações no arquivo.
No terminal do Visual Studio Code, faça commit e efetue push das alterações no repositório Git executando os seguintes comandos:
git add . git commit -m "Build and deploy website application" git push
Executar o pipeline
No navegador, acesse Pipelines.
Selecione a execução mais recente do pipeline.
Aguarde até que a fase de Build seja concluída com êxito.
O pipeline pausa antes de executar a fase Validar (Ambiente de Teste) porque o pipeline precisa de permissão para usar o grupo de variáveis ao qual a fase se refere. Você precisa aprovar o acesso do pipeline ao grupo de variáveis, pois está executando o pipeline neste projeto pela primeira vez. Quando você executar o pipeline novamente, não precisará aprovar o acesso ao mesmo grupo de variáveis.
Selecione Modo de Exibição.
Selecione Permitir.
Selecione Permitir.
A fase Validar (Ambiente de Teste) é concluída com êxito.
O pipeline continua e a fase Implantar (Ambiente de Teste) é concluída com êxito. O pipeline então executa a fase Smoke Test (Ambiente de Teste), mas a fase smoke test falha.
Selecione a fase Smoke Test (Ambiente de Teste) para abrir o log do pipeline.
Selecione a etapa Executar smoke tests para exibir a seção associada do log do pipeline.
Observe que o log de pipeline inclui a resposta da verificação de integridade. A resposta indica que há um problema com a comunicação do aplicativo com Banco de Dados SQL do Azure. O banco de dados ainda não foi implantado ou configurado, e é por isso que o site não consegue acessá-lo. No próximo exercício, você corrigirá esse problema de configuração.