Ejercicio: Adición de una fase de prueba a la canalización
El equipo de seguridad de la empresa de juguetes le ha pedido que compruebe que el sitio web solo es accesible mediante HTTPS. En este ejercicio, configurará la canalización para ejecutar una prueba de comprobación de la compilación que compruebe los requisitos del equipo de seguridad.
Durante el proceso, hará lo siguiente:
- Agregar un script de prueba al repositorio.
- Actualizar la definición de canalización para agregar una fase de prueba.
- Ejecutar la canalización y observar el error de prueba.
- Corregir el archivo de Bicep y observar que la canalización se ejecuta correctamente.
Adición de un script de prueba
Aquí, agregará un script de prueba para comprobar que el sitio web es accesible cuando se usa HTTPS y no lo es cuando se usa el protocolo HTTP no seguro.
En Visual Studio Code, cree un archivo denominado Website.Tests.ps1 en la carpeta deploy.
Pegue el código de prueba siguiente en el archivo:
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" } }
Es código es un archivo de prueba de Pester. Requiere un parámetro denominado
$HostName
. Ejecuta dos pruebas en el nombre de host:- Intente conectarse al sitio web mediante HTTPS. La prueba se supera si el servidor responde con un código de estado de respuesta HTTP entre 200 y 299, lo que indica una conexión correcta.
- Intente conectarse al sitio web mediante HTTP. La prueba se supera si el servidor responde con un código de estado de respuesta HTTP de 300 o superior.
Para los fines de este ejercicio, no es importante que comprenda los detalles del archivo de prueba y cómo funciona. En el resumen se proporcionarán vínculos para que pueda obtener más información si está interesado.
Publicación de la salida del archivo de Bicep como una variable de salida de fase
En el script de prueba que ha creado en los pasos anteriores es necesario probar un nombre de host. El archivo de Bicep ya incluye una salida, pero, antes de poder usarla en las pruebas de comprobación de la compilación, debe publicarla como una variable de salida de fase.
En Visual Studio Code, abra el archivo azure-pipelines.yml en la carpeta deploy.
En la fase Implementación, actualice el paso de implementación para publicar las salidas en una variable:
- 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
Ahora el proceso de implementación sigue usando la misma tarea que antes, pero las salidas de las implementaciones se almacenan en una variable de canalización denominada
deploymentOutputs
. La variable de salida tiene el formato JSON.Para convertir las salidas con formato JSON en variables de canalización, agregue el siguiente paso de script debajo del paso de implementación:
- 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)
Si la implementación se completa correctamente, el script accede al valor de cada salida de la implementación de Bicep. El script usa la herramienta
jq
a fin de acceder a la parte pertinente de la salida JSON. A continuación, el valor se publica en una variable de salida de la fase con el mismo nombre que la salida de implementación de Bicep.Nota:
Pester y jq están preinstalados en agentes hospedados por Microsoft para Azure Pipelines. No es necesario hacer nada especial para usarlos en un paso de script.
Guarde el archivo.
Adición de una fase de prueba de comprobación de la compilación a la canalización
Ahora, puede agregar una fase de prueba de comprobación de la compilación que ejecute las pruebas.
En la parte inferior del archivo, agregue la definición siguiente para la fase SmokeTest:
- stage: SmokeTest jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
Este código define la fase y un trabajo. También crea una variable denominada
appServiceAppHostName
en el trabajo. Esta variable toma su valor de la variable de salida que ha creado en la sección anterior.En la parte inferior del archivo, agregue la definición de paso siguiente a la fase SmokeTest:
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
Este paso ejecuta un script de PowerShell para ejecutar el script de prueba que ha escrito antes mediante la herramienta de pruebas Pester.
En la parte inferior del archivo, agregue la definición de paso siguiente a la fase SmokeTest:
- task: PublishTestResults@2 name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'
Este paso toma el archivo de resultados de la prueba que crea Pester y lo publica como los resultados de la prueba de canalización. Verá cómo se muestran los resultados en breve.
Observe que la definición del paso incluye
condition: always()
. Esta condición indica a Azure Pipelines que siempre debe publicar los resultados de la prueba, incluso si se produce un error en el paso anterior. Esta condición es importante porque cualquier prueba con errores provocará un error en el paso de prueba y normalmente la canalización deja de ejecutarse después de un paso con errores.Guarde el archivo.
Comprobación y confirmación de la definición de canalización
Compruebe que el archivo azure-pipelines.yml es similar al código siguiente:
trigger: batch: true branches: include: - main pool: vmImage: ubuntu-latest 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'
Si no es así, actualícelo para que coincida con este ejemplo y después guárdelo.
Confirme e inserte los cambios en el repositorio de Git mediante la ejecución de los comandos siguientes en el terminal de Visual Studio Code:
git add . git commit -m "Add test stage" git push
Ejecución de la canalización y revisión del resultado de la prueba
En el explorador, vaya a la canalización.
Seleccione la ejecución más reciente de la canalización.
Espere hasta que la canalización complete las fases Lint, Validate (Validación) y Preview (Vista previa). Aunque Azure Pipelines actualiza de forma automática la página con el estado más reciente, es recomendable actualizarla ocasionalmente.
Seleccione el botón Review (Revisar) y después Approve (Aprobar).
Espere a que finalice la ejecución de la canalización.
Observe que la fase Deploy (Implementación) finaliza correctamente. La fase SmokeTest finaliza con un error.
Seleccione la pestaña Pruebas.
Observe que en el resumen de la prueba se muestra que se han ejecutado dos pruebas. La primera se realizó correctamente y la otra produjo un error. La prueba con error aparece como Toy Website.Does not serve pages over HTTP (Toy Website. No proporciona páginas sobre HTTP).
Este texto indica que el sitio web no se ha configurado correctamente para satisfacer los requisitos del equipo de seguridad.
Actualización del archivo de Bicep
Ahora que ha identificado que la definición de Bicep no cumple los requisitos del equipo de seguridad, lo corregirá.
En Visual Studio Code, abra el archivo main.bicep de la carpeta deploy.
Busque la definición de la aplicación de Azure App Service y actualícela para incluir la propiedad
httpsOnly
en su áreaproperties
: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 } ] } } }
Guarde el archivo.
Confirme e inserte los cambios en el repositorio de Git mediante la ejecución de los comandos siguientes en el terminal de Visual Studio Code:
git add . git commit -m "Configure HTTPS on website" git push
Repetición de la ejecución de la canalización
En el explorador, vaya a la canalización.
Seleccione la ejecución más reciente.
Espere hasta que la canalización complete las fases Lint, Validate (Validación) y Preview (Vista previa). Aunque Azure Pipelines actualiza de forma automática la página con el estado más reciente, es recomendable actualizarla ocasionalmente.
Seleccione la fase Vista previa y vuelva a revisar los resultados hipotéticos.
Observe que el comando hipotético ha detectado el cambio en el valor de la propiedad
httpsOnly
:Resource and property changes are indicated with these symbols: + Create ~ Modify = Nochange The deployment will update the following scope: Scope: /subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/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.
Vuelva a la ejecución de canalización.
Seleccione el botón Revisar y después Aprobar.
Espere a que finalice la ejecución de la canalización.
Observe que toda la canalización finaliza correctamente, incluida la fase SmokeTest. Este éxito indica que ambas pruebas se han superado.
Limpiar los recursos
Ahora que ha completado el ejercicio, puede quitar los recursos para que no se le facturen.
En el terminal de Visual Studio Code, ejecute el comando siguiente:
az group delete --resource-group ToyWebsiteTest --yes --no-wait
El grupo de recursos se elimina en segundo plano.
Remove-AzResourceGroup -Name ToyWebsiteTest -Force