DevOps is an evolving term that is becoming quite popular amongst IT organizations these days. It is a set of practices that automates the process between software development and IT teams. The process involves building, testing and releasing the software faster and more reliably. Using DevOps increases the speed of delivery in organizations and improves quality. DevOps aligns effectively with agile principles in order to deliver changes frequently. Below are key practices that are a part of the DevOps lifecycle.
A pipeline is a logical group of activities which are performed together to accomplish a task. Azure Pipelines are used to serve the purpose of build, test and deploy to any language, platform and cloud. This pipeline is used to configure CI(Continuous Integration) and CD(Continuous Delivery) and is referred to as build and release pipelines. Pipeline execution is taken care of by agents ( either Microsoft hosted or Self-hosted) and execution time is charged based on the build and deployment time needed for a project.
If the software needs to be continuously integrated and deployed, below is a description of the process followed:
- Commit: Commit is defined as a change that has been done on the code base and pushed to the repository.
- Build: Build compiles all the source code of the project to create a final package.
- Automated Tests: This phase executes the test cases written as a part of the project. And this helps identify issues with the code change by reporting the test cases execution analysis.
- Deployment: The version which is building can be deployed to any environment needed.
This blog focuses more on the practices of Continuous Integration and Continuous Deployment which are part of DevOps.
Continuous Integration is a development practice where developers integrate the code frequently to a central repository. Each integration will be verified by automated build and tests.
Continuous delivery is a practice designed to deploy the changes to production like environments before moving to production. This is to ensure applications function as expected using automated testing.
In contrast to continuous delivery, continuous deployment is a deployment that is made automatic after acceptance tests.
Let’s now understand how to configure the CI as well as CD for an Azure app service from VSTS.
How to configure CI?
Building and Testing are the main activities of the continuous integration task. To configure it, we need a pipeline which takes care of building the solution as well as running the test cases written. The building also includes restoring NuGet packages if required for the solution to build successfully.
Following are the steps to create a build definition, captured from VSTS project using Git as source control:
Please note: The steps listed below assume the solution is already part of source control (ex: Git) using VSTS along with branches required ( for ex: Dev and Master Branch along with local dev branches)
1. Once you login to VSTS account, there is a menu option available named ‘Pipelines’ which has inner menu items ‘Builds’ and ‘Releases’ to manage builds and release definitions.
2. From Builds menu, create a build definition by selecting the source of the solution where it is stored and the default branch from where the builds should be triggered.
3. Now select a template for the build definition. In this case, the solution is deployed on Azure app service. Select the ‘Azure Web App for ASP .NET’ highlighted and click on ‘Apply’
4. Now, the build definition is created along with a deployment step of an Azure app. Since we want deployments to be triggered with respect to environments, remove the step by selecting the step and clicking on remove option. Other steps will take care of restoring NuGet packages, running test assemblies if any are part of the solution and publish the artefacts required for deployment. If the solution doesn’t have test cases written, remove the “VSTest -Test Assemblies” step as well.
5. Now, select the specific solution path on which build definition should be triggered by selecting the pipeline option and solution field.
6. Now, go to the Triggers tab and enable the continuous integration option. This means that any commit that happens to the solution by dev team will trigger the build immediately. Also, select the branch respectively in the branch filters. If you want to use same build definition for all the branches in the repository, just type * and hit enter.
7. It’s all set in the definition. You can play with other options like modifying retention policies, updating the naming format of the builds. Below is the snapshot of the builds and the status in case of failures and success. You can view the details which commit along with developer name, a branch has triggered the build and with duration of the build time.
How to Configure CD?
Continuous Delivery and Deployment involves doing the deployment to the environments needed. This set up assumes we have three environments – Dev, QA and Production and the build created above will trigger the deployment. Let’s understand how to configure the release definition.
1. From the Pipelines menu, navigate to “Releases” and create a new release definition. As you can see, the definition requires two things artifacts and stages. Artifacts mean the published files created by the build. Add an artifact by selecting the respective build definition of the application. Add the environments required to monitor the deployment.
2. Adding artifacts.
3. Adding stages. Click on “Add Stage” and select the template type “Azure App Service” as the build should be deployed on Azure web app and click on “Apply”. Input the name and owner to the stage. For Ex: Dev.
4. Provide the attributes to the deployment template that has been added. In this case, since it is azure app service, azure subscription and app service details need to be provided. To add azure subscriptions to the VSTS account, create a new service connection. Please refer https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=vsts
5. Based on the requirement, pre and post deployment conditions like approvers, triggers can be enabled. Below are the pre-deployment conditions that can be configured for each stage (environment) if needed.
Below are the post-deployment conditions that can be configured for each stage(environment) post-deployment on the respective environment.
6. Since there are multiple stages (environments), different variables (app settings) can be tagged with respect to the environment using the ‘variables’ option. These variables will be added/updated during deployment to respective environment. In the image below, the variables of prod are filtered as the scope selected is “Prod”.
Since both, the build and release definitions, are ready, the process can be tested by creating a local (feature branch). Create a pull request to merge with the default branch (ex: Dev) and then monitor the build and release status of the application.
More Points :
1. There can be a single build definition and the build can be renamed based on the branch by adding a PowerShell task at the end in the build definition with the script below. This helps us to understand from which branch commit the build got triggered.
2. You can have your own branch policies to restrict commits directly to the branch, add reviewers to approve the incoming commits, make work items mandatory while creating a pull request. A pull request is a request that pulls the commit from the source branch to the selected destination branch.
3. Git feature branch workflow can be used in order to leverage continuous integration features. This helps when there is a large team and each feature developed by a team member using a feature branch is independent of the main branch which is always error free.
Why CI and CD ?
Following are the benefits using CI and CD :
- Faster Delivery: Automated Delivery helps organizations respond to market changes better. The need for speed is of utmost importance to reduce the deployment time of the new features. Also with this approach, organizations have a better chance to be at par with their competition and stay in business, and faster delivery increases the ROI.
- Low-Risk Deployment: Integrating code frequently reduces the risks between deployments as there is a very small time-gap between the releases and the issues are caught sooner. Also, the scope of assumptions on the issues is reduced.
- Lower Costs: Since the build and deployment are automated, cost of maintaining the builds and deployments is reduced.
- Secured Releases: Continuous Delivery helps to secure the releases by keeping the approvals for deployments on any environment. This avoids releasing the broken build onto the system.
- Improves Collaboration: As the process has frequent deliveries, entire product team (business, dev and operations) has to have frequent internal communication to discuss the requirement and fill the gaps soon, if any. This increases transparency and helps in making effective decisions.
- Running Tests in Real World: At times things can “work locally” because when they are tested, it is just a snapshot of the local codebase and by the time team pushes changes, things change. CI helps in running all the test cases in the central code base which helps to spot any integration challenges faster.
- Switch releases: There can be multiple deployments of each release even for one environment with a possibility to switch back to the working release in case of deployment failure at any point in time. When the deployment of a release fails for an environment, the previous release can be redeployed to that environment.
- Decrease Code Review Time: We can configure CI and Version Control System to communicate with each other to point out when a merge request is good to merge, for example, all the tests have passed and it meets all requirements. In addition, even the difference in code coverage can be reported right from the merge request. This can dramatically reduce the time it takes to review a merge request.