Exercício - Implantar um aplicativo Web
Na sua empresa de brinquedos, sua equipe de desenvolvimento de sites comprometeu a versão mais recente do site com seu repositório Git. Agora, você está pronto para atualizar seu pipeline para criar o site e implantá-lo no Serviço de Aplicativo do Azure.
Nesse processo, você executa as seguintes tarefas:
- Adicione um novo modelo de pipeline para o trabalho de compilação.
- Atualize o pipeline para incluir o trabalho de compilação.
- Adicione um novo teste de fumaça.
- Atualize o estágio de implantação para implantar o aplicativo.
- Executar o pipeline.
Adicionar um modelo de pipeline para o trabalho de compilação
Adicione uma nova definição de tarefa que contenha as etapas necessárias para criar o aplicativo de site.
Abra o Visual Studio Code.
Na pasta deploy/pipeline-templates, crie um novo 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 compilação para transformar o código-fonte do aplicativo de site em um arquivo compilado pronto para ser executado no Azure. Em seguida, o trabalho copia o artefato compilado para uma pasta de preparo temporária e o publica como um artefato de pipeline.
Guarde as alterações ao ficheiro.
Renomeie o primeiro estágio de pipeline e adicione um trabalho de compilação
Abra o arquivo azure-pipelines.yml na pasta deploy .
Modifique o estágio Lint . Renomeie-o 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
Guarde as alterações ao ficheiro.
Atualizar o arquivo de teste de fumaça
Os desenvolvedores do site adicionaram um ponto de extremidade de integridade ao site. Este ponto de extremidade verifica se o site está online e se pode chegar ao banco de dados. Aqui, você adiciona um novo teste de fumaça para invocar a verificação de integridade do pipeline de implantação.
Abra o arquivo Website.Tests.ps1 na pasta deploy .
Adicione um novo caso de teste que invoque a verificação de integridade. O caso de teste falhará se o código de resposta não for 200, o que indica sucesso.
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" } }
Guarde as alterações ao ficheiro.
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 seu 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
Guarde as alterações ao ficheiro.
Atualizar estágio de implantação
Abra o arquivo deploy.yml na pasta deploy/pipeline-templates .
Na definição do trabalho de implantação do estágio 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 de pipeline adicionadas posteriormente para trabalhar com seu banco de dados exigem que o sistema operacional Windows seja executado. Você pode usar diferentes pools de agentes para diferentes trabalhos em seu pipeline, para que os outros trabalhos continuem a usar o pool de agentes de pipeline do Ubuntu Linux.
Na etapa SaveDeploymentOutputs do trabalho Deploy, adicione uma nova 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
appServiceAppHostName
variável tem aisOutput=true
propriedade aplicada a ela, porque essa variável é usada na etapa de teste de fumaça. AappServiceAppName
variável é definida e usada no mesmo estágio e trabalho de pipeline. Então, ele não precisa daisOutput=true
configuração.No final do Implantar conteúdo do trabalho, adicione uma nova 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'
Nota
Tenha cuidado com o recuo do arquivo YAML, garantindo que a nova etapa de implantação seja recuada no mesmo nível da
DeployBicepFile
etapa. Se não tiver certeza, copie todo o conteúdo do arquivo deploy.yml do exemplo na próxima etapa.Observe que você não baixou explicitamente o artefato na definição de 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 confirme as alterações
Verifique se o arquivo deploy.yml se parece com o exemplo a seguir:
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'
Guarde as alterações ao ficheiro.
No terminal do Visual Studio Code, confirme e envie suas alterações para o repositório Git executando os seguintes comandos:
git add . git commit -m "Build and deploy website application" git push
Executar o pipeline
No seu navegador, vá para Pipelines.
Selecione a execução mais recente do seu pipeline.
Aguarde até que o estágio Build termine com êxito.
O pipeline pausa antes de executar o estágio Validar (Ambiente de Teste) porque o pipeline precisa de permissão para usar o grupo de variáveis ao qual o estágio se refere. Você precisa aprovar o acesso do pipeline ao grupo de variáveis, porque você está executando o pipeline neste projeto pela primeira vez. Ao executar o pipeline novamente, não é necessário aprovar o acesso ao mesmo grupo de variáveis.
Selecione Exibir.
Selecione Permitir.
Selecione Permitir.
O estágio Validar (Ambiente de Teste) é concluído com êxito.
O pipeline continua e o estágio Implantar (Ambiente de Teste) é concluído com êxito. Em seguida, o pipeline executa o estágio de teste de fumaça (ambiente de teste), mas o estágio de teste de fumaça falha.
Selecione o estágio Teste de fumaça (Ambiente de teste) para abrir o log do pipeline.
Selecione a etapa Executar testes de fumaça para exibir a seção associada do log de 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 o Banco de Dados SQL do Azure. O banco de dados ainda não está implantado ou configurado, e é por isso que o site não pode acessá-lo. No próximo exercício, corrija esse problema de configuração.