README.md

Deploying your application faster and safer

Application deployment has changed drastically over the years, with tedious, manual tasks being replaced by scripted routines. It’s even easier today with cloud services to help you out.

In this talk, we’ll take a deep dive into automating and continuously deploying your application using Azure Services. We’ll start with the basics, discussing automated operations that developers control (DevOps) like A/B testing and automated approval gates. We’ll then take that entirely to the cloud using Azure’s new DevOps project, showing you how you can automate the deployment of a frontend web application, backend web service and database, and mobile application with a few clicks of a button.

Session script

Slide Deck

I am so excited to be here today to talk to you all about DevOps. Now, I know some of you are thinking, cool DevOps! And some others are probably thinking, DevOps? Who cares? That's just CI/CD Pipelines right? Why should I care about that?

I can give you all the reasons and I can pull out charts and graphs to back up my statements. But I wanted to show you a short film that really personifies the difference of before and after DevOps

And THAT is why we need to do DevOps!!! NOT the way we used to. All hitting servers with hammers tryng to get our code to deploy once a year. We need to be a well oiled machine like that pit crew! Continuously delivering value!

Now I've mentioned DevOps a lot, but what exactly is DevOps. I bet if I ask 10 people in this room what DevOps is, we will get 10 different responses. And I'm not saying anyone elses definition is wrong. But in order to frame this conversation we are having, let me give you Microsoft's Definintion of DevOps

At Microsoft, DevOps is something very specific. Devops is the union of people, process and products to enable the continous delivery of value to our end users. Now notice I said that super carefully. I didn't say continously deliver code. Because what will that give us, just piples and piles of code that's no use to our end users. And notice, I didn't even say continously deliver features. Because we could be delivering feature after feature, but if we are not delivering value, we are just wasting time!

Now why is this important? Why do should we care about DevOps. The speed of business today is SO fast, that we must adopt DevOps best practices just to keep up. If we don't, our competitors either have or they will adopt DevOps best practices. And whey they do, they WILL out innovate us and they WILL render us obsolete. And no one wants to be rendered obsolete.

This isn't just theory anymore. We now have the cold hard imperical facts that cleary demonstrate this. Adopting DevOps best practices means you are faster to market, you have lower failure rates. Much faster lead time for changes and much faster Mean time to recover. And what does all of this translate into? INCREASED REVENUE!
.

To implement DevOps successfully, you have to attack all three pillars when writing software. You must address the People, the Process and the Products

For the people portion, that's the toughest change to make. This is a cultural shift that needs to take place in the organization. Where everybody from the top down all become hyperfocused on continuously delivering value. I don't want to hear, well, that's how we always do things from anyone. Everyone needs to focus on continuously delivering vaue.

For the process, we need to have a process that will let us interate fast enough, yet still deliver code of high enough quality. So what does that mean? I need to be able to plan my sprints, and I need to be able to check my code in and out while tracking against the work I'm doing. And as I'm checking code in and out? Builds need to kick off. Automated Tests need to be run. Security scans need to happen. And if the build are good, an automated system needs to pick up my bits and deploy them into my Dev, QA, UAT all the way out in to production. And why does this need to be automated? Potentially, this can happen many times a day! So we need to make sure the process is consistent and repeatable. Every single time like clock work. And once the code reaches production, it doesn't end there. We still need to be able to monitor our code in production. We need to know things like, is my app up or down, is my app performing well, and what are users really doing in my app? Because answers to those questions let me know if I'm delivering vaue to my end users. And if I am, we can double down on those types of activities in the next sprint. And if we aren't, then we can quickly reprioritize our backlog and course correct.

Now all of this requires the right products and tools to help enable all of this. So we need tools that will let us track our work throughout our sprint. We need source control systems that can corrolate our work to our checkins. We need automated build and release systems that can build on everycheckin, run all of our unit tests and automate deployment all the way to production. And we need systems in place to monitor our app in production.

Out there in the world, there are all sorts of tools that do these things. And Azure is an open system, which means you can keep using all of the DevOps tools you are most familiar with.

However, you can replace ALL of them with just one product. Azure DevOps

Azure DevOps is literally everything you need to take an idea and turn that idea into a working piece of software in the hands of your end users, for ANY language targeting ANY platform. Azure DevOps is a suite of 5 sepparate products that work SEAMLESSLY together. There's a work item tracking product called Azure Boards, where you can track any unit of work in your software project with visual tools to help you manage all of your work. There is Azure Pipelines, where you can build yout your CI/CD pipelines for any language targeting any platform. There is Azure Repos where you can host your own Git repo or a centralized version control system. There is Azure Test Plans for you to create, plan and run all of your manual tests. And finally there is Azure Artifacts, where you can host your package management systems, whethere they be nuget, maven or even generic packages.

In today's session, we will be concentrating on Azure Pipelines, where we will deploy our code faster yet safer!

Demo

[Bring up main browser with all the tabs and bring up tab 1]

So the code for TailWind is all in github, and we need to build a CI/CD pipeline from github to Azure Pipelines. That's super easy to do with the Azure Pipelines market place extension. Lets go into the marketplace and search for the Azure Pipeline Extension

I've already installed the extension so let's just go in and configure this

And we will configure it to create a CI pipeline for our Tailwind Front End repo

This takes us to the login screen of Azure DevOps

Where it will take you through a wizard to help you set up a CI pipeline quickly

Notice Azure Pipelines analyzes the repo and offers you templates that make sense for the technolgogies and languages in your repo. This repo is a node.js app so let's chose the Node.js template

This creates for us an azure-pipelines.yml file. So it creates for you a yaml build pipeline. The build engine in Azure pipelines is basically a task runner. It does one task after another after another. And you can describe the tasks either with a visual editor or with a yaml file. There are many benefits to using yaml builds or Pipeline as Code. Primarily, now your build pipeline is checked right into source control so your build pipeline is versioned right alongside your source code. If you need more info on yaml builds, just follow the docs link which will take you to our docs page which descrive everything you will need to know.

Let's go ahead and save and run this build

This saves the azure-pipeines.yml file into our git repo which in turn fires off our build. And what happens in the build? First it downloads all the source code from git hub, then it executes the build steps described in the yml file. So in our case it does

Downloads the source code

Installs Node.js

Does an npm install and build

Now this is fine but I want to customize the build a little, and I want to show you all what the visual editor looks like. So let's hope into the visual editor

So here, you can see each individual step and now, i'm configuring my build to

Install npm

Setup the DB connection strings

Build the app because we are creating a staic web app out of the node.js app

Zip everything up so it's ready to be deployed

publish the zip of the website as our build artifact back to Azure Pipelines

The build system in Azure Pipelines is 100% configurable to do ANYTHING. Any language targeting any platform! And the way you customize this build is by adding and removing tasks.

Where out of the box, there are a little over a hunred tasks that you can drag over to the left and just start using.

And what if hyou want to do something that's not out of the box?

Not a big deal, just go to our marketplace where our partners have created over 500 build and release tasks that you can just download and start using.

And if you want to do something that's not out of the box and not in the marketplace? It's still not a problem because you can write your own custom tasks. Custom tasks are nothing more than powershell or node.js. So what that means is that anything you can do from the command line, you can easily get this build and release system to do as well. Which translates into you can make this build and release system do ANYTHING! Any language targeting any platform!

Ok, so we have a visual build that describe the customized build that I want to happen, so the easiest way to add this to our YAML build is to

view the yaml that gets generated by this visual build

Let's go ahead and copy it, and then we'll just paste this into our azure-pipelines.yml file

Let's go back into VSCode and we'll pull down the latest changes with a git pull

and now let's paste the yaml and replace everything in azure-pipelines.yml

And now lets push that yaml file back into GitHub. And once the code hits github, it will kick off a new build

And what's this build doing? It's downloading the latest source from github, including the azure-pipelines.yml file. It then kicks off a build and executes the build steps described in the yml file! Pipeline as code!!!. And then it will

Do an npm install

Setup my db connections

Build app

zip up the website so it's ready to be deployed

publish the zip file as the build artifact for this build back to Azure Pipelines

Oh and if you notice, right now, I'm just hardcoding my database end points. If we want to become more secure, we can even store secrets in the pipeline and then use the secrets in the yaml file.

To set up secrets let's edit our build

Where we can now add variables, lock them to encrypt it and now, if we go back to our azure-pipelines.yml file, we can reference the secret build variables by adding line 32 and 33

Ok, looks like our build has completed

And we get a nice build report that shows everything that happened during the build includeing tests.

We can even examine the build artifact by clicking on the drop

Where you can see we created a zip file of the website

So just like that, we can create a build pipeline. But we still need to create a release pipeline to release this app. To do that, we'll just click on the Release button

Which brings up the visual editor for the release pipeline. Tailwind Traders website will be hosted in Azure App Service, so we can just select the Azure App Service Deployment Template

And now we just need to finish configuring the release. To configure a release, first we create the stage or environment. The first environment I want to deploy to is my staging environment so I'll replace the name with Staging

After defining your stage, next, you get to define the steps that will happen to deploy your app to that stage. So clicking on the steps link will take us to the task runner for this stage.

And since we've already selected the App Service Deployment template, there's not a whole lot of configuring left to do. We just need to chose our azure subscription and chose the app service we want to deploy to. In this case, I want to deploy to the Tailwind Front End staging app service.

Now that we have defined a stage, and defined the steps needed to deploy my app, we can choose manual approvers before and after each stage. For the Staging environment, let's just create a post depoyment approver. That way, if a new build kicks off, it will automatically deploy into my staging environment with no manual intervention

I'll just add myself as a manual approver for this demo. You can add a list of people where everyone on the list has to approve before it will pass through the manual gate. or you can create a group of people and if one person in the group approves, it will pass through the gate. Or you can use a combintion of lists and groups. So you can tighten down security as much as you need to.

Now, let's add another stage to deploy to our production environment. Hover over the environment and select clone to clone the environment.

And we will name the new stage Prod

And now we need to tweak the release steps a little bit so it deploys to the production environment.

Click on the steps in the prod environment

And change the app service to the production app service.

Click save and voila! We just created a release pipeline that releases Tailwind Traders front end into the staging environment, and then after approvers into the production environment.

Let's see the release in action so we'll click release and click Create Release

And then we'll creat a release using the latest build by clicking Create

Where we can now watch the release happen live.

And what is happening? The release is going to the build's drop location. It's going to pick up the deployment bits from the drop location and it will deploy those bits into the staging environment based off of the steps that we configured for the staging stage.

Just like with the build the release is fully customizable where you can make it do anything. It's just a task runner, so like the build pipeline, you customize the release steps by adding and removing task runner. Out of the box, you get hundreds of tasks with many hundreds more coming from the marketplace. And you can write your own custom tasks that can make this release system do anything.

Ok, looks like the release finished release in the staging environment and it is now waiting for a post deployment approval

Before we approve it, let's check out our staging environment to see if the new code actually go deployed.

Bring up browser with the front end in the two tabs, bring up tab 1

Click refresh

And Voila! Code deployed into the staging environment!

We can now go back to Azure Pipelines, and click the post deployment approval

And now the code flows into the Prod environent

And what is it doing? Release management is going to the drop location for this specific build. The very same drop location where it picked up the bits for staging. And it will deploy the EXACT same bits it deployed into staging will now be deployed into production. There is no new build that's kicked off. There's no way stray code can slip in. Its the exact same bits.

Ok, looks like the bits have been deployed and we are now waiting for a post deployment approval.

Let's check out production

And refresh

And Bam! New code deployed all the way to prod. So now I'll approve the post deployment approval

And now, we have built our first build and release pipeline where any checkin from github will kick off our build and release through staging all the way into production.

Cool huh?

But you know what? we can do even better. Remember Azure Pipelines is fully customizable where we can make the release system do anything. Including Advanced DevOps best practices. Things like Blue Green deployments, where we first deploy into an environment that's an exact replica of what's in production. Do our testing in it, and when we r ready, we swap production with the BlueGreen environment. So now, what was in production is in my BlueGreen spot and what was in my Blue Green spot is now in production. Something like that is easily doable using Azure Pipelines. Even something like AB Testing, where we deploy new code and route just some of the traffic, like 10% to the new code and route the rest of the traffic to the old code. This way, we can slowly and carefully gather telemetry, make sure we are delivering value. And if things look good, we can slowly bump up the traffic to 20, 30 eventually 100 percent.

In fact, using the power of Azure Pipelines and Azure App service, this is really pretty trivial to do. Check this out.

[Go back to main browser, Tab 2 - Tailwind Front End App Service in Portal]

Here is the azure portal page for my app service which is hosting the Tailwind Traders front end.

To implement AB testing, scroll down to Development Tools and select Testing In Production

Here we get to add a deployment slot. Deployment slots are... think of them like a virtual directory for your web app.

We'll create a slot and then we can direct what percentage of the traffic we want routed to what slot.

I'll name this new slot ABTesting

And this creates me my slot. Now, I just need to add in the percentage of traffic that I want to route to the slot. For this demo, I'll pick 50%.

And that's all I need to do on the infrastructure side. To implement AB testing in my pipeline, all I'll need to do is make some simple changes.

And we do need to tweak the deployment step, because instead of deploying the new code to the production slot, we will deploy the new code to the ABTesting slot we just created

And save and Bam. That's all we have to do. Now, to see this in action let's go make some code changes.

Let's turn the background of our app purple

Save it, and commit back to github

This kicks off our our build

And what is happening in this build?

The build engine is downloading the latest changes from github including the azure-piplines.yml file. Then the build engine starts executing all the steps defined in the yaml file.

NPM Install

Setup DB Connection strings and endpoints

Build App into static files

Zip everything up so the build artificat is the zip file of the web app all ready to be deployed

published build artifact back to Azure Pipelines.

And while this is running, I wanted to show you one more thing. Because right now, our database user and password is just stored as plain text in my yml file

We can easily store and use secrets in Azure Pipleines by editing the build

Where we can store secrets for our pipelines which are encrypted so no one can see them. And to use them, in your yml file, we would just reference them like this

Ok, looks like the build has finished and now it's kicked off the release pipeline

So what is it doing? Release Management is downloading the build artificat from the build. In this case, it's the zip file of the compiled application and now it is deploying this new code. The one with the purple background into the staging environment. And here it is, deployed in staging.

Approving this

And now, the bits start flowing into the Prod A slot

So what is really happeing? Release management is going to the drop location, the very same drop location for this specific build and download the build artifacts. The VERY same build artifcats as what we just deployed into staging? It will now deploy those exact same bits into the ABTesting slot. There was no extra build, no extra compile, no extra bundling. These will guarentee be the exact same bits.

Ok, now that we've deployed into the TestAB slot

Let's refresh our production environment and we see...

Why isn't the background purple? Remember, we are now routing 50% of the traffic to the old code and 50% of the traffic to the new code. So let's open up another browser

[Go back to the main browser, open new tab, copy and paste front end prod url]

And...

Voila! 50% of our traffic routed through the old code, 50% of the traffic routed through the new code. Now, we can collect telemetry to help us determine if we are delivering value. And if they are, we can approve this and the code

Will flow 100% to the new code.

As you can see, we can easily set up our pipeline so we can increment the flow from 10% to 20% and slowly all the way up to 100%. And if we are not giving value, we can also set up the pipeline to stop the deployment and roll back.

Pretty cool huh. I have just shown you

Creating a CI/CD Pipeline

Implementing advanced DevOps best practices like AB Testing using Azure Pipelines and Azure App Service

But we can do even better! Using Azure Pipelines, we have the ability to create automated approval gates based off of continuous monitoring. So now, we can automate the approval process from one stage to the next using AI!!!

For instance, right I've set up my staging environment to be monitored using Application Insight.

Looking for uncaught browser based javascript alert. And if there are too many of these, this will create an alert in Application Insight.

So the idea now is for me to deploy into the staging environment. I can then run my tests, users can start testing in the staging environment. And if Application insight finds too many alerts or browser based errors, it will automatically stop my deployment so I don't deploy into production. And if everything looks good, it will automatically with no user approvals, flow into the production environment.

To set this up, we set up alerting in application insight for the staging environment, and then we need to tweak the release pipeline to use automated gates.

First, I'm going to remove the manual approver from the post deployment step

And here, you can see application Insight has caught a bunch of browser errors

Which means now, when my gate hits, it detects the alerts from App Insight, fails the gate so now the broken code automatically does not get pushed to the prod environments!!!

And BAM! Gate detected Application Insight alerts. Failed and release died in staging.

SUPER COOL Stuff!!!

So what have I shown you so far?

We can easily create CI/CD Pipelines for any language targeting any platform

We can easily implement pretty much anything in our pipelines, including advanced DevOps best practices like AB Testing.

We can even enable automated approval gates using Continuous monitoring so now we can deploy faster yet even safer!!!

And all of this can be done easily. But let me tell you a confession. I may be a DevOps practitioner, but I'm not a huge fan of building out CI/CD Pipelines by hand. I mean, I recognize the importance of good pipelines, but I love to write code! That's what makes me happy. And with the power of Azure, i can get started super easily with just a couple of clicks. And what do I mean by "getting started?"

Using the power of Azure DevOps Projects, with just a few clicks, I can create everything I need to get started. A Team Project in Azure Pipelines. Sample code in the language that you pick in my repo. A CI/CD pipeline that makes sense for the technolgoies picked, and infrastructure provisioned for you in Azure. And I get ALL of this with just a couple of clicks. Let me show you what I mean.

[Tab 4 - Azure Portal ]

From the azure portal, let's go and create an Azure DevOps project.

Now the very first thing it's going to ask you is what language do you want to use. You can pick .NET of course, node, php, java, python, ruby go with more languages to come!

For this demo, let's pick node and click next

Now it's asking what framework do you want to use. For this demo, let's just build a simple Node.js app.

And now, it's asking what infrastructure do you want to host your app? For this demo, let's host our node.js app in a kubernetes cluster.

And now, it's asking what instance of Azure DevOps do you want to use to orchestrate everything. You can create a brand new one from here, or use one that already exists. For this demo, I'll pick my demo account, I'll name the project IgniteTour, name my Kubernetes Cluster IgniteTourCluster, click done and....

Bam, that is LITERALLY all you need to do. Now, just kick back and let Azure build everything out for you. A team project in Azure Pipelines. Sample code in the langauge that you picked, In our case, a node js sample app, sitting in a git repo. A CI/CD Pipeline that makes sense for the technologies picked, so a node js app running in a docker container, hosted in a kubernetes cluster. And infrastructure provisioned for you in Azure. So a kubernetes cluster deployed for us in Azure. And when it's all done doing this, you get a portal blade that looks like this

[Tab 5 - Ignite 1 DevOps Project Dashboard ]

Where on the left hand side you see the CI/CD Pipeline. And on the right hand side, you see all the infrastructure that got provisioned for you in Azure uncluding our kubernetes cluster, instance of application isight and our web app running in our Kubernetes cluster.

And all of these links are deep links into the resource itself. For instance

Clicking on the link to the code will take us to the git repo holding our node js app.

Notice, this is just a node js app using DevOps best practices so we are using Arm templates for Infrastructure as Code and also using Helm charts to package up our kubernetes app.

For the build pipeline

We create for you a build pipeline that makes sense for the technologies picked. So in this case you get a build pipeline that creates a docker image for the node.js sample app, pushes the image into an instance of Azure Container Registry and then packages the app up as a helm package.

Next, for the release pipeline

We create for you a release pipeline that makes sense for the technologies picked.

We create a pipeline that creates your azure infrastructure using the ARM templates, which includes the kubernetes cluster in Azure Kubernetes Service. And then we deploy our app using Helm.

And after deploying the app, the app is no available by clicking on the app endpoint from the portal blade

Which launches our sample app deployed in Azure Kubernetes Service

And once again. You get all of this with just a couple of clicks!!

So million dollar question. How do you get your real code into this pipeline instead of the sampel app?

Simple enough

Going to the git repo

This is just a plain old git repo. So simple enough to clone this onto our hard drive, remove the application folder, copy our application into the local repo. Commit and push those changes back up to Azure Repos which will kick off the CI/CD pipeline with our real code which then get's pushed all the way into production!

There's another way we can do this too by editing the build pipeline.

And now, when we get source, instead of getting the source from Azure Repos, we'll switch that over to my github repo holding my real code, click Save and Queue

And this should start building my real code from github and sending it through the release pipeline all the way to my kubernetes cluster.

And going back into the portal

[Tab 6 - Ignite 2 DevOps Project Dashboard ]

You can see that the code is being pulled from github, it's been built and deployed and here is my real app, deployed into my kubernetes cluster

BAM!!!! And ALL Of this, with just a couple of clicks.

So what have we've shown you all?

We can easily build out CI/CD pipelines for any language targeting any platform

We can easily impliment advanced DevOps techniques using Azure Pipelines and Azure

We can even include automated deployment gates that utilize continuous monitoring to help us determine if a gate should pass or not

And we can quickly scaffold out our CI/CD pipelines into Azure with just a couple of clicks using Azure DevOps Projects!

Now all of these demos that I have shown are still relatively simple. How would all of this work with a real world application? Like with Tailwind Traders?

The Tailwind Traders application consists of a node.js web front end with two microservices. The inventory service is a .net core micro service running in a docker container hosted in Azure App Service. The product service is a node js micro service running in a docker container hosted in a kubernetes cluster. The web front end is a Node.js app hosted in Azure App Service. And finally, there is also an iOS mobile app front end as well. Can we use Azure Pipelines to build and release this real world scenario?

Here is one build that builds ALL 4 parts of our application in parallel. We use a
hosted windows agent to build our .net core inventory service and we create a docker image out of it.

Next we use an ubuntu agent to build our node js product service container and then we create a helm package out of it

Next we use another ubuntu agent to build our node js Tailwind front end web application

And finally, we use one of our hosted mac agents to create our iOS application.

1 build, 4 parallel agents building our app all at once. We are the ONLY cloud vender that will give you agents for all 3 platforms. Windows, Linux and Macs!!!!

We can do the same thing with our release pipelines too.

[Tab 8 - Tailwind Release All Up ]

Where we have one release with 4 parallel tracks. One track to deploy the inventory service as a container into App Service

One track taking the Product Service and deploying that as a helm app in a Kubernetes Cluster

One track that deploys the web front end as a static site sitting in App service and finally, one track that takes the ios app and deploys it all the way out into the App Store.

So real world? You bet. Using azure pipelines, you can deploy any app targeting any platform no matter how complex your app. And as for release gates, here are some real world cases of using release gates.

[Tab 9 - Release Gate Docusign Example]

I was recently at a hospital where they literally had a rule in place where they could not deploy into production without a physical document signed and uploaded to their docusign server. This was turning into a bottleneck as now, a physical person had to verify the document was signed before deployments into production could happen. However, I also knew that Docusign had a rest api, so it was super simple to create a custom gate that checked to see if the document was signed.

So now, after the code is deployed into QA, tests were done, a human ok'd it, and now, the gate kicked in. When you set up a gate, you get to set up the polling frequency as well as the time out. So in this case, I pulled every 5 minutes checking to see if the document was signed. First time, wasn't signed. Second time, still wasn't signed. 15 minuytes later? Docuemnt was signed and the new deployment automatically deployed into the production environment.

Another example of using these release gates is here, where I used Dynatrace monitoring to see if a release is good or not.

[Tab 10 - Release Gate Dynatrace Unbreakable Pipeline Pass]

In this example, code was deployed to staging, load test were run, and then the gate kicked in, where we use dynatrace to help us determine if the deployment was good or bad. In this case, all response times looked good, the gate passed and the code flowed into production.

[Tab 11 - Release Gate Dynatrace Unbreakable Pipeline Fail]

And here, after the code was deployed in staging and load tests were run, dynatrace detected enough annomolies that it said the release was bad, failing the gate, and the bad code never made it into production.

So here you can see how using automated approval gates, you can use AI to help with your deployments. So all you devs out there, let's do this!!! Go to dev.azure.com and let's start building our CI/CD pipelines so we can all deploy faster yet safer