Simple SQL Server, .Net Core & Angular Deployment with Azure DevOps

Jesus Angel Moreno Leon
The Startup
Published in
8 min readOct 6, 2020

Code deployment is one of those task developers must do on day to day basis, with nowadays technologies this has gotten to a point where it can be fully automated with barely human intervention and all of it almost for free. With that being said the goal of this article is to describe how to successfully implement a Full Application deployment in Azure DevOps.

This is not a walkthrough sorry, I do prefer to explain things with a real implementation even if that means to skip a bit of the information. The idea is to get to what we really care, that is the final look of the configuration.

Tech Stack

As you might know, a web application is typically composed of 3 parts; storage, services, and the user interface, all of them interact together to serve all the application capabilities to the end-users. These are represented by the following code projects.

  1. Database (SSDT — SQL Server Data Tools)
  2. .Net Core API
  3. Angular 8

This gives us the first guideline of how to compose the deployment, we can understand this as the steps to follow to get it all working.

Pipeline

A general definition can be understood as the programmatic steps to achieve something, it does not necessarily mean to deploy code, however, in software development 99% of the time that is the real goal.

Microsoft’s definition:

Azure Pipelines is a cloud service that you can use to automatically build and test your code project and make it available to other users

Now that we have some basic understanding of a Pipeline let’s dive into what exactly are we trying to do. A deployment pipeline is very often composed of the followings:

  1. Develop. Is the assets and source code produced by the development team, it should reflect the business needs.
  2. Build. Is the process of converting source code to another form of code or deliverable that can be understood and executed by machines.
  3. Deploy. It the process from which a specific version of the software is available for use, it can be to a distributed environment with multiple nodes or to a single web server for example.
Pipeline workflow

Remember, this is a simple pipeline strategy, other approaches can include unit testing, code checks, pre-conditions, and so on.

Build & Deploy

Besides the coding activities, we have the Build & Deploy steps on our workflow, in Azure DevOps these are represented as Pipelines & Releases respectively so we will continue with these terms from now on.

The goal of this setup is to end up with 3 Pipelines per each one of the data tiers of our application database, backend, and frontend. The same will happen for the Release but we will get to them soon.

Database pipelines for db, api and web

Database Pipeline

Pipeline. Defines the name, the Agent which is where the job is going to be executed, and finally the artifact name.

Database pipeline name step

Get Sources. Where to get the code from? typically is a composition of Provider — Project — Repository-Branch,

Database pipeline get sources step

Build Solution. This is where the target project is set up so we have to indicate the explicit location on the repository branch. We can also manipulate some parameters like the build version, and the architecture x64, or x86.

Configuration (debug/release), this is important because it defines what kind of deliverable we are producing, the main difference is that the debug version is not optimized, additional information is required and generated to be able to set breakpoints in the code so developers can run programs step by step. A release version lacks all of this information and is fully optimized. That being said, the build process will even change the original code for something equivalent to the sake of better performance.

Database pipeline build step

Artifacts: This is an important concept of the build process, it is the package that encapsulates all the assets produced by a build process it contains the deliverable code and other files that can be included manually during the build process. These are formally published internally in Azure DevOps so they are available for other processes to pick up.

Database pipeline publish step

There you go, this all we need to successfully run a database build in .Net. Remember this is only the first step, it finishes when we have produced the artifacts so they are ready to be deployed to the target environment.

Database Release

The release is basically the job where the artifacts are deployed so they are now available for end-users. It is composed of

  1. Artifacts. We already explained this. They work as the source of our release job.
  2. Stages. These are a logical organization, so we can add steps into our deployment strategy like pre-conditions, testing phases, stopping dependent services, and others.
Database release view

Dacpac Deploy. Our stage job is very simple as you can see it only configures the dacpac and connection string to the remote SQL server.

Note: I’m not a fan of repeating my self not only in code but also on the web, that being said this database pipeline and release should work as a good point of reference to apply the same approach to the Net Core API. Of course, there are a few things that change because the SSDT project is very different however that’s exactly what I’ll try to go over, the differences.

.Net Core API Pipeline

The fundamental difference is the build command line, this command line works in Azure DevOps as well as your local machine:

Publish Command Line: dotnet publish — self-contained=false — force — runtime win-x64 — configuration Debug /p:EnvironmentName=Development — output=dist

I’m would like to extend on two values of this command:

  • — self-contained=false. You might be wondering why this is not self-contained. Well, with this development we are still using on-premise Windows Servers as hosting environments so they already have the .Net Core Runtime. That being said, a non-self-contained publish will exclude those runtime dependencies which ends up being a lighter deployment artifact.
  • /p:EnvironmentName=Development. In Azure DevOps configuration concerns are handled through Environment Variables which is is a very old but useful concept of Windows OS. This value defines the deployment configuration to be load on runtime and depending on the hosting setup this value can be scoped to the application scope or at the server level.
.Net core api publish command

You might be wondering why we are calling publish instead of the build command, this is because the default configuration of the publish command is to build the application first and finally do a local publish under Debug or Release folder. Of course, all of this is configurable trough additional parameters but we keep it simple. The two steps are done at once and just the transmission of those files is left for the release job.

.Net Core API Release

A simple FTP transmission is good enough however there could be other additional considerations. For example, the target application can be in use for some program of the hosting server or even for active users which in that case we will not be able to replace the respective files. I mention this because this is where the pre-conditions of the stage are useful, we can add additional tasks to display a maintenance dialog and also to drop connections or other processes that could be using the service at the beginning of the deployment.

Net Core API FTP deployment

Angular Pipeline

Being a completely different platform and actually a non-Microsoft product we have to install a few things before building this app.

Angular CLI. Installs the core engine of Angular and all of its features so we can build, test, and deploy our projects.

npm install angular cli

NPM Install. By default, installs all module dependencies listed in package.json. It can be also understood as the restore NuGet packages of .Net projects but applied to Angular.

npm install

Ng Build. Again, a source code transformation happens in this step, we can also find a configuration parameter that indicates the environment concerns of this build. In this case, the “dev” value parameter decide which transformation is applied to the environment.ts file of our project.

baseHref=/dev/web. This parameter defines the root location of our application which in this case is not located in the domain root. This adjustment is needed so resources like js files, images, and others can be found in runtime.

Finally, publish the artifact for the Release job.

angular publish artifact

Angular Release

I’m not including an image of the artifact stages of the job because it is exactly the same as previously shown, one source artifact and one stage job. As you can see there are no remarkable differences. again, the FTP transmission is our deployment method.

Angular FTP transmission

Conclusion

Creating an automated build and deploy strategy is not that hard however it is a fact that a lot of little pieces might work well to achieve this; we haven’t talked about permissions, hosting options, unit test, environment configuration, shared resources an lots of different things that can be included in this article but, we would like to stay focus on what this is about which is, build and deploy.

Remember that your team can always implement variations that work better in your development environment. A guideline like this will never cover all the specific details that you might have in mind when reading this article. Take your decisions and learn from them, there is no other way to succeed.

A guideline like this will never cover all the specific details that you might have in mind when reading this article. Take your decisions and learn from them, there is no other way to succeed.

--

--