Oefening: een webtoepassing implementeren
Bij uw speelgoedbedrijf heeft uw team voor websiteontwikkeling de nieuwste versie van de website doorgevoerd in uw Git-opslagplaats. U bent nu klaar om uw pijplijn bij te werken om de website te bouwen en deze te implementeren in Azure-app Service.
In dit proces voert u de volgende taken uit:
- Voeg een nieuwe pijplijnsjabloon toe voor de buildtaak.
- Werk de pijplijn bij om de buildtaak op te nemen.
- Voeg een nieuwe betrouwbaarheidstest toe.
- Werk de implementatiefase bij om de toepassing te implementeren.
- Voer de pijplijn uit.
Een pijplijnsjabloon voor de buildtaak toevoegen
Voeg een nieuwe taakdefinitie toe die de stappen bevat die nodig zijn om de websitetoepassing te bouwen.
Open Visual Studio Code.
Maak in de map deploy/pipeline-templates een nieuw bestand met de naam build.yml.
Voeg de volgende inhoud toe aan het build.yml pijplijnsjabloonbestand:
jobs: - job: Build displayName: Build application and database pool: vmImage: windows-latest steps: # Build, copy, and publish the website. - task: DotNetCoreCLI@2 displayName: Build publishable website inputs: command: 'publish' publishWebProjects: true - task: CopyFiles@2 displayName: Copy publishable website inputs: sourceFolder: '$(Build.SourcesDirectory)/src/ToyCompany/ToyCompany.Website/bin' contents: '**/publish.zip' targetFolder: '$(Build.ArtifactStagingDirectory)/website' flattenFolders: true - task: PublishBuildArtifacts@1 displayName: Publish website as pipeline artifact inputs: pathToPublish: '$(Build.ArtifactStagingDirectory)/website' artifactName: 'website'
De taak voert een buildstap uit om de broncode van de websitetoepassing om te zetten in een gecompileerd bestand dat klaar is om te worden uitgevoerd in Azure. De taak kopieert vervolgens het gecompileerde artefact naar een tijdelijke faseringsmap en publiceert het als een pijplijnartefact.
Sla de wijzigingen in het bestand op.
Wijzig de naam van de eerste pijplijnfase en voeg een buildtaak toe
Open het azure-pipelines.yml bestand in de map Deploy .
Wijzig de lintfase . Wijzig de naam in Build en voeg een buildtaak toe die gebruikmaakt van de build.yml pijplijnsjabloon die u hebt gemaakt.
trigger: batch: true branches: include: - main pool: vmImage: ubuntu-latest stages: - stage: Build jobs: # Build the Visual Studio solution. - template: pipeline-templates/build.yml # Lint the Bicep file. - template: pipeline-templates/lint.yml # Deploy to the test environment. - template: pipeline-templates/deploy.yml parameters: environmentType: Test # Deploy to the production environment. - template: pipeline-templates/deploy.yml parameters: environmentType: Production
Sla de wijzigingen in het bestand op.
Het betrouwbaarheidstestbestand bijwerken
De websiteontwikkelaars hebben een statuseindpunt toegevoegd aan de website. Dit eindpunt controleert of de website online is en of deze de database kan bereiken. Hier voegt u een nieuwe betrouwbaarheidstest toe om de statuscontrole aan te roepen vanuit uw implementatiepijplijn.
Open het bestand Website.Tests.ps1 in de map Deploy .
Voeg een nieuwe testcase toe waarmee de statuscontrole wordt aangeroepen. De testcase mislukt als de antwoordcode niet 200 is, wat aangeeft dat de test is geslaagd.
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" } It 'Returns a success code from the health check endpoint' { $response = Invoke-WebRequest -Uri "https://$HostName/health" -SkipHttpErrorCheck Write-Host $response.Content $response.StatusCode | Should -Be 200 -Because "the website and configuration should be healthy" } }
Sla de wijzigingen in het bestand op.
Uitvoer toevoegen aan Bicep-bestand
U wilt een implementatiestap toevoegen waarmee uw website naar Azure-app Service wordt gepubliceerd, maar voor de publicatiestap is de naam van de App Service-app vereist. Hier maakt u de naam van de app beschikbaar als uitvoer van uw Bicep-bestand.
Open het bestand main.bicep in de implementatiemap .
Voeg aan het einde van de bestandsinhoud de naam van de App Service-app toe als uitvoer.
output appServiceAppName string = appServiceApp.name output appServiceAppHostName string = appServiceApp.properties.defaultHostName
Sla de wijzigingen in het bestand op.
Implementatiefase bijwerken
Open het bestand deploy.yml in de map deploy/pipeline-templates .
Configureer in de definitie van de implementatietaak van de implementatiefase (in de buurt van regel 59) de taak voor het gebruik van de door Windows gehoste agentgroep:
- stage: Deploy_${{parameters.environmentType}} displayName: Deploy (${{parameters.environmentType}} Environment) jobs: - deployment: DeployWebsite displayName: Deploy website pool: vmImage: windows-latest variables: - group: ToyWebsite${{parameters.environmentType}} environment: ${{parameters.environmentType}} strategy:
Voor sommige van de pijplijnstappen die u later toevoegt om met uw database te kunnen werken, moet het Windows-besturingssysteem worden uitgevoerd. U kunt verschillende agentpools gebruiken voor verschillende taken in uw pijplijn, zodat de andere taken de Ubuntu Linux-pijplijnagentgroep blijven gebruiken.
Voeg in de stap SaveDeploymentOutputs van de deploy-taakeen nieuwe pijplijnvariabele toe met de waarde van de app-naam uit de uitvoer van de Bicep-implementatie:
- bash: | echo "##vso[task.setvariable variable=appServiceAppName]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppName.value')" 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)
U ziet dat de
appServiceAppHostName
variabele deisOutput=true
eigenschap erop heeft toegepast, omdat die variabele wordt gebruikt in de betrouwbaarheidstestfase. DeappServiceAppName
variabele wordt ingesteld en gebruikt in dezelfde pijplijnfase en -taak. De instelling is dus niet nodigisOutput=true
.Voeg aan het einde van de inhoud van de taak Implementeren een nieuwe stap toe om de app te implementeren in Azure-app Service:
steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: ToyWebsite${{parameters.environmentType}} deploymentName: $(Build.BuildNumber) location: ${{parameters.deploymentDefaultLocation}} resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) -reviewApiUrl $(ReviewApiUrl) -reviewApiKey $(ReviewApiKey) deploymentOutputs: deploymentOutputs - bash: | echo "##vso[task.setvariable variable=appServiceAppName]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppName.value')" 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) - task: AzureRmWebAppDeployment@4 name: DeployWebsiteApp displayName: Deploy website inputs: appType: webApp ConnectionType: AzureRM azureSubscription: ToyWebsite${{parameters.environmentType}} ResourceGroupName: $(ResourceGroupName) WebAppName: $(appServiceAppName) Package: '$(Pipeline.Workspace)/website/publish.zip'
Notitie
Wees voorzichtig met de inspringing van het YAML-bestand, zodat de nieuwe implementatiestap op hetzelfde niveau als de
DeployBicepFile
stap wordt ingesprongen. Als u het niet zeker weet, kopieert u de hele deploy.yml bestandsinhoud uit het voorbeeld in de volgende stap.U ziet dat u het artefact niet expliciet hebt gedownload in de pijplijndefinitie. Omdat u een implementatietaak gebruikt, downloadt Azure Pipelines het artefact automatisch voor u.
Controleer de inhoud van het deploy.yml bestand en voer uw wijzigingen door
Controleer of uw deploy.yml bestand eruitziet als in het volgende voorbeeld:
parameters: - name: environmentType type: string - name: deploymentDefaultLocation type: string default: westus3 stages: - ${{ if ne(parameters.environmentType, 'Production') }}: - stage: Validate_${{parameters.environmentType}} displayName: Validate (${{parameters.environmentType}} Environment) jobs: - job: ValidateBicepCode displayName: Validate Bicep code variables: - group: ToyWebsite${{parameters.environmentType}} steps: - task: AzureResourceManagerTemplateDeployment@3 name: RunPreflightValidation displayName: Run preflight validation inputs: connectedServiceName: ToyWebsite${{parameters.environmentType}} location: ${{parameters.deploymentDefaultLocation}} deploymentMode: Validation resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) -reviewApiUrl $(ReviewApiUrl) -reviewApiKey $(ReviewApiKey) - ${{ if eq(parameters.environmentType, 'Production') }}: - stage: Preview_${{parameters.environmentType}} displayName: Preview (${{parameters.environmentType}} Environment) jobs: - job: PreviewAzureChanges displayName: Preview Azure changes variables: - group: ToyWebsite${{parameters.environmentType}} steps: - task: AzureCLI@2 name: RunWhatIf displayName: Run what-if inputs: azureSubscription: ToyWebsite${{parameters.environmentType}} scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | az deployment group what-if \ --resource-group $(ResourceGroupName) \ --template-file deploy/main.bicep \ --parameters environmentType=$(EnvironmentType) \ reviewApiUrl=$(ReviewApiUrl) \ reviewApiKey=$(ReviewApiKey) - stage: Deploy_${{parameters.environmentType}} displayName: Deploy (${{parameters.environmentType}} Environment) jobs: - deployment: DeployWebsite displayName: Deploy website pool: vmImage: windows-latest variables: - group: ToyWebsite${{parameters.environmentType}} environment: ${{parameters.environmentType}} strategy: runOnce: deploy: steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: ToyWebsite${{parameters.environmentType}} deploymentName: $(Build.BuildNumber) location: ${{parameters.deploymentDefaultLocation}} resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) -reviewApiUrl $(ReviewApiUrl) -reviewApiKey $(ReviewApiKey) deploymentOutputs: deploymentOutputs - bash: | echo "##vso[task.setvariable variable=appServiceAppName]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppName.value')" 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) - task: AzureRmWebAppDeployment@4 name: DeployWebsiteApp displayName: Deploy website inputs: appType: webApp ConnectionType: AzureRM azureSubscription: ToyWebsite${{parameters.environmentType}} ResourceGroupName: $(ResourceGroupName) WebAppName: $(appServiceAppName) Package: '$(Pipeline.Workspace)/website/publish.zip' - stage: SmokeTest_${{parameters.environmentType}} displayName: Smoke Test (${{parameters.environmentType}} Environment) jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy_${{parameters.environmentType}}.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'
Sla de wijzigingen in het bestand op.
Voer in de Visual Studio Code-terminal uw wijzigingen door en push deze naar uw Git-opslagplaats door de volgende opdrachten uit te voeren:
git add . git commit -m "Build and deploy website application" git push
De pijplijn uitvoeren
Ga in uw browser naar Pijplijnen.
Selecteer de meest recente uitvoering van uw pijplijn.
Wacht totdat de buildfase is voltooid.
De pijplijn wordt onderbroken voordat de fase Validate (Test Environment) wordt uitgevoerd, omdat de pijplijn toestemming nodig heeft om de variabelegroep te gebruiken waarnaar de fase verwijst. U moet de toegang van de pijplijn tot de variabelegroep goedkeuren, omdat u de pijplijn voor het eerst in dit project uitvoert. Wanneer u de pijplijn opnieuw uitvoert, hoeft u de toegang tot dezelfde variabelegroep niet goed te keuren.
Selecteer Weergeven.
Selecteer Toestaan.
Selecteer Toestaan.
De fase Valideren (testomgeving) is voltooid.
De pijplijn wordt voortgezet en de fase Deploy (Test Environment) is voltooid. De pijplijn voert vervolgens de fase Betrouwbaarheidstest (Testomgeving) uit, maar de betrouwbaarheidstestfase mislukt.
Selecteer de fase Betrouwbaarheidstest (testomgeving) om het pijplijnlogboek te openen.
Selecteer de stap Betrouwbaarheidstests uitvoeren om de bijbehorende sectie van het pijplijnlogboek weer te geven.
U ziet dat het pijplijnlogboek het antwoord van de statuscontrole bevat. Het antwoord geeft aan dat er een probleem is met de communicatie van de toepassing met Azure SQL Database. De database is nog niet geïmplementeerd of geconfigureerd. Daarom heeft de website er geen toegang toe. In de volgende oefening lost u dit configuratieprobleem op.