Tuesday, April 3, 2018

Working with the Azure DevOps project

Download PDF version of this walk-through.

Microsoft has added a new project type in Azure that facilitates DevOps. This is the "DevOps Project" and it is currently in preview. In this post I shall show you how it works in its present state. You can expect it to look different when it reaches final release.

Some of the benefits of the DevOps project are:
  • you can be up and running with a new DevOps pipeline very quickly
  • a wide range of languages and frameworks are supported like .NET, Java, PPH, Node and Python
  • you can start fresh or bring in your application from GitHub on external Git
  • it has built-in Application Insights integration for instant analytics and actionable insights
  • CI/CD using Visual Studio Team Services (VSTS)
In this tutorial, we will use a very simple ASP.NET Core 2.0 web application that you can clone from GitHub. 

I assume you already have the following:
  • You have an Azure account at https://portal.azure.com
  • You have a VSTS account at https://www.visualstudio.com/team-services/
  • You have Docker installed on your computer
  • You have Git installed on your computer
  • You have a GitHub account at http://github.com
  • You have some basic knowledge about Docker
The plan is to deploy a sample ASP.NET Core 2.0 application into a Docker container on Azure using the new DevOps project in Azure.

Forking the sample ASP.NET Core 2.0 application

Login into your GitHub account in your favorite browser.

In a different browser tab, go to https://github.com/medhatelmasry/CompoundInterestCalculator.

Fork this repository into your GitHub account by clicking on the Fork button in the top-right corner.




The Sample Web Application

In the CompoundInterestCalculator directory, there are two other folders: Calculator & UnitTests. Go into the Calculator folder with the following terminal command:

cd CompoundInterestCalculator\Calculator

The Dockerfile in the current folder looks like this:

FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish --framework netcoreapp2.0 --configuration Release --output dist

# Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/dist .

# run the application
ENTRYPOINT ["dotnet", "Calculator.dll"]

The Dockerfile contain instructions for creating a Docker image.



OPTIONAL - do this only if you have Docker installed on your computer

Let's create the Docker image and run the application in a Docker container by executing the following terminal window commands while in the Calculator folder:

docker build -t calculator .
docker run -d -p 8080:80 calculator 

View the web application by going to http://localhost:8080. It will look like this:


The DevOps project in Azure

Let us deploy this application using the DevOps project in Azure. Point your browser to https://portal.azure.com and login into your Azure subscription. Click on "All services" on the left-side navigation:


In the blade that appears, enter "devops" in the filter field then choose "Dev Ops Projects PREVIEW".


Click on the blue "Create DevOps Projects" button in the "DevOps Projects" blade.


The next dialog shows us the types of pipelines that can be generated for us, namely: .NET, Java, Static Websites, Node.js, PHP, Python and your own code. This list is sure to change as time goes by.

Click on the bottom square titled "Bring your own coded", then click Next.


You are asked to choose your code repository. You choices are either GitHub or External Git. Choose GitHub. You will next be asked to choose the the repository and branch.

Enter values as shown above then click on Next. Select "ASP.NET Core" from the drop-down list then click Next.

You are next asked to choose an Azure service to deploy the application. At the time of writing there are only three choices. Select "Web App for Containers" then click on Next.

As soon as you click on "Web App for Containers" a dialog slides from the right-side that looks like this:


Simply click on OK in the above dialog without changing anything, then click on Next.

The next blade is so that Azure can create for you an end-to-end pipeline in VSTS.

Below is a table that describes the values that you should choose:

Account Choose "Use existing" radio button if you already have a VSTS account that uses the same credentials as Azure. If you do not already have a VSTS account, then go ahead and choose "Create New".
Project name You can name the VSTS project: "CompoundInterestCalculator".
Subscription Choose a valid Azure subscription
App name Choose an app name that comprises a unique host name when combined with .azurewebsites.net
App Service location Choose a data center that is closest to where you are

After you are satisfied with the values that you have entered, click on Done.

Deployment of the DevOps project gets underway and it could take about 4 minutes. There is much that is happening behind the scenes:

  • A project is being created in VSTS that points to a GitHub repository.
  • Build and Release definitions are created in VSTS
  • The release version of the application is deployed to Azure
  • A number of other resources are automatically created in both Azure and VSTS

When deployment is completed you can view the website by going to https://.[your app name].azurewebsites.net or simply click on the Browse button on the blade that appears.


It takes a few minutes before the web application appears in your browser. If you see a message "Service Unavailable", it may be that you need to be patient and wait a while longer. When it eventually does appear, it should look just like this:


Azure Artifacts

Let us see what artifacts were created in Azure. Click on "Resource groups" in the left-side navigation.


You will find two resource groups that were created for you, one for Azure artifacts and the other for VSTS.


In my case, clicking on the top Resource Group revealed the following four items:


You can see that four resources belong to the resource group: Application Insights, App Service, Container Registry, and an App Service Plan.

The second resource group contained the following items:

 

There are two resources in the second resource group: a Team Services Account and a DevOps project.

VSTS Artifacts

Next, let's have a look at what is going on in VSTS. Login into your VSTS account and have a look around.

NOTE: You can go directly into your project in VSTS from the DevOps project in Azure by clicking on the link shown below in Azure:



You will find that a new project was created for you.

Click on the project that was just created, then click on Build and Release >> Builds. A new build was created and it shows that it successfully ran.


Click on Build and Release >> Releases. You will also discover that a release was created for you and that it has also completed successfully. 

Continue to look around in VSTS by checking the build and release definitions.

Unit Tests

As mentioned before, there are two projects in our Visual Studio 2017 solution. One happens to be a a Unit Testing project that uses the xunit framework. Let us look at the Build tasks in VSTS in order to determine whether or not out test cases are being executed. 

Click on Build and Release >> Builds.

Click on the build definition that was created for you by the DevOps project in Azure as shown below.

Click on Edit in the top-right.
There are two tasks that have already been defined:
  • Build an image
  • Push an image

It is obvious that unit testing tasks are absent. Let us add tasks that will run our unit tests. These must be added before the push & build image tasks. Click on + then add three .NET Core tasks. 
You can drag-and-drop three of these .NET Core tasks and place them before the already existing tasks.
Change the configuration of each of the .NET Core tasks as follows:

First .NET Core task
Display Name: Restore
Command: restore
Path to projects: **/*.csproj

Second .NET Core task
Display Name: Build
Command: build
Path to projects: **/*.csproj
Arguments: --configuration $(BuildConfiguration)

Third .NET Core task
Display Name: Test
Command: test
Path to projects: **/*Tests/*.csproj
Arguments: --configuration $(BuildConfiguration)
Publish Test Results

Below are the screen captures of each of the three .NET Core task configurations:


This is all we need to ensure that our test cases are processed. Let us queue a build and see what happens. Click on Save & queue >> Save & queue on the top right side.
On the next dialog, simply click on the Save & queue button.

To see progress of the build, click on the link on the top-left side.
After the build completes, click on Tests on the left-side and you will see that all eight test cases have successfully passed.

Eventually, when the build is successful, it will automatically trigger a release.

Whenever any application code changes are committed to source control, the build and release processes are automatically triggered. Let's see for ourselves that this is indeed the case. Let's make a change to the code in GitHub. Find the file CompoundInterestCalculator/Calculator/Models/CompoundInterest.cs in GitHub. Edit the document by clicking on the pencil icon on the top-right side:
We will disable a piece of logic that is important to one of the test cases. Comment out statement "throw new Exception("Principal amount cannot be negative.");" on line 19.  then click on the "Preview Changes" tab.



Enter a comment under "Commit changes" then click on the green "Commit changes" button. 


The above edit an commit automatically triggers a VSTS build. Return to VSTS then click on Build and Release >> Builds. Click on the build definition.


You will notice that the last build failed. Click on the failed build to find out the root cause. There is a red X beside Test node. Click on it.

More detail is available regarding what exactly happened as shown below:


It is clear from this short walk-through that the DevOps project in Azure has automatically done many of the steps that would have had to be done manually in VSTS. We only needed to do a minor tweak to the generated build definition by adding three tasks to run our unit tests. I am sure this new DevOps addition to Azure will become much more mature and useful with the passage of time.



Friday, March 23, 2018

Continuous deployment and delivery of Angular App with VSTS & Azure

Background

This tutorial describes processes and best practices for an end-to-end continuous deployment and delivery of an Angular Application.

Assumptions:

  •       Node.js, npm and angular-cli are installed on dev computer
  •          Angular is installed on your computer: npm install -g @angular/cli
  •          GIT is installed on the dev computer
  •          Developer has access to an account on VSTS (Visual Studio Team Services) at http://www.visualstudio.com
  •          Developer has an account on Azure (http://portal.azure.com)

Creating a simple Angular CLI app on dev computer:

Create an angular app using angular-cli:
ng new angular-hello-world
cd  angular-hello-world
ng serve
Point your browser to http://localhost:4200 and you should see the following:

Web.config file

In order for Angular’s routing to work smoothly on Azure, it is necessary to have a web.config file in the root folder of the application. Therefore, create a web.config file in the src directory and add to it the following code:

<?xml version="1.0"?>
<configuration>
   <system.webServer>
      <rewrite>
         <rules>
         <rule name="Angular Routes" stopProcessing="true">
            <match url=".*" />
            <conditions logicalGrouping="MatchAll">
               <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
               <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
               <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
            </conditions>
            <action type="Rewrite" url="/" />
         </rule>
         </rules>
      </rewrite>
   </system.webServer>
</configuration>

To enable the web.config file to be packaged with production code, edit the angular-cli.json file and add ‘web.config’ to assets, as follows:
. . . . .
"assets": [
  "assets",
  "favicon.ico",
  "web.config"
],
. . . . .

Build app

Build the app using the following command:

ng build --prod

This produces the production version of the application into the dist folder. To test the trans-piled version of the app, point your browser to http://localhost:4200/dist. You should see the same app as before, this time it is being served from production code.


 VSTS

VSTS is Microsoft’s DevOps platform. Login into VSTS and create a new project. In my case I created a new project named angular-hello-world.



Once the project is created in VSTS, it is time for us to push our code to VSTS using GIT. Copy the address of the GIT repo so that we can use it to sync our code.


Back at your computer, run the following commands from your command prompt to push the code into your projects VSTS git repository:

git remote add origin {your-git-url-here}
git push -u origin master
In my case, this would be:

git remote add origin https://medhat.visualstudio.com/DefaultCollection/_git/angular-hello-world
git push -u origin master
Click on Code >> angular-hello-world in VSTS to verify that your code is indeed in VSTS:


The code will look like this:


 Building the code in VSTS

The same steps that we carried out to build our app on the development computer will be translated into tasks in VSTS. To build our app, choose: Build & Release >> Builds:


Click on the “+ New definition” button:



On the “Select a template” page, scroll to the bottom of the list and highlight item “Empty”, then click Apply:


Select “Hosted” in the “Default agent queue” drop-down-list:


Next, click on “+ Add Task” on the left side:


In the filter, enter npm. Highlight the npm task then click on Add:



This task will install all the npm dependencies:


The above task runs the command “npm install”. You do not need to make any changes to this task as it does exactly what we want it to do.

Add another npm task to run “npm run build” command, which is essentially a script in our package.json file:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
The second npm task should look like this:


Display name: build
Command: custom
Command and arguments: run build --prod


 Create release package

Click on the ‘Add Task’ button, enter “archive” in the search box, hover over the Archive Files task and click Add. Change the “Archive files” task as follows:


Display name: create release package
Root folder (or file) to archive: dist
Prefix root folder name to archive paths: UNCHECK


 Publish release package

Next, we publish the zip we created in the last step. Click on the Add Task button, enter “publish build” in the search box, hover over the Publish Build Artifacts task and click Add:




Display name: Publish release package
Path to Publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
Artifact Name: drop
Artifact Type: Server
That’s it for all our steps. Let’s run the build! Click on Save and Queue >> Save and Queue in the top right hand corner.


On the next dialog, click on “Queue”

Now the build will run for us. While that is happening let us turn on continuous integration so that when we make changes in our repository it will trigger a new build.

Click on the build number link in the in the top left-side corner. This will allow you to see progress of the build. When the build is completed without any errors, you will see a green “Build Succeeded” message as shown below:


Artifacts

You can see the package that was created by selecting the Artifacts tab:



Download the drop folder to see what was created inside that directory.

Continuous Integration

We will need to setup continuous integration so that whenever new code is committed then the build process is kicked off. Click on the build as shown below:



Click “Edit” on the top right-side:


On the next page, click on “Triggers”:



Enable continuous integration by enabling the switch:



Click: Save & Queue >> Save:



On the next dialog, add a comment then click Save:



Creating Release

Log into Azure and create a web app.



Create a release definition by clicking on Build & Release >> Releases:


Next, click on the blue “+ New definition” button. Under ‘Select a template select Azure App Service Deployment then click Next >:



On the next dialog, make sure that you have the right build name and enable “Continuous deployment”:



Click on “Create”:

Choose your Azure subscription then click on the blue Authorize button:


After you log into your Microsoft account, the border around the “Azure subscription” field will change from red gray. Choose the correct azure web app in the “App Service name” field. Your release task will look like this:



Click Save:



You can enter a comment in the following dialog then click on OK.



Click on Release >> Create Release:


This displays the following type of dialog:



Choose the correct build that will be used for the release. In the above example it is 40.

Click on Create.



Click on the link beside the definition file to see progress:


If all is well, the blue “IN PROGRESS” bar will change to a green “SUCCESS” bar.