Have you ever wanted to deploy multiple parts of applications to the same web app? I have found that it isn't completely uncommon to have the an Angular CLI project along side an API project. Some projects deploy these separably but what if we wanted to deploy them together to 1 web application on Azure? This is completely possible through Visual Studio online's builds.
I took a little inspiration from John Papa's implementation of deploying an Deploying Angular to Azure. While this is great for a lot of cases, we had an existing Angular 2 App that we wanted to deploy in the same web application as our API. There are several options out there to deploy this but we ultimately decided to deploy these together because we do multiple deployments of this application and didn't want to have to maintain 2 web apps for every deployment.
Before we dive in too deep let's make a couple assumptions of what we actually need in place to make this work:
- An Angular 2 CLI in GitHub
- An ASP.net Core Project on GitHub
- An Azure Account Sign Up Here
- An Visual Studio Team Services Online Account Sign up here
- A Project on your Visual Studio Team Services account
Before starting we need to have a little idea of where we are going. To get the optimal structure, it was the best fit for our application to have 2 build definitions:
- Server Build - This build definition will contain the build for the ASP.net application.
- Angular Build - This will contain the build of the Angular Application.
In addition to the Build Definitions, we will also be creating a simple Release Definition for publishing both builds to Azure.
The ASP.net Build
The simplest of the builds is the ASP.net build. To get started with this,simply do the following in your project in Visual Studio Team Services:
- Go to Builds under the Builds & Releases
- Click New Build Definition
- Select the template ASP.net Core
- Select Hosted for the build Agent
- Select the desired repo
- Save & Queue Build
That is it for the ASP.net Build!
The Angular CLI Build
Now lets make this a little more interesting by throwing a little more complicated build at it. The Angular build is not that much more complicated, just requires a few more manual steps. (If you have read John Papa's example, this will be a repeat essentially)
Setting Up Angular CLI
- Click New Build Definition
- Select Start with Empty Template
- Click Add New Task
- Select Command Line
- Make the first command with the following settings to install Angular CLI:
Install NPM Packages
- Add Another Task and Select npm
- Add Another Command Line Task that has the following settings
This is where things get changed up a little, most examples show publishing directly from the build, but we are saving that for a later time in the Release Definition
- Add Another Task and Select Publish Build Artifacts
- In the Path to Publish & Artifact Name put dist
Wait..What about publishing to Azure?
I know most examples in the build definition they show adding the publishing in the build, but we are actually going to do this in a release so we can pull both the Server and Angular builds into one release.
We are going to now build the Release Definition in the following steps:
*Deploy ASP.net Application *
- Goto Releases Tab under the Builds & Releases
- Click New Definition
- Select Azure App Service Deployment. This will give us a good starting point and save a few steps. If you want to trigger it on builds, be sure check the box for it
- Select the Server Build as the Build Definition source.
- The Editor will now ask you for your Azure Subscription and the desired App Service Name
Deploy the Angular Application
- Click Add Agent Task
- Select Azure App Service Deploy
- Select the same Azure Subscription and desired App Service Name as above.
- Now select the Project or folder and select the dist folder of your UI Build
A few more things..
While this gets your deployment going and essentially merging 2 applications into 1 deployment. There are a few things to keep in mind:
- You will need to adjust your catch all route on your ASP.net to catch any routes that the Angular app should catch.
- Make sure your ASP.net app is set to use the index.html as the default.