AZ-400: Designing and Implementing Microsoft DevOps Solutions

Design and Implement Pipelines

Demo Azure Pipelines

In this guide, we explore how to create and manage an end-to-end Azure Pipeline for automating code integration, building, and deployment using Azure DevOps. Follow along as we demonstrate setting up a new project, integrating your code repository, configuring a CI/CD pipeline, and deploying your application as an Azure Static Web App.


Creating an Azure DevOps Project

Begin by logging into Azure DevOps and creating a new project. In our example, we name the project KodeKloud Blog. This project will serve as the host for our Blazor WebAssembly website, which we plan to deploy as a static application on Azure.

The image shows an Azure DevOps interface with a project creation window open, where a new project named "KodeKloudBlog" is being set up with private visibility.


Setting Up Azure Repos

Once your project is created, the next step is to add your website code to Azure Repos for version control and team collaboration. Open a terminal and add your Azure Repos as a remote repository to your local git repository with the following command:

git remote add origin https://[email protected]/jeremymorgankodekloud/KodeKloudBlog

Clone the repository to your local machine:

C:\Users\jeremy\repos>git clone https://[email protected]/jeremymorgankodekloud/KodeKloudBlog
Cloning into 'KodeKloudBlog'...
warning: You appear to have cloned an empty repository.
C:\Users\jeremy\repos>cd KodeKloudBlog
C:\Users\jeremy\repos\KodeKloudBlog>

After copying your project files into the local folder, stage and commit your changes:

C:\Users\jeremy\repos\KodeKloudBlog>git add .

Then commit your changes:

git commit -m "initial commit"

Finally, push the changes to Azure Repos:

git push

This process uploads your files into the Azure Repos repository, making them available for development and integration.

The image shows a project overview page from Azure DevOps, featuring a welcome message and options for various services like Boards, Repos, and Pipelines. The sidebar includes navigation links, and there are sections for project stats and members.


Creating Your First Pipeline

With your code safely in Azure Repos, it's time to build an automated pipeline. Azure Pipelines connects your source code to build and deployment processes.

  1. Navigate to the Pipelines section and click New Pipeline.
  2. When prompted for the code source, choose Azure Repos Git. While Azure DevOps supports other options such as Bitbucket Cloud or GitHub, our example focuses on Azure DevOps.

The image shows an Azure DevOps interface prompting the user to create their first pipeline, with navigation options on the left sidebar.

Next, select your project repository and choose the ASP.NET Core template. Out-of-the-box, the template might work well, but you may need to perform slight modifications such as specifying the agent pool. Below is an example pipeline configuration:

trigger:
- master

pool:
  vmImage: 'windows-latest'
  name: Default

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)WebApp.zip"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'

If you prefer building the pipeline from scratch, you can start with only the necessary tasks:

trigger:
- master

pool:
  vmImage: 'windows-latest'
  name: 'Default'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\\WebApp.zip"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'

Review this YAML file and then click Save and Run. This action creates a new commit which triggers the build process.

The image shows an Azure DevOps interface for creating a new pipeline, asking "Where is your code?" with options for Azure Repos, Bitbucket Cloud, GitHub, and GitHub Enterprise Server.

Azure DevOps provides a variety of pre-made templates for different project types, such as Java, .NET Core, C#, C++, and Docker. These templates serve as excellent starting points for your CI/CD pipeline configurations.

The image shows the Azure DevOps interface for creating a new pipeline, with various project templates listed, such as Xamarin.Android, .NET Core, and Docker. The left sidebar includes options like Overview, Boards, Repos, and Pipelines.


Managing Build Agents and Permissions

When running the pipeline for the first time, you might receive a message stating that the pipeline requires permission to access a specific resource. Click View, then Permit to authorize the pipeline for continuous use of the designated agent pool (named "Default").

Pipeline Permission Notice

Remember to permit resource access so that your pipeline can consistently use the designated agent pool for all runs.

The image shows an Azure DevOps pipeline interface where a permission is needed to access a resource, with a pop-up asking to permit access for the agent pool "Default."

After permitting, the pipeline will commence running. You can monitor each step—installing NuGet, building with Visual Studio Build, running tests via VSTest, and completing the process—by viewing the job details.

The image shows an Azure DevOps pipeline run for "KodeKloudBlog" with various completed job steps, including initialization, checkout, and build processes. Each step is marked with a green check, indicating successful completion.


Deploying to Azure Static Web Apps

After your code successfully builds, the next step is to deploy your Blazor web application as an Azure Static Web App. Static web apps are ideal for hosting HTML, JavaScript, and CSS files—and you can extend them with serverless functions if needed.

To deploy:

  1. In the Azure portal, create a new Static Web App.
  2. Choose your subscription, resource group, and assign a name (for example, KodeKloud blog). Select the Free plan if you do not require advanced features.
  3. Under deployment details, select Azure DevOps as your source. Then, choose the appropriate organization, project, repository, and branch.

The image shows the "Create Static Web App" page on the Microsoft Azure portal, where users can configure settings such as subscription, resource group, app name, hosting plan, and deployment details.

Configure the build presets with these settings:

  • App location: / (root)
  • API location: API (if applicable)
  • Output location: wwwroot

The image shows the "Create Static Web App" page on Microsoft Azure, where deployment details and build configurations are being set up using Azure DevOps.

After reviewing your selections, click Review and create. When deployment completes, you can access your static website via the resources section.

The image shows the "Create Static Web App" page on the Microsoft Azure portal, displaying a summary of details for a static web app setup, including subscription, resource group, and repository information.


Linking Pipelines with Static Web Apps

Once the static web app is linked to your Azure DevOps project, every successful build can automatically trigger a deployment. The pipeline logs will show the detailed progress of the deployment:

Creating "C:\Users\Jeremy\Downloads\agent_work\1\a\KodeKloudBlog.parameters.xml" because "AlwaysCreate" was specified.
Touching "C:\Users\Jeremy\Downloads\agent_work\1\a\KodeKloudBlog.BuildParameters.xml" because "AlwaysCreate" was specified.
...
Adding file (C:\Users\Jeremy\Downloads\agent_work\1\a\Release\net8.0\Browser-wasm\PubTmpOut\wwwroot\css\app.css).
...

This log illustrates how the deployment package is built and pushed to the static web app. During development, you can monitor the pipeline console to track details about job steps, agent usage, and the overall execution time.

The image shows an Azure DevOps Pipelines dashboard with a list of recently run pipelines, including "KodeKloudBlog" and "azure-static-web-apps-purple-island," both manually triggered for the master branch.


Adjusting Build Agent Settings for Linux

In certain scenarios, you may need to change your build agent from Windows to Linux. For example, if your YAML configuration specifies vmImage: ubuntu-latest but your default pool contains only Windows agents, update the configuration to use a Linux agent. The following example shows a pipeline setup for Azure Static Web Apps using an Ubuntu agent:

name: Azure Static Web Apps CI/CD
pr:
  branches:
    include:
      - master
trigger:
  branches:
    include:
      - master
jobs:
  - job: build_and_deploy_job
    displayName: Build and Deploy Job
    condition: or(eq(variables['Build.Reason'], 'Manual'), or(eq(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.Reason'], 'IndividualCI')))
    pool:
      vmImage: ubuntu-latest
    variables:
      - group: Azure-Static-Web-Apps-purple-island-038b9b710-variable-group
    steps:
      - checkout: self
        submodules: true
      - task: AzureStaticWebApp@0
        inputs:
          azure_static_web_apps_api_token: $(AZURE_STATIC_WEB_APPS_API_TOKEN_PURPLE_ISLAND_038B9B710)
          app_location: '/' # App source code path
          output_location: 'wwwroot' # Built app content directory -- optional

After updating and committing the changes, run the pipeline to verify that it now leverages the Linux agent. Once both pipelines run successfully, your website will be deployed.

Visit your website afterward to see the published homepage:

The image shows a weather data table from a website, displaying dates, temperatures in Celsius and Fahrenheit, and a summary of the weather conditions. The sidebar includes navigation options for "Home," "Counter," and "Weather."


Continuous Integration and Updating Your Site

With your CI/CD pipeline in place, any changes pushed to the repository will automatically trigger a new build and deployment cycle. For example, consider this C# snippet from the main file of your Blazor application:

using KodeKloudBlog;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.RootComponents.AddHeadElement("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();

If you update your Razor pages—say, by modifying the home page—you might add content like this:

@page "/"
<PageTitle>Home</PageTitle>
<h1>Welcome to the KodeKloud Blog</h1>
<p>This is a change that was automatically pushed!</p>
Welcome to your new app.

After saving your changes, check the git status:

C:\Users\jeremy\repos\KodeKloudBlog>git status
On branch master
Your branch is up to date with 'origin/master'.
...

Then stage, commit, and push your changes:

git add .
git commit -m "new blog update"
git push

If you encounter an error similar to:

! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://dev.azure.com/jeremymorgankodekloud/KodeKloudBlog/_git/KodeKloudBlog'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. Use "git pull" before pushing again.

Simply run a git pull to merge the remote changes, and then push your updated code.

Once the changes are pushed, the pipeline will automatically rebuild and redeploy your application. Refresh your website to witness the updates in action.


Recap

StepDescription
Azure DevOps Project CreationSet up a new project named "KodeKloud Blog" to host your application.
Azure Repos IntegrationImport your Blazor application code into Azure Repos for version control.
Pipeline ConfigurationConfigure CI/CD pipelines to build, test, and deploy your application.
Deployment SetupDeploy the built application to Azure Static Web Apps.
Continuous IntegrationEnable automated deployments on code changes to maintain an up-to-date website.

Azure Pipelines streamline the process from code commits to production deployments, making them essential to a modern DevOps strategy. For more detailed documentation, visit Azure DevOps Documentation and Azure Static Web Apps.

Enjoy automating your builds and deployments, and keep your site updated effortlessly!

Thank you for reading.

Watch Video

Watch video content

Previous
Getting Started with Azure Pipelines