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 humo que compruebe si se cumple el requisito 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
En primer lugar, agregará un script de prueba para comprobar que el sitio web es accesible cuando se usa HTTPS y no es accesible cuando se usa el protocolo HTTP no seguro.
En Visual Studio Code, cree un nuevo archivo en la carpeta deploy . Asigne al archivo el nombreWebsite.Tests.ps1.
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 pasa si el servidor responde con un código de estado de respuesta HTTP comprendido entre 200 y 299, 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 necesario comprender los detalles del archivo de prueba y cómo funciona. Si le interesa, puede obtener más información comprobando el recurso que aparece en el resumen del módulo.
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 Implementar , actualice el paso de implementación para publicar las salidas en una variable:
name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: $(ServiceConnectionName) deploymentName: $(Build.BuildNumber) location: $(deploymentDefaultLocation) resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) deploymentOutputs: deploymentOutputsEl proceso de implementación sigue usando la misma tarea que anteriormente, pero las salidas de las implementaciones ahora 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:
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
jqa fin de acceder a la parte pertinente de la salida JSON. Después, 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 humo que ejecute las pruebas.
En la parte inferior del archivo, agregue la siguiente definición para la fase SmokeTest :
jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ] steps:Este código define la fase y un trabajo. También crea una variable denominada
appServiceAppHostNameen 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, añada la siguiente definición de paso a la etapa 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 ` -CIEste 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, añada la siguiente definición de paso a la etapa SmokeTest:
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 pronto.
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 error hará que se produzca un error en el paso de prueba y, normalmente, la canalización deja de ejecutarse después de un paso con error.Guarde el archivo.
Comprobación y confirmación de la definición de canalización
Compruebe que el archivo azure-pipelines.yml tiene el siguiente aspecto:
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'Si el archivo no tiene el mismo aspecto, actualícelo para que coincida con este ejemplo y 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 Azure DevOps, 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 y Preview . Aunque Azure Pipelines actualiza automáticamente la página con el estado más reciente, es recomendable actualizar la página ocasionalmente.
Seleccione el botón Revisar y, a continuación, seleccione Aprobar.
Espere a que finalice la ejecución de la canalización.
Observe que la fase Implementar 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.
Este texto indica que el sitio web no está configurado correctamente para satisfacer los requisitos del equipo de seguridad.
Actualización del archivo de Bicep
Ahora que ha sabe 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 en la carpeta deploy .
Busque la definición de la aplicación de Azure App Service y actualícela para incluir la
httpsOnlypropiedad en supropertiessección: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 y Preview . Aunque Azure Pipelines actualiza automáticamente la página con el estado más reciente, es recomendable actualizar la página 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/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.Vuelva a la ejecución de canalización.
Seleccione el botón Revisar y, a continuación, seleccione 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 resultado indica que se han superado ambas pruebas.
Limpieza de 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

