How Azure can help your company expand in multiple regions (5 of 5)
Tags: azuredevops, git, ci, cd
Published: 2021-07-16 16:51:04

A previous article guided you through setting up your repository. You did this by creating multiple branches that reflect the GitFlow model and protecting those branch use policies. Then, I gave you an overview of how pull requests work. This article — the final installment in the Azure series — will show you how to implement Azure’s continuous testing, integration, and deployment mechanisms.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wc74t0kdp1rzix63gmy.png)
 
#Continuous Integration
Continuous Integration (CI) is a practice that allows multiple developers to frequently merge code changes into a remote repository by automating the build, test, and run processes. To implement your own CI pipeline in Azure, follow these steps:
- From the dashboard, select **Pipelines**.
- Click the **New Pipeline** button.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7f1ddd5i9rzi8k8fmpph.png)
 
- Select **Azure Git Repos** as a source that will trigger our pipeline.
- From the multiple templates that Azure DevOps will suggest, select **Starter Pipeline** and paste the following code in it.

```
trigger:
- main
pool:
  vmImage: ubuntu-latest
variables:
  buildConfiguration: 'Release'
steps:
- script: dotnet build --configuration $(buildConfiguration)
  displayName: 'dotnet build $(buildConfiguration)'
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'
```
#Continuous Testing
As mentioned before, the continuous integration pipeline can perform both static and dynamic tests automatically. **Static testing** is a technique to improve the quality of your application by detecting bugs, vulnerabilities, and code smells without executing your application’s code. **Dynamic testing**, on the other hand, focuses on the behavior of your application; it requires execution of your application’s code.
This tutorial will teach you how to perform static testing using SonarCloud.

##Install the SonarCube Extension
To be able to use the SonarCloud functionalities, you must install the SonarCloud extension in your organization using the following steps:
- Sign in to your Azure DevOps organization.
- Go to **Organization Settings**.
- Select **Extensions**.
- Click on **Browse Marketplace** at the top right.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf2mh250xvhbrqtm9wqp.png)
 
- As the Marketplace opens, search for **SonarCloud**. Click on the correct SonarCloud result as shown below.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abxv9a3pr2i803n8ezzs.png)

- Click on the **Get it Free** button.
- Select your target organization from the dropdown, then click **Install** to complete the procedure.

##Link the Project to SonarCloud
It is now time to connect your Azure DevOps project to SonarCloud.
- Navigate to https://sonarcloud.io/ in your browser, then click **Log In** at the top of the page.
- Select **With Azure DevOps** and grant permissions to SonarCloud.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/huwu3398nnrw7yn5psmm.png)
 
- Click on your profile’s icons on the top right side of the window, then select **My Account**.
- Enter the name of your token, click the **Generate** button, and copy the token.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ly606bfjbt5wxiwir160.png)
 
- From your Azure DevOps organization, navigate to your project.
- From the **Project Settings**, open the **Service Connections Page**.
- Click the **New Service Connection** button and select **SonarCloud** to define and secure a connection to a SonarCloud.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/703x6nxewo6yk40irszo.png)
 
- Fill in the parameters for the service connection, allowing all pipelines to use this connection option.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qdl6t9vau8ucibal976.png)
 
- Click **Verify and Save** to create the connection.

##Create a New Project on SonarCloud
Before you continue with the configuration of the CI pipeline, you must create a project on SonarCloud that will be linked to the repository in the next steps.
- Sign in to your SonarCloud account.
- Select the **My Projects** tab on the top left side of the page.
- Click the **Analyze New Project** button.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpsq9a2qvyo3ctrvuoum.png)
 
- Select your organization, check your project and click **Set Up**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dg4sfhjyfke2yj4f0ulp.png) 

##Add Task into the Continuous Integration Pipeline
Now that you have successfully connected your SonarCloud account to your project, you can move forward and add the SonarCloud-specific tasks installed by the extension into your continuous integration pipeline.
- From the dashboard, select **Pipelines**.
- Select the pipeline that you previously created.
- Click the **Edit** button on the top right-hand corner of the page.
- Filter the available tasks for SonarCloud.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aiwb5f24bwvwfdrgd7qh.png) 

The order in which these tasks should be executed is:
1. **Prepare Analysis Configuration:** configures the settings before executing the build
2. **Run Code Analysis:** analyzes the source code
3. **Publish Quality Gate Result (optional):** shows if the code meets the quality standards in the build summary
Let us start by adding a Prepare Analysis Configuration task before the build task. Here you must select the service connection, the organization, how the analysis is done (MSBuild in this tutorial because the example application was developed using the .NET 5 framework), the project key, and the project name.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3qhhnh4b4rztwirylzu.png) 

The project key is the values of the parameter ID in the URL of your SonarCloud project.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4ta028z4owchwjco5b6.png) 

- Add a new **Run Code Analysis** task after your build task.
- Add a new **Publish Quality Gate Result** task on your build pipeline summary.
- Add a new **.NET Core task** with the command **Publish**. Make sure the **Zip Published Project** option is checked.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5001x6yr84u8ath2gmgz.png) 

- Lastly, add the **Publish Build Artifact** task.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gkflmw7qc7wigg78xpn5.png)
 
- Save your pipeline.
The pipeline will look something like this:
```
trigger:
- main
pool:
  vmImage: ubuntu-latest
variables:
  buildConfiguration: 'Release'
steps:
- task: SonarCloudPrepare@1
  inputs:
    SonarCloud: 'SonarCloud'
    organization: 'gtrekter'
    scannerMode: 'MSBuild'
    projectKey: 'GTRekter_Training'
    projectName: 'Training'
- script: dotnet build --configuration $(buildConfiguration)
  displayName: 'dotnet build $(buildConfiguration)'
- task: SonarCloudAnalyze@1
- task: SonarCloudPublish@1
  inputs:
    pollingTimeoutSec: '300'
- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: true
    zipAfterPublish: true
    arguments: '--configuration $(buildConfiguration) --output  $(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'
```
#Continuous Deployment
Now you can create your continuous deployment (CD) pipeline. This pipeline will automatically deploy the changes to the app services you made based on the previous tutorial.

##Create a Connection to Azure Resource Manager
To be able to create, update, and delete resources in your Azure account, you must create a connection to Azure Resource Manager. Azure Resource Manager is the deployment and management service for Azure. To create the connection, perform the following steps:
From your Azure DevOps organization, navigate to your project.
- From the **Project Settings**, open the **Service Connections Page**.
- Click the **New Service Connection** button and select **Azure Resource Manager**.
- Select the **Service Principal (Automatic)** authentication type.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kwzrqnq3a2khqnvtrck4.png)
 
- Select your scope level, filling in the parameters for the service connection and allowing all pipelines to use this connection option.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ko7pkyzxf6ow6safpzfi.png) 

- Click **Save** to create the connection.
##Create a Release Pipeline
- From the dashboard, select **Pipelines** and then **Releases**.
- Click the **New Pipeline** button.
- Select **Add an Artifact**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t22lpqwdw6dk5orpl9nr.png)
 
- Select **Build** as the source type, then select the building pipeline from within the **Source (Build Pipeline)** dropdown.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ksudtwfbav8pgajdxx0.png)
 
- To enable deployment each time a new build is available, click the lightning icon in the top right-hand corner of your artifact. Enable the **Continuous Deployment Trigger**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsm9etle94qa0yp0hhf1.png)
 
- Click on **Add a Stage**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/llena5yqxcbp0ahxk9rf.png)
 
- Select **Empty Job**.
- Click the + icon then select the **Azure App Service Deploy** tasks.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36na2nm2av333wevlavg.png)
 
- Select the service connection to the Azure Resource Manager that you have previously created; target the App Service. The example shows deployment of the application in the App Service hosted in a server in the Central United States.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qlcpkl7z0pg2226qo6lt.png)
 
- Go back to the **Pipeline** tab.
- Click **+ Add** and select **Clone Stage** from the dropdown.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yldpye1rip6824ah4xn.png)
 
- Change the App Service of the cloned stage to point to the App Service hosted on a server in Northern Europe.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yh0nrzrv33eju1uhs3db.png)
 
- Click the **Save** button at the top right-hand side of the page.
Congratulations! You have finished setting up the proposed architecture.
#Testing the Architecture
Now that the entire architecture is finally ready, you can test the entire workflow.
- On your local machine, change your application’s response to an HTTP request at the root by pasting the following code into your **Configure** method of your **Startup** file.
```
app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("How Azure can help your company expand in multiple regions - Part 5");
    });
});
```
Stage, commit, and push the changes on the **feature-amazingfeature** branch to the remote repository.
```
$ git add .
$ git commit -m "Change the response"
[feature-amazingfeature 369b799] Change the response
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 192.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Analyzing objects... (3/3) (20 ms)
remote: Storing packfile... done (109 ms)
remote: Storing index... done (116 ms)
To https://dev.azure.com/GTRekter/Training/_git/Training
   d7b19ea..369b799  feature-amazingfeature -> feature-amazingfeature
```

- Navigate to your project on Azure DevOps, select the **Pull Request** option in the **Repos** tab, and click **New Pull Request**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/952q3v8crp0qyadn1kh4.png) 

- Select the branch **feature-amazingfeature** as the source, the branch **develop** as the target, create a title, create a description, and click **Create**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6rnaxykf5dm3hkliqnt7.png) 

- Click approve. Then click Complete to conclude the pull request.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9dzjbty5m1rokp03zgz.png) 

To avoid hundreds of unused branches, check the Delete **feature-amazingfeature** After Merging option, then click **Complete Merge**.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ew88aw6dx93muibmhjv1.png) 

Repeat the same procedure for the other branches:
- **Source:** develop / **Target:** releases
- **Source:** releases / **Target:** main
Once the merge into the main is complete, the build pipeline will start automatically.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jgkv0z0x5gxs908vuydn.png) 

Once your build pipeline is completed, you can view the results of the analysis performed by SonarCloud by navigating to https://sonarcloud.io/ in your browser and selecting the appropriate SonarCloud project.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fktcc7nraa6978e03do1.png) 

If your pipeline successfully completes, your release pipeline will automatically start. This will deploy the application on the two App Services located in different regions.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4d7z928bg0cdnffts6wu.png) 

If you navigate to the URL defined in your Azure Front Door resource, your HTTP request will be forwarded to the geographically closest App Service in the backend pool. In my case, because I am currently in Philadelphia, Pennsylvania, Azure Front Door will forward my request to the App Service located in the Central United States.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qydvhu6qpeivyipb2wf.png)