Övning – Lägga till ett teststeg i pipelinen
Leksaksföretagets säkerhetsteam har bett dig att kontrollera att din webbplats endast är tillgänglig via HTTPS. I den här övningen konfigurerar du pipelinen så att den kör ett röktest som kontrollerar säkerhetsteamets krav.
Under processen gör du följande:
- Lägg till ett testskript på lagringsplatsen.
- Uppdatera pipelinedefinitionen för att lägga till ett teststeg.
- Kör pipelinen och observera att testet misslyckas.
- Åtgärda Bicep-filen och observera att pipelinekörningen har körts.
Lägga till ett testskript
Här ska du lägga till ett testskript för att kontrollera att webbplatsen är tillgänglig när HTTPS används och inte är tillgänglig när http-protokollet som inte är säkert används.
I Visual Studio Code skapar du en ny fil i distributionsmappen med namnet Website.Tests.ps1.
Klistra in följande testkod i filen:
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" } }
Den här koden är en Pester-testfil. Den kräver en parameter med namnet
$HostName
. Den kör två tester mot värdnamnet:- Försök att ansluta till webbplatsen via HTTPS. Testet godkänns om servern svarar med en HTTP-svarsstatuskod mellan 200 och 299, vilket indikerar en lyckad anslutning.
- Försök att ansluta till webbplatsen via HTTP. Testet godkänns om servern svarar med en HTTP-svarsstatuskod på 300 eller högre.
I den här övningen är det inte viktigt att du förstår informationen i testfilen och hur den fungerar. Vi tillhandahåller länkar i sammanfattningen så att du kan lära dig mer om du är intresserad.
Publicera Bicep-filens utdata som en fasutdatavariabel
Testskriptet som du skapade i föregående steg kräver ett värdnamn för att testa. Din Bicep-fil innehåller redan utdata, men innan du kan använda den i dina röktester måste du publicera den som en stegutdatavariabel.
I Visual Studio Code öppnar du filen azure-pipelines.yml i distributionsmappen.
I distributionssteget uppdaterar du distributionssteget för att publicera utdata till en variabel:
- 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
Nu använder distributionsprocessen fortfarande samma uppgift som tidigare, men utdata från distributionerna lagras i en pipelinevariabel med namnet
deploymentOutputs
. Utdatavariabeln formateras som JSON.Om du vill konvertera JSON-formaterade utdata till pipelinevariabler lägger du till följande skriptsteg under distributionssteget:
- 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)
Om distributionen har slutförts kommer skriptet åt värdet för varje utdata från Bicep-distributionen. Skriptet
jq
använder verktyget för att komma åt den relevanta delen av JSON-utdata. Sedan publiceras värdet till en fasutdatavariabel med samma namn som Bicep-distributionsutdata.Kommentar
Pester och jq är båda förinstallerade på Microsoft-värdbaserade agenter för Azure Pipelines. Du behöver inte göra något speciellt för att använda dem i ett skriptsteg.
Spara filen.
Lägga till ett rökteststeg i pipelinen
Nu kan du lägga till ett rökteststeg som kör dina tester.
Lägg till följande definition för SmokeTest-fasen längst ned i filen:
- stage: SmokeTest jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
Den här koden definierar fasen och ett jobb. Den skapar också en variabel i jobbet med namnet
appServiceAppHostName
. Den här variabeln tar värdet från utdatavariabeln som du skapade i föregående avsnitt.Lägg till följande stegdefinition i SmokeTest-fasen längst ned i filen:
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
Det här steget kör ett PowerShell-skript för att köra testskriptet som du skrev tidigare med hjälp av Pester-testverktyget.
Lägg till följande stegdefinition i SmokeTest-fasen längst ned i filen:
- task: PublishTestResults@2 name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'
Det här steget tar testresultatfilen som Pester skapar och publicerar den som pipelinetestresultat. Du ser hur resultatet visas inom kort.
Observera att stegdefinitionen innehåller
condition: always()
. Det här villkoret anger för Azure Pipelines att det alltid ska publicera testresultaten, även om föregående steg misslyckas. Det här villkoret är viktigt eftersom ett misslyckat test gör att teststeget misslyckas och normalt slutar pipelinen att köras efter ett misslyckat steg.Spara filen.
Verifiera och checka in din pipelinedefinition
Kontrollera att filen azure-pipelines.yml ser ut som följande kod:
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'
Om den inte gör det uppdaterar du den så att den matchar det här exemplet och sparar det sedan.
Checka in och skicka ändringarna till Git-lagringsplatsen genom att köra följande kommandon i Visual Studio Code-terminalen:
git add . git commit -m "Add test stage" git push
Kör pipelinen och granska testresultatet
Gå till din pipeline i webbläsaren.
Välj den senaste körningen av din pipeline.
Vänta tills pipelinen har slutfört faserna Lint, Validate och Preview . Även om Azure Pipelines automatiskt uppdaterar sidan med den senaste statusen är det en bra idé att uppdatera sidan ibland.
Välj knappen Granska och välj sedan Godkänn.
Vänta tills pipelinekörningen har slutförts.
Observera att distributionssteget har slutförts. SmokeTest-fasen avslutas med ett fel.
Välj fliken Tester .
Observera att testsammanfattningen visar att två tester har körts. En passerade och en misslyckades. Testet som misslyckades visas som Leksakswebbplats.Hanterar inte sidor via HTTP.
Den här texten anger att webbplatsen inte har konfigurerats korrekt för att uppfylla säkerhetsteamets krav.
Uppdatera Bicep-filen
Nu när du har upptäckt att din Bicep-definition inte uppfyller säkerhetsteamets krav ska du åtgärda det.
Öppna filen main.bicep i mappen deploy i Visual Studio Code.
Hitta definitionen för Azure App Service-appen och uppdatera den så att den
httpsOnly
innehåller egenskapen i dessproperties
område: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 } ] } } }
Spara filen.
Checka in och skicka ändringarna till Git-lagringsplatsen genom att köra följande kommandon i Visual Studio Code-terminalen:
git add . git commit -m "Configure HTTPS on website" git push
Kör pipelinen igen
Gå till din pipeline i webbläsaren.
Välj den senaste körningen.
Vänta tills pipelinen har slutfört faserna Lint, Validate och Preview . Även om Azure Pipelines automatiskt uppdaterar sidan med den senaste statusen är det en bra idé att uppdatera sidan ibland.
Välj förhandsgranskningssteget och granska konsekvensanalysresultatet igen.
Observera att kommandot what-if har identifierat ändringen i
httpsOnly
egenskapens värde: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.
Gå tillbaka till pipelinekörningen.
Välj knappen Granska och välj sedan Godkänn.
Vänta tills pipelinekörningen har slutförts.
Observera att hela pipelinen har slutförts, inklusive SmokeTest-fasen . Den här framgången indikerar att båda testerna har godkänts.
Rensa resurserna
Nu när du har slutfört övningen kan du ta bort resurserna så att du inte debiteras för dem.
Kör följande kommando i Visual Studio Code-terminalen:
az group delete --resource-group ToyWebsiteTest --yes --no-wait
Resursgruppen tas bort i bakgrunden.
Remove-AzResourceGroup -Name ToyWebsiteTest -Force