Deploying an Angular application with Azure Pipelines
In this article, I explain how we can deploy an Angular application to an App Services in Azure Portal, by using Azure Pipelines. In this example, I’m using a repository in Azure DevOps environment.
Azure Pipelines automatically builds and tests code projects to make them available to others. It works with just about any language or project type. Azure Pipelines combines continuous integration (CI) and continuous delivery (CD) to test and build your code and ship it to any target. (Microsoft Docs)
Creating an Angular Application
For example purpose, I’m going to create a new Angular application using Angular CLI. If you don’t have it yet, you can install it by using the command
npm install -g @angular/cli. Also, it’s necessary to have an Azure account in order to deploy the application, and an Azure DevOps account in order to create the pipeline.
With the command
ng --version you can check which Angular version you have. In this example, I’m using Angular 13:
Let’s create an Angular application with the command
ng new application-name. And we can run the application with the command
ng s. And we can access the application in the browser by accessing
Creating Services in Azure Portal
In Azure Portal (https://portal.azure.com/) we need to create a “Resource Group”:
After that we can create an “App Service”:
Click in “Create”:
In the next page inform all the required data and make sure to select “Node 16 LTS” and “Linux”:
When you access the App Service in Azure Portal, you can see the URL to the application:
This is the default page that will appear when you try to access it:
There is a VERY IMPORTANT configuration that we must do in order to be able to run an Angular application in an App Service in Azure. If you don’t do this configuration, when you deploy an Angular application in a App Services, you will notice that the deployment will succeeds but even though, it will not be possible to see the app running in the browser, you will only see this page:
This happens because with a Linux environment there is no server that serves up the server that we are going to deploy, so we need to do it manually by using the PM2.
“PM2 is a daemon process manager that will help you manage and keep your application online.” (You can read more about it here: https://pm2.keymetrics.io/.)
PM2 is an Advanced production process manager for node.js. This allows us to run applications and run processes inside Node. In order to configure it, go to the App Service you just created > Configuration > and in the “Startup Command” add the command
pm2 serve /home/site/wwwroot -no-daemon-spa and click in Save:
If you don’t do this, when you run the Pipeline it will succeed but the application will not be visible when you try to access it.
After doing this configuration, if you try to access the URL of the App Service now, the following page will be displayed:
But don’t worry, after we do the deployment, the application will be available.
Creating Services in Azure DevOps
In Azure DevOps (https://dev.azure.com/) we need to create a repository:
We can then push our code to the repository by accessing the Angular project folder and using the commands:
git remote add origin INFORM_THE_REPOSITORY_URL
git add .
git commit -m "Initial commit"
git push origin master
Creating the Environments
Before actually implementing the pipeline, we can create eh environments we want to have. For example, we can have “Development”, “Acceptance”, “Production”, and others. In order to do that, go to Pipelines > Environments and click in “Nem Environment”:
In this example, I create three environments: “Development”, “Acceptance”, and “Production”:
You can also configure that in order to be deployed to some of these environments, someone needs to approve. For example, let’s create this configuration to say that in order to deploy to the “Production” environment, some user must approve it. In order to do that, click in the Production environment and go to the configuration > “Approvals and checks”:
Click in the “+” (add check) button:
Select “Approvaels” and click in “Next”:
Inform the users you want to give permission to approve and click in “Create”:
In case you select more than one user, you can also configure if ALL users must approve, or if one, two, or how many users you want must approve.
Creating the Pipeline
Implementing CI and CD pipelines helps to ensure consistent and quality code that’s readily available to users. And, Azure Pipelines provides a quick, easy, and safe way to automate building your projects and making them available to users. (Microsoft Docs)
The Pipeline is where the CI/CD process happens. “Continuous Integration (CI) is the practice used by development teams of automating merging and testing code.”, and “Continuous Delivery (CD) is a process by which code is built, tested, and deployed to one or more test and production environments.” (Microsoft).
Now that the Angular code is in the repository and we already created the environments, we can then create the pipeline. Go to “Pipelines” and click in “Create Pipeline”:
Select the “Azure Repos Git”:
Select your project:
And then you should see the following page:
Now you can delete everything below the comments and we will create it from scratch. Remove it and click in “Save and run”:
Because we save it, you can see that a new file named “azure-pipelines.yml” will be added to our repository:
This is the file that we are going to use to configure the Pipeline. Now we can finally start to implement it.
A common problem that can happen the first time you run the pipeline, is the “free parallelism grant” error. In case you see this error in your pipeline, you can access the link and do the request (note that can take around 3 days to be approved — in my case, took only some hours and the permission was granted):
This is the message in the image above:
##[error]No hosted parallelism has been purchased or granted. To request a free parallelism grant, please fill out the following form https://aka.ms/azpipelines-parallelism-request
If can see if you have this error by accessing “Pipelines” and clicking in the pipeline:
Implementing the Pipeline
Now we can finally implement the YML file for the Pipeline. In the “azure-pipelines.yml” file we have the following main steps in this exact order:
- 1- Node.js will be installed
- 2- The application will be build
- 3- The unit tests will be executed
- 4- The files will be zipped
- 5- The artifact will be created
- 6- The deployment will be done IF build succeeds (in this stage is where the application is being deploying to the App Service in Azure Portal)
- 7- Where the deployment to acceptance environment can be done (in this example, it is only printing a message, just for demonstration purpose)
- 8- Where the deployment to the Production environment can be done (in this example, it is only printing a message, just for demonstration purpose)
Below you can see the complete yml file, and I will also explain each step (note that in a YML file, the amount of spaces/tabs matters, so you need to be careful with that):
In line 6 we define when the pipeline will be executed. In this case, is always when something is merged into master. If you want to specify other branches, you can do like this:
This means that always when something is merged into the master branch or in some branch that starts with “feature/” or “bug/”, the pipeline will be executed. For example, if you create a branch named “feature/task-01”, because the branch’s name starts with “feature/”, it will also run the pipeline when something is changed in the branch.
In the Build stage, we are:
- Installing Node version 16
- Installing angular CLI and building the application (note I’m first using the
cdcommand to open the app folder, and after that I’m installing Angular CLI and building with the
- Running the unit tests
- Creating the packages to be deployed:
In the Development stage we are going to deploy the application to the App Service in Azure:
With the “dependsOn” and the “condition” properties, you can be sure that this step will only be executed if the build stage succeeds. This means that if the application is not building or some unit test is failing, the application will not be deployed.
In the “appName” property, you must mention the same name of your “App Service” in Azure Portal:
In the “azureSubscription” you must inform your subscription.
In “appType” make sure to select Linux.
In the last stages, we are actually just printing a message in the screen, but I added these steps for demonstration purpose, in case you want to have multiple environments, which in this case you can use these steps:
If you open the yml file by the repository section, you will only be able to see a plain text:
But if you go to Pipelines > Select the Pipeline and click in Edit, you can then see a useful tool that helps us to configure the tasks:
Then you can click on “Settings” and a helper will be displayed on the right side:
When the pipeline process starts, you can see the stages:
If you click in the stages, you can also see with more details what is happening:
In the first time the pipeline runs with success we need to give permission. Click in the Deploy stage:
Click in “View”:
Click in “Permit”:
The pipeline will run and the system will be deployed to the App Service. But note that because of the configuration we have done, it will be necessary to give permission to deploy to Production:
Just do the same configuration we did before for the other stage:
And click in “Approve”:
After that all the steps will be completed, and you should see that the pipeline is now green:
If you click in the pipeline you can also see the four stages we created:
If we access now the App Service URL, we should see the application deployed:
Working with Azure Pipelines is a great way to implement CI/CD to your projects. In this example, we saw how can we implement the pipeline using a repository in Azure DevOps, but you can also use repositories from other sources such as GitHub or BitBucket and implement the pipeline in Azure DevOps. Pipelines are very useful and bring many benefits since you don’t need to deploy your app manually and as we saw in this article, it’s also possible to configure to only deploy the app if the application is running well and we can also configure users to approve the deployment, making the deployment process even more secure. You can check the code of this project here:
Thanks for reading!