Lab 03: Creating a Pipeline
Start course
1h 2m

This course deals with how to implement continuous delivery with the Azure DevOps solution. In particular, we will be exploring how to design different release strategies and some factors you need to consider while setting up release pipelines. This will include looking at release triggers, release gates, and other areas associated with releasing code, including working with different environments. We will also take a look at deployment patterns and how they can be implemented in your release strategy and release pipelines. During this course, we will be using hands-on examples to help work through these concepts and configurations.

If you have any feedback for us about this course, please contact Cloud Academy at

Learning Objectives

  • Design a release strategy
  • Set up a release management workflow using Azure DevOps
  • Implement an appropriate deployment pattern

Intended Audience

  • DevOps engineers 
  • People preparing for Microsoft’s AZ-400 exam


  • General knowledge of Azure
  • Experience with Git version control, including pushing changes into repositories
  • You do not need to know any specific development language

So now that we've created our skeleton of the release pipeline, we want to populate those with tasks that will deploy the web application. The first step in this process, though, is we're gonna create some variables groups. So we go to variable group, add variable group, we're gonna call this VarDev. And we're gonna add three variables to this. We're gonna add the ResourceGroupName. We're gonna add the SlotName, and the WebAppName. Resource group, we'll call WebAppDev. The slot, we already have a production slot so we're gonna add one for development, and the web app needs to be unique within Azure itself. So I'll just use my initials, the date, mywebapp and add dev on the end and save.

To save time, we're gonna clone this variable set and we'll call it VarProd. And take the dev off here, we're gonna call this PreProduction or PreProd. And take the dev off the end, save. If we go back to the library, we can see we've created two, VarDev, VarProd, and we can now go to our release. Here's our pipeline and the releases we have so far. If we edit that release and go to variables, first thing we're gonna do is add ourself a single variable for the pipeline release called Region. So that's the Azure region we're gonna deploy to. In this case, I'm in West US and that's where we're gonna deploy it. We go to the variable group, we can link a variable group. And we're gonna link VarDev to the stages rather than the release for test and development.

So now we can return to the pipeline and add some tasks. If we click on the view stage tasks here, we'll add our first task, and we'll search for Azure resource group deployment and add. If we click the task itself we can choose the subscription which we've already set up with the service connections. The resource group, we wanna use the variables, which was the dollar ResourceGroupName. And it is case sensitive so make sure you get that right. We can have Region in here and linked artifacts. In this case, we wanna use the Azure deployment template. So if we go look just briefly at the GitHub project for the quickstart template 101-webapp-basic-windows, we can see we've got the azuredeploy.json and the parameters file.

If we look at the Azure deploy file, we can see we've got a WebAppName, so we need to be case sensitive of that. And the rest of these parameters we're gonna pick up through the default parameters. So if we use the ellipsis, we can see our two, our source artifacts, and we have the hello world from our Azure Repo and the GitHub quickstart template.

If we open this up and scroll down, 101-webapp-basic-windows, expand that and choose the azuredeploy.json file. So that's the template we wanna use. Now we wanna do the same thing and pick out the parameters file. Scroll down. Parameters. In our case, we want to give a parameterized, our parameter for the web application name to this template. But instead of creating our own parameter file, we'll just override one particular parameter. So that's the parameter we wanna override. So we're just gonna do a dash, parameter, dollar, WebAppName. And there are other deployment options there, we can choose the names and outputs and other things. We're not gonna touch any of that at the moment. We're gonna add our next job, which is an archive job.

We're looking for the HTML docs root directory. So we don't need all the Azure quickstart templates, that's really large, we just wanna zip up the docs file there. We're also gonna un-tick this prepend root. We don't want the root name on that, we just wanna deploy directly to it. If we have any trouble, we can use the verbose output, so let's tick that on. The next task we wanna add is Azure PowerShell. You have a choice here of using a file path for a script or we're gonna use some inline code. I've already typed this out to save some time, but we'll review it. Pick your service connection. So the code here is:

New-AzWebAppSlot -ResourceGroupName $(ResourceGroupName) -Name $(webAppName)-webapp -Slot $(SlotName) -AppServicePlan AppServicePlan-$(WebAppName)

which is what the template does, so it actually adds -WebApp to the name and uses the app's service name for that plan. So we'll save that there.

We just need to come down, we've still got something wrong, it wants to know what version of PowerShell. So we're just gonna use the latest version that's installed. We're gonna add another task which is the Azure app service. Deploy. Again, pick the service connection. I'm gonna copy these parameters in to save some time. So $(webAppName)-webapp. We wanna deploy to a slot, right. Paste in the ResourceGroupName here and the SlotName we want is again the parameter we've already created.

Now, in this case, we can see what's next, we're looking for the package or folder. So that's what we're creating in this archive file. So if we look at this output here, to keep things simple, we're gonna call this the WebAppName. And we're just gonna copy that parameter as it is into our app service package deployment. So in our staging directory, these are one of these predefined variables that exist within Azure DevOps. And we have one last task here, select deployment method. So it will try to auto-detect. In our case, we just wanna use the zip deploy. So we've gone and created the zip file, we've told it where to find that zip file, and we've told it how to deploy it. Fingers crossed, that should be the dev stage complete. So we'll save that.

Next, we wanna go and create the tasks for test. In the tasks for test, we're gonna do a swap application slots. So under app service manage, if we add that. We're gonna pick our Azure subscription again. We're gonna pick the app service name. So that's our $(WebAppName)-webapp, $(ResourceGroupName), SlotName, which in our case was dev and we wanna swap that with production. So for our test environment, we're moving the development stage into the test stage which is the production version of this web application. And we'll click save.

So to kick this off we can commit some code again. So we'll call this My World HTML app. My code. Save all and commit. And let's push that change.

If we go look at our releases, we now see Release-6. There's some ones I deleted in between that. And we'll watch the development. If dive into the release itself we can see that job's being initialized, artifacts being downloaded. We can also actually look at the pipeline again while we're waiting for that.

Under the test task itself, if we scroll down here, we can see artifacts to download. So for that environment, we don't actually need to download all this content, so that's a very large file. So we're just gonna un-tick these two and that should speed up our deployments. So we'll save that and just say remove artifacts. So that's not gonna happen till next release, which is fine because that will still help us through this version. So we're still deploying. Waiting for output.

If we go over to our Azure subscription. So we're in the Azure portal. Refresh that, we can see the web apps here. And then currently we have no resources inside it but we have one resource group template being deployed. And here, here's the deployment name, date, time. And we can dive in and start looking a little bit closer at all these resources. I'm going to pause the video at this point and return once this web application has deployed into this resource group.

So let's have a look at our environment. We can see the web service template finished deploying. If we go to the resource group we can see our AppServicePlan, we can see the dev slot here, we can see the application itself. So we've deployed into the dev slot. If we open up that slot there and then we do browse, we can see the static sample HTML which is the page we should be seeing.

If we return to our deployment, we can see we're not scheduled to go into the test environment yet. It's waiting. If we go back to the web app and look at our production slot and browse, we'll get the default template here. If we return to this piece and choose to deploy manually, so rather than waiting for that scheduled time, we're just gonna say manual kick off and we're gonna deploy. That job is now queued.

While we're waiting for that to complete, we'll come back and have a look at the logs for this task itself. And we can see the various initialize job, download artifacts, here we created the resource group, it gives you the times of how long everything's taken, can see the inline PowerShell script we used to create the slot and the application deployment, and the job's been finalized.

If we return to the release, we can see now this is the downloading artifacts. So because we changed that artifacts before this release, that change isn't in effect in this release v6. So we're gonna have to wait for that to download, so you see how removing those artifacts that we don't use will speed up this deployment time. Here we can see we're up to the swap slots. It's running.

So we've now got the -dev website, which is now empty because we have swapped the application into the new site. And running in our production slot for the dev environment is our sample application. So we've successfully created and executed our first pipeline task and moved a web application and deployed the infrastructure for it using parameters and a continuous deployment trigger.

As a final task, you can change the code here and make sure you change the header. I've just executed the change on the wrong title, so we'll change the header this time and we'll commit that change, so I'll save that. Welcome to DevOps. And we'll push that change there, so it's gonna initiate a new release. And what we're gonna see is into the dev slot we're gonna see the Welcome to DevOps header change and our production or test version of the application will have the old version of the website. So we'll minimize this and there's my previous release I pushed into the... Didn't make the change in the right heading. I'll pause the video and we'll just wait and see how that goes. So that release has completed. If we go refresh the main website, we can see we've still got our HTML code there. And if we refresh that site, we can see in the development slot we now have Welcome to DevOps.

About the Author

Matthew Quickenden is a motivated Infrastructure Consultant with over 20 years of industry experience supporting Microsoft systems and other Microsoft products and solutions. He works as a technical delivery lead managing resources, understanding and translating customer requirements and expectations into architecture, and building technical solutions. In recent years, Matthew has been focused on helping businesses consume and utilize cloud technologies with a focus on leveraging automation to rapidly deploy and manage cloud resources at scale.