Volume 30 Number 12
Microsoft Azure - Manage Technical Debt with SonarQube and TFS
By Cesar Solis | November 2015
Technical debt is the set of problems in a development effort that make progress on customer value inefficient. It undermines productivity by making code hard to understand, fragile, time-consuming to change, difficult to validate and creates unplanned work that blocks progress. Technical debt saps an organization’s strength because of high customer-support costs and, eventually, some combination of these issues produces larger problems.
Technical debt is insidious. It starts small and grows over time through rushed changes and lack of context and discipline. It can materialize out of nowhere—even for a project regarded as “clean”—because of changes in project circumstances. For example, prototype code produced for the U.S. market might be proposed for international, instantly creating debt related to localizability. Or, as technologies evolve, the app might not keep up.
Debt comes in many forms, including problems found through code analysis, duplicate code, code complexity, not enough tests, overlapping and flaky tests, and “architectural spaghetti.”
The core problems faced by development teams in managing their technical debt include:
- Understanding and identifying the debt and where it’s located in the code.
- Evaluating the cost of remediation and the cost of non-remediation. Fixing technical debt has a cost. Not fixing it also has a cost, which is even more complex to evaluate and can be bigger.
- Putting policies in place focused on preventing debt from getting worse and managing it down.
- Exposing developers to the debt required to meet the policies in a way that isn’t overwhelming, so that they can tackle it as a natural part of their day-to-day development process and don’t regard it as a huge time-consuming and tiresome chore.
- Tracking debt over time to ensure that it’s trending in the right direction and meeting defined policies.
- Remediating debt as efficiently and automatically as possible.
So, this debt has to be managed—not necessarily eliminated—and, thus, has to be measured. When managed down, it should be prioritized among other new features and desired functionality. The impact should be measured, as well, just as the financial impact of acquiring a home loan is measured.
You need to be conscious of the decisions you make that might increase technical debt during development. You should be able to measure the improvements achieved by actually managing technical debt. This is important to justify the product owners’ (clients, users, managers and so on) investment.
Solutions such as SonarQube from SonarSource collaborate with Visual Studio Team Foundation Server (TFS) to provide strategies to facilitate data gathering and present it in a way that helps manage and reduce technical debt. SonarQube is an open source platform for understanding and managing technical debt.
In this article, we’ll focus on a method of measuring and actively managing technical debt. Called Software Quality Assessment based on Lifecycle Expectations (SQALE), it’s an open source method that focuses on non-functional quality attributes of a software code base (bit.ly/1JQ96qT). The SQALE method was developed by Inspearit France (formerly DNV ITGS France).
According to a SonarSource blog post, technical debt is like a home water leak (bit.ly/1N0Y4A9). When you have a water leak at home, what do you do first, plug the leak or mop the floor? The answer is simple and intuitive: You plug the leak. Why? Because any other action will be useless; it will be only a matter of time before the same amount of water is back on the floor.
With technical debt, “fixing the leak” means putting the focus on the “new” code; that is, the code that was added or changed since the last release, or the last commit/check-in.
Implementing SonarQube and TFS
Figure 1 shows a reference architecture for an enterprise setup of TFS and SonarQube; there’s detailed guidance on capacity, design, implementation and operation of TFS on-premises and in Microsoft Azure Infrastructure as a Service (IaaS) in the “TFS Planning Guide” and “TFS on Azure IaaS Guide,” which can be downloaded from the Visual Studio ALM Rangers CodePlex site (aka.ms/treasure5). This architecture and its implementation are directed toward enterprise-level support by considering high-availability features in the data tier through a database cluster, and in the application tier with a farm.
Figure 1 Team Foundation Server Reference Architecture, Including SonarQube
A scalable SonarQube server deployment can be achieved by setting up multiple SonarQube servers based on individual teams, or by technology taking into consideration the following:
A SonarQube database can be installed within an instance in the database cluster providing a secure way to handle high-availability services.
SonarQube analyzer (plug-in) implements a scalable per-server way of processing loads of analysis data into the SonarQube database.
The database and the analyzers must be located in the same network. SonarSource has been working on refactoring SonarQube (version 5.2) so that it has a three-tier architecture, which will make this constraint obsolete.
All the machines—database, Web server, analyzers—must be time-synchronized.
Prerequisites for Hosting SonarQube and TFS on Azure
To set up a TFS and SonarQube environment on Azure you need to have an Azure subscription with enough credit toward the size of the environment you’re going to create. You can use the TFS Planning Guide (bit.ly/1JzfVJK) to decide on the sizing of Virtual Machines (VMs). The guide also provides recommendations on authentication models such as Stand-alone, Extended Domain and One Way trust options. A great feature of Azure that can help accelerate the environment creation is the available ready-made TFS VM template, as shown in Figure 2.
Figure 2 Virtual Machines Template Available on Microsoft Azure
Network configuration should be selected according to your needs for protecting external access to inner layers of the TFS architecture. Various ways of connecting Azure to on-premises through a VPN should be reviewed as a way to extend corporate infrastructure and gain cloud elasticity. The guide describes best practices and performance tips that are helpful in setting up the TFS environment on Azure. SonarQube requires that the database and analyzers must be located in the same network.
Follow these recommended steps when planning for the installation:
- Determine Azure IaaS suitability. Cloud computing delivers computing capabilities as a service, giving you access to resources such as compute power, networking and storage. Decide whether the constraints are acceptable and whether there’s a value-add.
- TFS planning. Use the “TFS Planning and Disaster Avoidance and Recovery Guide” (bit.ly/1JzfVJK) to determine the best server architecture for your requirements.
- Azure IaaS mapping. Map to the closest Azure VM configuration based on cost and scalability.
- Azure platform governance. Define the account, subscriptions and ownership of administration and reporting to meet your enterprise auditing requirements. Clearly define ownership and responsibilities.
- Network planning. Define your network, which encompasses on-premises requirements, network address segments, affinity grouping, name resolution, Azure tunneling and monitoring.
- Storage planning. Define your storage strategy using on-premises storage or Azure storage.
- Validate. Contact an Azure subject matter expert from Microsoft or Azure communities (bit.ly/1fVTgz0) and validate the plans before committing yourself. Ensure the planned environment is technically and financially viable and can be maintained.
As the intention of this article is to set up a SonarQube server for demo and trial purposes, additional steps are not mentioned here. If you’re planning or provisioning a production environment or a migration from an existing one, you should review the other steps in the guide for a complete plan. There’s also a deployment checklist in the guide that should be followed for a successful installation.
The Azure IaaS reference architecture and installation exercised here is based on the companion proof of concept (POC) detailed in the “TFS on Azure IaaS Guide,” which can be used for sample implementation. While the guide contains detailed steps for setting up the TFS POC environment, there’s no constraint around using the same instructions with your own POC environment or the production one.
SonarQube Installation Requirements
We recommend using the same IaaS SQL Server instance for SonarQube installation, just taking care of specific SQL Server configuration requirements when creating the SonarQube database. The “SonarQube Installation Guide for Existing Team Foundation Server 2013 Single Server Environment” (bit.ly/1itxhS9) has plenty of detailed information and references on how to set up Azure Regions (make sure to co-locate the SonarQube server VM in the same region as TFS) and SQL Server. The SQL Server configuration and database creation has specific requirements to meet for SonarQube. For example, the SQL Database should be case-sensitive and accent-sensitive and this is not the default. SQL authentication also needs to be enabled and a SQL user configured for SonarQube to work. When hosting on Azure you need to change network protocols for SQL Server to enable access to the database from outside the VM by following certain steps. First, using the SQL Server Configuration manager, enable the Named Pipes and the TCP/IP protocol for the SQL Express database, as shown in Figure 3.
Figure 3 Enabling the Named Pipes and the TCP/IP Protocol for the SQL Express Database
Still in the Server Configuration manager, edit the TCP/IP properties, and in the IP Addresses tab, look for TCP Dynamic Ports and make a note of the port (here 49419), as shown in Figure 4. You’ll use it to enable the connection to the database from the outside.
Figure 4 Note the Port Number in TCP Dynamic Ports to Enable the Connection to the Database from the Outside
As shown inFigure 5, restart the SQL Server by right-clicking on SQL Server Express in the SQL Server Services item and choose Restart. Start the SQL Server Browser (in the Service Tab change it from Stopped to Automatic and then start it).
Figure 5 Start the SQL Server Browser
You now need to open a port in the firewall so that the database is accessible from the TFS machine. Type the following in the cmd.exe prompt running as administrator:
netsh advfirewall firewall add rule name="SQL" dir=in action=allow protocol=TCP localport=49419 49590
SonarQube doesn’t require the full JVM installation—Java SE Runtime Environment (JRE) should be enough and there are specific recommendations on how to set it up and take advantage of a x64 processor architecture.
The Setup of the SonarQube Server section in the guide describes the download, installation and configuration procedures when configuring and starting SonarQube, including Windows Firewall settings.
When hosting on Azure you need to enable access to the SonarQube server to be accessible from the outside world. To do so, first turn off anonymous access. To force user authentication, log in as a system administrator and go to Settings | General Settings | Security and set the Force user authentication property to true.
Open the port in the firewall for the Web server. Now you need to open a port in the firewall so that the Web server is accessible from the Internet. In a cmd.exe prompt running as administrator, type:
netsh advfirewall firewall add rule name="Sonar Web" dir=in action=allow protocol=TCP localport=9000
Add EndPoints in Azure for Sonar Web and the database. For the moment, you can log in to the SonarQube machine with a remote desktop and access the database and the Web site. You need to ensure you can connect to these two resources from your machines over the Internet. For this, you need to create Endpoints in Azure:
- Go to portal.azure.com.
- Browse to find the virtual machine where SonarQube is set up.
- In the blade presenting this VM, click on All Settings.
- In the settings, click Endpoints.
- In the Endpoints blade, click Add.
- Add an endpoint named Sonar Web mapping the TCP public port 9000 to the private port 9000.
- Add an endpoint named SQL mapping the TCP public port 1433 to the private port 49419 (the port 1433 is expected by the SQL Server Management Studio or Visual Studio to discover SQLEXPRESS). Note that this step won’t be necessary any longer when SonarQube 5.2 is released.
SonarQube can perform analysis on many languages; first you need to install the plug-ins for the languages of the project to be analyzed from the SonarQube plug-in library (bit.ly/1NdhnYF) or through SonarQube Update Center (bit.ly/1NPKZet). Then you need to install and configure some prerequisites on the build agent, depending on the type of projects: MSBuild.SonarQube.Runner (bit.ly/1LOYzM3), a for .NET- based projects); SonarQube Maven Plugin runner (for Java Maven projects); and SonarQube Runner, a generic runner for all other projects types.
Integrate with Team Build and test the modified build definition, as shown in Figure 6. The SonarQube Runner tool integrates well with Build Agent so it can easily be taken over by development teams used to work with TFS.
Figure 6 SonarQube Performing Analysis with Build Agent
Strategy to Manage Technical Debt
Now that the SonarQube environment is set up, we’ll describe a strategy to leverage technical debt measurement within the agile virtuous cycle to improve the value to the product owner and the business. As noted by the SQALE method, our intention is to define clearly what creates the technical debt, estimate correctly this debt, analyze the debt upon technical and business perspective, and offer different prioritization strategies allowing establishing an optimized payback plan.
The SQALE method, as shown in Figure 7, is used for formulating and organizing the non-functional requirements that relate to the code’s quality. It’s organized in three hierarchical levels: characteristics, sub-characteristics and requirements related to the code’s internal attributes. (These requirements usually depend on the software’s context and language. Any violation of these requirements introduces technical debt.)
Figure 7 The SQALE Method
The SQALE method normalizes the reports resulting from the source code analysis tools by transforming them into remediation costs and non-remediation costs. It also defines rules for aggregating these costs, either following the SQALE method’s tree structure, or following the hierarchy of the source code’s artifacts. In order to manage the technical debt of a software project, you should make the debt visible. Make sure the product owner and marketing personnel know that technical debt exists and repeat to them often, “If we don’t schedule time to pay off technical debt, you may not get all of the features you want.”
The water leak metaphor recommends postponing the current technical debt, except what’s really important and urgent to fix—for instance, security issues. Thus, take a baseline, make sure that you’re aware of any new debt, try not to introduce any new debt (stop the leak) and as you’re working and refactoring code, take the time to fix the existing debt. You’re unit testing it, so this isn’t dangerous to do so (clean up as you go).
Managing technical debt doesn’t need to be budgeted. It’s a change of behavior in the entire organization.
As seen in Figure 8, SonarQube presents a dashboard based on SQALE in order for the team to have a common representation of the quality state of a software project.
Figure 8 The SQALE Method-Based SonarQube Dashboard Within a Project Lifetime
Figure 9 shows the Technical Debt Pyramid widget. Read the graph vertically from bottom to top. First, you want to ensure you’re testable (40min), otherwise, when you change code, there’s no guarantee you won’t introduce more problems. Then you want to be reliable, which will take an extra 42min; so in total, to be reliable you need to spend 1h 22min and so on.
Figure 9 The Technical Debt Pyramid Widget
How to Manage the Technical Debt?
Following are the main steps required to manage the technical debt:
Step 1: Set project goals. There should be a definition of what creates technical debt. The indices are computed based on the average remediation efforts estimated by the development team. Several graphs and diagrams are used to efficiently visualize the strengths and weaknesses of the assessed source code. You should ask:
- Which software pieces contribute the most to the risks?
- Which quality criteria are the most impacted?
- What is the impact of the identified non-compliances on the project or its users?
These are defined goals over a project. SonarQube allows you to drill down to specific issues within the code in order to understand the reason and implications and, thus, plan tasks for paying back the debt. This analysis should be made during agile planning and, if possible, prioritized along Product Backlog Items (PBIs). The PBIs are defined and evaluated to balance or improve velocity or other architecture characteristics. The characteristics are defined from more critical, to the ones that will deliver potential business value, to the product users like portability or reusability.
Step 2: Monitor the amount of technical debt over time. Be able to check results of tasks executed or best practices being implemented. Questions to ask include whether the technical debt increased during the last day/sprint/version and how much margin there is related to the goal set for the project.
Step 3: Analyze the process and the impact. You should also be able to compare technical debt by following up practices between different projects or teams or subcontractors. This could improve practices between teams while taking best practices and applying them more effectively while also better measuring technical debt results.
It’s possible to analyze the origin of the technical debt by answering questions such as Which part of the current debt has been created during the last day/sprint/version, which part of the current debt is inherited from legacy code and which parts of the project have the highest technical debt.
Teams should also focus on specific parts of technical debt in order to optimize the results. For this, ask questions such as which are the most urgent issues to fix within my code, what are the next issues to fix and which violations of “right code” are not so costly to fix and will generate a high decrease of the impact for business.
Finally, if I spend 100 hours to decrease the technical debt, ask how much I will improve my velocity? And what improvement will users perceive on the quality of the application?
The answers to these questions will provide a natural feedback mechanism for finding opportunities for improvement and closing the gaps to a better product.
The SQALE method supports three strategies for addressing technical debt:
- Follow the technical logic (avoid useless rework). Use the SQALE pyramid.
- Decrease the business impact by fixing the non-conformities with the highest business impact.
- Optimize your ROI by fixing the non-conformities with the highest ROI.
Technical debt has to be managed—not necessarily eliminated—and, thus, has to be acknowledged and measured. Choosing to stop it is a good start. You might choose to manage it down, and there are different ways. You might clean up existing debt as you touch code to fix bugs or add new features. Or you might decide remediation actions are important to take for security or conformance issues. Perhaps this is the way your organization thinks it should address the problem. In that case, the work needs to be prioritized among the other new features or functionality desired, measuring the impact on the implications.
You should learn to be conscious of the decisions you make that might increase technical debt and you should be able to measure the improvements achieved by actually managing it.
SonarQube and the TFS integration components help facilitate gathering data from build in the Microsoft Build Engine, or TFS and Visual Studio Online. SonarQube presents technical debt in a way that helps you understand it and plan how to better invest in resolving it. There is ongoing work done by Microsoft and SonarSource (see bit.ly/1OeqftX) to improve this integration further and provide a first-class solution for managing technical debt on a platform.
Cesar Solis Brito has been a consultant specializing in software development in the financial and pharmaceutical fields and at Microsoft for more than 20 years. Currently, he’s an escalation engineer at Microsoft for the Azure Platform. He has been actively working in ALM and related Microsoft development technologies. You can reach him at Cesar.Solis@microsoft.com or follow him on Twitter: @cesarsolis.
Hosam Kamel is a senior premier field engineer at Microsoft, and a Visual Studio ALM Ranger with more than 10 years of software development experience. He currently specializes in Visual Studio ALM and Team Foundation Server. You can reach him via his blog at blogs.msdn.com/HKamel or follow him on Twitter: @HosamKamel.
Thanks to the following Microsoft technical experts for reviewing this article: Mathew Aniyan, Brian Blackman, Harysh Menon, Duncan Pocklington and Jean-Marc Prieur