Azure Web Apps are really handy hosting environments and support CI/CD pipelines.
This is a walkthrough of some work I did to highlight:
Configuring a project in Visual Studio Team Services (VSTS) using C# on .NET Core with ASP.NET Core
Preparing a CI/CD pipeline in VSTS for deployment into an Azure App Service environment
The code itself is minimal - just a random quote generator with a very limited set of quotes. I often use this type of codebase to demonstrate a variety of CI/CD principles - I call it my fortune cookie app (based on the old Unix fortune program). It’s a very useful platform for demonstrators as it can be stand-alone, use databases (relational or other), be a web api etc and I’ve prepared it in a range of languages and systems.
Unfortunately, VSTS does not support public repositories but the code is pretty much secondary to the process I’ll describe. The code is a pretty basic NET Core project that comes to life with the following:
dotnet restore dotnet build dotnet watch run
VSTS and App Services
For this demo I wanted to have a basic CI/CD pipeline running that:
Built new commits
Deploys automatically to an Azure App Service instance used for testing
Provide a manual approval gate for the production deployment
Defining a CI/CD pipeline can be approached in a few ways:
In VSTS as a build and release process
In the Azure Web App itself - this is the easiest for getting started. You can then go into VSTS and expand and configure as needed.
The Web Apps
I created two Web App instancess - one for Test and one for Production.
I used the free App Service Plan tier as it’s enough for the demo and you can get the whole thing running for $0.
|You can use slots in Web Apps to provide blue/green deployment but I’m going real simple in this demo.|
If you’re going to setup CD via the Azure web app console, configure your Test web app instance first and use it for your Continuous Delivery configuration. That sets up an automatic CI/CD pipeline for you and your commits cause a release into the Test instance. You can then re-engineer the pipeline to include a Production environment (the second web app instance).
To start off, I created a VSTS project and committed some basic "hello, world" code using
dotnet new mvc scaffold. Over in the Azure portal I went to
and linked to the VSTS team that contains the project.
I then setup a web app - just a very basic config using the free tier. After creating a Web App in the Azure portal, I went into the App’s blade and selected the "Continuous Delivery" menu option. It’s pretty straight-forward to point the Web App to the VSTS project and Azure sets up the initial CI/CD pipeline.
The screenshot below demonstrates what gets created in the VSTS project’s
I disabled the
Test stage as I won’t create tests for this demonstration.
You can see that the CI side is just doing the basic Build, Test, Publish routine.
The publish step is useful to display as it shows how the
parameters are set:
I made a minor change to the Publish Artifact step as I wanted the build artifact name to include the Git check-in version:
Only the 1 CI workflow is required for this demonstration. I want to build the code and package it for deployment over the various environments.
Over in the VSTS project’s
Releases section you’ll find that the CD pipeline has also been configured.
I expanded on what Azure configured for me by creating an additional environment (
Each of the Environments (
Production) point to their own Web App instance:
The screenshot above indicates a few things:
Each Environment has a single task (to deploy to the Web App instance)
Testenvironment doesn’t need manual approval but
Productiondoes - check the person icon
VSTS Releases are broken up by environment, phase and task:
An environment is essentially a release endpoint, such as a web app instance (or slot)
Each environment has one or more phases that provide runtime environments for carrying out tasks.
Each phase has one or more tasks that define a work item to be completed
I admit it’s a little confusing but, for this demo, we keep it simple and have a single phase with a single task for each environment.
Triggers configuration for the release gives us the bridge between the CI and CD worlds.
You can see in the screenshot below that the release will run each time CI produces a new artifact:
Checking out the configuration for the Test environment, you can see that there’s no approval required to deploy to
Test - we just let it happen once CI has done its thing.
Test environment also has some configuration to handle queues -
this is handy as I’m only using a single test endpoint and want to roll-up multiple changes
if they start backing up:
Test environment has one task,
Deploy Azure Service.
This is configured to deploy the new artifact to the relevant App Service.
One important item to note is that I’ve selected "Take App Offline" -
this is important as it avoids problems wrt replacing the running codebase with the new one:
Production environment isn’t hugely different to
Essentially, we want an automatic deploy into
Test but only deploy to
following a manual approval gate (maybe there’s a QA person):
Production deployment is set to go ahead as long as
Test was successfully deployed
(and pending approval):
Just a quick note about approvals. When
Test has deployed successfully,
the approver for
Production receives an email similar to the one below:
Clicking on the approval link will take them to the VSTS site and ask them to either Approve or Reject (and provide comments):
Whilst this is a very simple application and CI/CD pipeline, it should serve as a basis for more advanced iterations. There are a number of items not covered that you should consider:
Automated testing: unit, UI, integration, load, security tests can all run from the CI/CD pipeline
Operational concerns: how are system/application logs managed and alerts configured?
Related services: this demo is self-contained but how would we manage resources such as databases and changes to their schemas (for example)?