Cvičení – přidání testovací fáze do kanálu
Bezpečnostní tým vaší společnosti toy vás požádal, abyste ověřili, že váš web je přístupný jenom přes HTTPS. V tomto cvičení nakonfigurujete kanál tak, aby spustil orientační test, který kontroluje požadavek bezpečnostního týmu.
Během tohoto procesu:
- Přidejte do úložiště testovací skript.
- Aktualizujte definici kanálu a přidejte testovací fázi.
- Spusťte kanál a sledujte selhání testu.
- Opravte soubor Bicep a sledujte úspěšné spuštění kanálu.
Přidání testovacího skriptu
V této části přidáte testovací skript, který ověří, jestli je web přístupný, když se použije protokol HTTPS a není přístupný při použití nezabezpečeného protokolu HTTP.
V editoru Visual Studio Code vytvořte nový soubor ve složce deploy s názvem Website.Tests.ps1.
Do souboru vložte následující testovací kód:
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" } }
Tento kód je testovací soubor Pester. Vyžaduje parametr s názvem
$HostName
. Spustí dva testy s názvem hostitele:- Zkuste se připojit k webu přes HTTPS. Test projde, pokud server odpoví stavovým kódem odpovědi HTTP mezi 200 a 299, což označuje úspěšné připojení.
- Zkuste se připojit k webu přes HTTP. Test projde, pokud server odpoví stavovým kódem odpovědi HTTP 300 nebo vyšší.
Pro účely tohoto cvičení není důležité pochopit podrobnosti testovacího souboru a jeho fungování. V souhrnu vám poskytneme odkazy, abyste se mohli dozvědět víc, pokud vás zajímají.
Publikování výstupu souboru Bicep jako výstupní proměnné fáze
Testovací skript, který jste vytvořili v předchozích krocích, vyžaduje k otestování název hostitele. Soubor Bicep už obsahuje výstup, ale než ho budete moct použít v orientačních testech, musíte ho publikovat jako výstupní proměnnou fáze.
V editoru Visual Studio Code otevřete soubor azure-pipelines.yml ve složce deploy .
Ve fázi Nasazení aktualizujte krok nasazení, aby se výstupy publikovaly do proměnné:
- 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
Teď váš proces nasazení stále používá stejnou úlohu jako předtím, ale výstupy z nasazení jsou uloženy v proměnné kanálu s názvem
deploymentOutputs
. Výstupní proměnná je formátovaná jako JSON.Pokud chcete převést výstupy ve formátu JSON na proměnné kanálu, přidejte následující krok skriptu pod krok nasazení:
- 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)
Pokud se nasazení úspěšně dokončí, skript přistupuje k hodnotě každého výstupu z nasazení Bicep. Skript používá
jq
nástroj pro přístup k příslušné části výstupu JSON. Pak se hodnota publikuje do výstupní proměnné fáze se stejným názvem jako výstup nasazení Bicep.Poznámka:
Pester i jq jsou předinstalované na agentech hostovaných Microsoftem pro Azure Pipelines. Nemusíte dělat nic zvláštního, abyste je mohli použít v kroku skriptu.
Uložte soubor.
Přidání fáze orientačního testu do kanálu
Teď můžete přidat fázi orientačního testu, která spouští testy.
V dolní části souboru přidejte následující definici pro fázi SmokeTest :
- stage: SmokeTest jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
Tento kód definuje fázi a úlohu. Vytvoří také proměnnou v úloze s názvem
appServiceAppHostName
. Tato proměnná přebírá hodnotu z výstupní proměnné, kterou jste vytvořili v předchozí části.V dolní části souboru přidejte následující definici kroku do fáze 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
Tento krok spustí skript PowerShellu pro spuštění testovacího skriptu, který jste napsali dříve pomocí testovacího nástroje Pester.
V dolní části souboru přidejte následující definici kroku do fáze SmokeTest :
- task: PublishTestResults@2 name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'
Tento krok provede soubor výsledků testů, který Nástroj Pester vytvoří a publikuje jako výsledky testu kanálu. Brzy uvidíte, jak se výsledky zobrazí.
Všimněte si, že definice kroku zahrnuje
condition: always()
. Tato podmínka značí službě Azure Pipelines, že by měla vždy publikovat výsledky testu, i když předchozí krok selže. Tato podmínka je důležitá, protože jakýkoli neúspěšný test způsobí selhání testovacího kroku a kanál se po neúspěšném kroku normálně zastaví.Uložte soubor.
Ověření a potvrzení definice kanálu
Ověřte, že váš soubor azure-pipelines.yml vypadá jako následující kód:
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'
Pokud tomu tak není, aktualizujte ho tak, aby odpovídal tomuto příkladu, a pak ho uložte.
Potvrďte a nasdílejte změny do úložiště Git spuštěním následujících příkazů v terminálu editoru Visual Studio Code:
git add . git commit -m "Add test stage" git push
Spusťte kanál a zkontrolujte výsledek testu.
V prohlížeči přejděte do kanálu.
Vyberte poslední spuštění kanálu.
Počkejte, až kanál dokončí fáze Lint, Validate a Preview . I když Azure Pipelines stránku automaticky aktualizuje nejnovějším stavem, je vhodné stránku občas aktualizovat.
Vyberte tlačítko Revize a pak vyberte Schválit.
Počkejte na dokončení spuštění kanálu.
Všimněte si, že fáze nasazení se úspěšně dokončí. Fáze SmokeTest se dokončí chybou.
Vyberte kartu Testy.
Všimněte si, že souhrn testu ukazuje, že se spustily dva testy. Jedna byla úspěšná a jedna selhala. Test, který selhal, je uvedený jako Web Toy.Neslouží stránky přes protokol HTTP.
Tento text označuje, že web nebyl správně nakonfigurovaný tak, aby splňoval požadavek vašeho bezpečnostního týmu.
Aktualizace souboru Bicep
Teď, když jste zjistili, že vaše definice Bicep nesplňuje požadavek vašeho bezpečnostního týmu, opravíte ji.
V editoru Visual Studio Code otevřete soubor main.bicep ve složce deploy .
Vyhledejte definici aplikace Aplikace Azure Service a aktualizujte ji tak, aby zahrnovala
httpsOnly
vlastnost v jejíproperties
oblasti: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 } ] } } }
Uložte soubor.
Potvrďte a nasdílejte změny do úložiště Git spuštěním následujících příkazů v terminálu editoru Visual Studio Code:
git add . git commit -m "Configure HTTPS on website" git push
Znovu spusťte kanál.
V prohlížeči přejděte do kanálu.
Vyberte poslední spuštění.
Počkejte, až kanál dokončí fáze Lint, Validate a Preview . I když Azure Pipelines stránku automaticky aktualizuje nejnovějším stavem, je vhodné stránku občas aktualizovat.
Vyberte fázi náhledu a znovu zkontrolujte výsledky citlivostní kontroly.
Všimněte si, že příkaz what-if zjistil změnu v
httpsOnly
hodnotě vlastnosti: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.
Vraťte se ke spuštění kanálu.
Vyberte tlačítko Revize a pak vyberte Schválit.
Počkejte na dokončení spuštění kanálu.
Všimněte si, že celý kanál se úspěšně dokončí, včetně fáze SmokeTest . Tento úspěch značí, že oba testy prošly.
Vyčištění prostředků
Teď, když jste cvičení dokončili, můžete odebrat prostředky, abyste za ně neúčtoli.
V terminálu editoru Visual Studio Code spusťte následující příkaz:
az group delete --resource-group ToyWebsiteTest --yes --no-wait
Skupina prostředků se odstraní na pozadí.
Remove-AzResourceGroup -Name ToyWebsiteTest -Force