Exercício – Adicionar uma fase de teste ao pipeline
A equipe de segurança da empresa de brinquedos pediu para você verificar se o site só é acessível via HTTPS. Neste exercício, você configurará seu pipeline para executar um teste de fumaça que verifica se o requisito da equipe de segurança foi atendido.
Durante o processo, você vai:
- Adicionar um script de teste ao repositório.
- Atualizar a definição de pipeline para adicionar uma fase de teste.
- Executar o pipeline e observar a falha do teste.
- Corrigir o arquivo Bicep e observar a execução de pipeline bem-sucedida.
Adicionar um script de teste
Primeiro, você adicionará um script de teste para verificar se o site está acessível quando HTTPS é usado e não acessível quando o protocolo HTTP não seguro é usado.
No Visual Studio Code, crie um novo arquivo na pasta de implantação . Nomeie o arquivo Website.Tests.ps1.
Cole o seguinte código de teste no arquivo:
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" } }Este código é um arquivo de teste do Pester. Ele requer um parâmetro chamado
$HostName. Ele executa dois testes em relação ao nome do host:- Tente se conectar ao site via HTTPS. O teste será aprovado se o servidor responder com um código de status de resposta HTTP entre 200 e 299, o que indica uma conexão bem-sucedida.
- Tente se conectar ao site via HTTP. O teste é aprovado se o servidor responde com um código de status de resposta HTTP igual a 300 ou superior.
Para fins deste exercício, você não precisa entender os detalhes do arquivo de teste e como ele funciona. Se estiver interessado, saiba mais verificando o recurso listado no resumo do módulo.
Publicar a saída do arquivo Bicep como uma variável de saída da fase
O script de teste criado nas etapas anteriores exige um nome de host para teste. O arquivo Bicep já inclui uma saída, mas, para usá-lo nos smoke tests, você precisa publicá-lo como uma variável de saída da fase.
No Visual Studio Code, abra o arquivo azure-pipelines.yml na pasta deploy.
Na fase Implantar, atualize a etapa de implantação para publicar as saídas em uma variável:
name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: $(ServiceConnectionName) deploymentName: $(Build.BuildNumber) location: $(deploymentDefaultLocation) resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) deploymentOutputs: deploymentOutputsO processo de implantação ainda usa a mesma tarefa que antes, mas as saídas das implantações agora são armazenadas em uma variável de pipeline chamada
deploymentOutputs. A variável de saída é formatada como JSON.Para converter as saídas formatadas como JSON em variáveis de pipeline, adicione a seguinte etapa de script abaixo da etapa de implantação:
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)Se a implantação for concluída com êxito, o script acessará o valor de cada saída da implantação do Bicep. O script usa a ferramenta
jqpara acessar a parte relevante da saída JSON. Em seguida, o valor é publicado em uma variável de saída de estágio que tem o mesmo nome que a saída de implantação do Bicep.Observação
O Pester e o jq são pré-instalados em agentes hospedados pela Microsoft para o Azure Pipelines. Você não precisa fazer nada especial para usá-los em uma etapa de script.
Salve o arquivo.
Adicionar uma fase de smoke test ao pipeline
Agora você pode adicionar uma fase de smoke test que executa os seus testes.
No final do arquivo, adicione a seguinte definição à fase SmokeTest:
jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ] steps:Esse código define a fase e um trabalho. Ele também cria uma variável no trabalho chamada
appServiceAppHostName. Essa variável obtém seu valor da variável de saída que você criou na seção anterior.No final do arquivo, adicione a seguinte definição de etapa à fase SmokeTest:
- 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 ` -CIEssa etapa executa um script do PowerShell para executar o script de teste que você escreveu acima usando a ferramenta de teste Pester.
No final do arquivo, adicione a seguinte definição de etapa à fase SmokeTest:
name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'Essa etapa usa o arquivo de resultados do teste que o Pester cria e publica como resultados do teste de pipeline. Você verá como os resultados são exibidos em breve.
Observe que a definição de etapa inclui
condition: always(). Essa condição indica ao Azure Pipelines que ele sempre deve publicar os resultados de teste, mesmo que a etapa anterior falhe. Essa condição é importante porque qualquer teste com falha fará com que a etapa de teste falhe e, normalmente, o pipeline para de ser executado após uma etapa com falha.Salve o arquivo.
Verificar a definição de pipeline e fazer commit dela
Verifique se o arquivo azure-pipelines.yml é semelhante ao seguinte código:
trigger: batch: true branches: include: - main pool: Dafault variables: - name: deploymentDefaultLocation value: westus3 stages: - stage: Lint jobs: - job: LintCode displayName: Lint code steps: - script: | az bicep build --file deploy/main.bicep name: LintBicepCode displayName: Run Bicep linter - stage: Validate jobs: - job: ValidateBicepCode displayName: Validate Bicep code steps: - task: AzureResourceManagerTemplateDeployment@3 name: RunPreflightValidation displayName: Run preflight validation inputs: connectedServiceName: $(ServiceConnectionName) location: $(deploymentDefaultLocation) deploymentMode: Validation resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) - stage: Preview jobs: - job: PreviewAzureChanges displayName: Preview Azure changes steps: - task: AzureCLI@2 name: RunWhatIf displayName: Run what-if inputs: azureSubscription: $(ServiceConnectionName) scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | az deployment group what-if \ --resource-group $(ResourceGroupName) \ --template-file deploy/main.bicep \ --parameters environmentType=$(EnvironmentType) - stage: Deploy jobs: - deployment: DeployWebsite displayName: Deploy website environment: Website strategy: runOnce: deploy: steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: $(ServiceConnectionName) deploymentName: $(Build.BuildNumber) location: $(deploymentDefaultLocation) resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) deploymentOutputs: deploymentOutputs - bash: | 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) - stage: SmokeTest jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.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'Se o arquivo não tiver a mesma aparência, atualize-o para corresponder a este exemplo e salve-o.
Faça commit e efetue push das alterações no repositório Git executando os seguintes comandos no terminal do Visual Studio Code:
git add . git commit -m "Add test stage" git push
Executar o pipeline e examinar o resultado do teste
No Azure DevOps, vá para o seu pipeline.
Selecione a execução mais recente do pipeline.
Aguarde até que o pipeline conclua as fases Efetuar Lint, Validar e Visualizar. Embora o Azure Pipelines atualize automaticamente a página com o status mais recente, é uma boa ideia atualizar a página ocasionalmente.
Escolha o botão Examinar e selecione Aprovar.
Aguarde a conclusão da execução de pipeline.
Observe que a fase Implantar foi concluída com êxito. A fase SmokeTest é concluída com um erro.
Selecione a guia Testes.
Observe que o resumo do teste mostra que dois testes foram executados. Um passou e um falhou. O teste que falhou está listado como Toy Website não fornece páginas via HTTP.
Este texto indica que o site não está configurado corretamente para atender aos requisitos da sua equipe de segurança.
Atualizar o arquivo Bicep
Agora que você sabe que a sua definição do Bicep não atende aos requisitos da sua equipe de segurança, você a corrigirá.
No Visual Studio Code, abra o arquivo main.bicep na pasta deploy.
Encontre a definição do aplicativo do Serviço de Aplicativo do Azure e atualize-a para incluir a propriedade
httpsOnlyem sua seçãoproperties.resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = { name: appServiceAppName location: location properties: { serverFarmId: appServicePlan.id httpsOnly: true siteConfig: { appSettings: [ { name: 'APPINSIGHTS_INSTRUMENTATIONKEY' value: applicationInsights.properties.InstrumentationKey } { name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: applicationInsights.properties.ConnectionString } ] } } }Salve o arquivo.
Faça commit e efetue push das alterações no repositório Git executando os seguintes comandos no terminal do Visual Studio Code:
git add . git commit -m "Configure HTTPS on website" git push
Executar o pipeline novamente
No navegador, acesse seu pipeline.
Selecione a execução mais recente.
Aguarde até que o pipeline conclua as fases Efetuar Lint, Validar e Visualizar. Embora o Azure Pipelines atualize automaticamente a página com o status mais recente, é uma boa ideia atualizar a página ocasionalmente.
Selecione a fase Visualizar e examine os resultados do teste de hipóteses novamente.
Observe que o comando de teste de hipóteses detectou a alteração no valor da propriedade
httpsOnly:Resource and property changes are indicated with these symbols: + Create ~ Modify = Nochange The deployment will update the following scope: Scope: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/ToyWebsiteTest ~ Microsoft.Web/sites/toy-website-nbfnedv766snk [2021-01-15] + properties.siteConfig.localMySqlEnabled: false + properties.siteConfig.netFrameworkVersion: "v4.6" ~ properties.httpsOnly: false => true = Microsoft.Insights/components/toywebsite [2020-02-02] = Microsoft.Storage/storageAccounts/mystoragenbfnedv766snk [2021-04-01] = Microsoft.Web/serverfarms/toy-website [2021-01-15] Resource changes: 1 to modify, 3 no change.Volte à execução de pipeline.
Selecione o botão Revisar e, em seguida, selecione Aprovar.
Aguarde a conclusão da execução de pipeline.
Observe que todo o pipeline é concluído com êxito, incluindo a fase SmokeTest. Esse resultado indica que ambos os testes foram aprovados.
Limpar os recursos
Agora que você concluiu o exercício, remova os recursos para não ser cobrado por eles.
No terminal do Visual Studio Code, execute o seguinte comando:
az group delete --resource-group ToyWebsiteTest --yes --no-wait
O grupo de recursos será excluído em segundo plano.
Remove-AzResourceGroup -Name ToyWebsiteTest -Force

