Adopting Azure DevOps : A Step-by-Step Approach

Last year, we decided to build our own Azure DevOps extension. We realized that it would be pretty ridiculous to create one for other people to use without fully embracing Azure DevOps ourselves. That’s how we decided to transition, and we learned quite a bit along the way.

If you were to look at our DevOps pipeline a few years ago, like most companies and open source projects, we had a mishmash of many different products, services, and bash scripts, all tied together with some duct tape and string. It turned out that there were a lot of pieces to the puzzle. Just like many other organizations, this situation was compounded by the fact that different DevOps tools from different companies didn’t always communicate well with each other. In short, we had a lot of work to do, but ultimately, we got our act together. We now have a beautiful, comprehensive solution that’s all based on Azure DevOps, instead of having multiple systems that everybody on the team had to understand and work with.

Here are the six stages of Azure DevOps integration that we went through. We hope this helps shed light on what you’ll need on your pathway to development nirvana.

Step 1: Find Your Pain Points

I’m a huge fan of Donovan Brown from the league of DevOps Advocates at Microsoft. When he speaks about DevOps, he often says (paraphrasing): “Find the thing that hurts the most. Do more and more of it and get better and better at it until it doesn’t hurt anymore.” We’ve made that a bit of a mantra.

If you’re going to adopt DevOps, and you’re thinking about switching to Azure DevOps, look yourself in the eyes and ask: What is the most painful thing right now in our DevOps pipeline? Is it that we don’t have enoughunit tests?Is it that deploying a new version of the software is a manual, error-prone process? Do you need a 20-page Word document for each deployment?

Even ifyou have a perfectly good DevOps pipeline, even if you’ve reached DevOps heaven, and even if your releases happen with a big shiny deploy button, you may still be breaking things in production. Then, you find that you don’t have the right tool to tell you what you broke (p.s. – that’s where OzCode’s extension can help). Other things may be bottlenecked, or just not working the way they’re supposed to. Identify those pain points and start there.

Step 2: Source Control (from SVN to Git)

I like to think about source control as where our code files go to sleep at night. When we were just starting OzCode, in the early proof of concept stage, we were using SVN—archaic technology, in my opinion—for source control. Then we moved to Git. There are plenty of automated tools to transform data from almost any source control to Git, which makes things a bit easier.

If you’re adopting Git, you should do it with full awareness. Take a look at what you are gaining, but also understand the costs you’ll incur along the way. Git requires a huge learning curve. There are functions like merging, re-basing, and push-pull. It can all seem very complicated and threatening to a newbie.

My best advice on how to deal with that? When you’re starting out with Git, it’s okay to treat it like your old source control system. If you translate what you know about source control and apply the same to Git, you can get away with it. It’s a myth that you have to learn all about re-basing, merging, and re-writing history right off the bat. Over time, you will start to adapt to its more powerful tools.

Our entire industry has been rapidly adopting Git of late, but if you’re late to the Git party and wondering if it’s really worth the switch, he’s my $0.2: Git has one killer feature that is truly transformational: effortless and instant branching. In archaic version control systems, creating or merging a branch was a major thing. Sometimes it could take 30 minutes because you needed to clone an entire copy of your source control.

With Git, you have instant branches that are literally one click away. That means you can divide work into feature branches in a much more efficient way. You can create a branch for each pull request and for each new feature you’re working on without bringing noise into the master. That, alone, will be transformative. It makes it much easier for people to go into a separate feature branch, do their work, and merge frequently with the master. You’ll get more work done with less friction.

Step 3:  Task Management (from Trello to Azure Boards)

Next, it was time to tackle task management. We had been using Trello, which I love for its simplicity. You only have three columns: “TODO”, “Doing”, “Done”. Trello excels at the pure Kanban, no-BS approach to task management: it’s basically a glorified TODO list – you drag the most important stuff to the top, and get them done.

Azure Boards, on the other hand, is much more complicated. There are Work Items and multiple statuses, which means you lose the straightforward simplicity. What you gain, however, is customization, allowing you to adapt to any flow you want.

For example, on the OzCode team board, there are a lot of work items or bugs that are deeply technical—basically, items that don’t require QA once they’re resolved. We decided to simply add a check box for “QA needed”, and created a flow for items that did or did not require QA and which can be assigned automatically. It took our DevOps guy just a few hours to accomplish this.

At the end of the day, you can pick and choose your tools, so if you prefer to stick with something simple like Trello, it will work fine, but you’ll lose traceability. Using Azure Boards with other parts of Azure DevOps allows you to do things like correlate pull requests to fixed bugs, which is incredibly useful.

Step 4: Get on the CI/CD Bandwagon

Continuous Integration (from TeamCity to Azure Pipelines)

Before Azure DevOps, we were using TeamCity, which is a product from JetBrains. It is actually a really good product for continuous integration. Like Azure DevOps, it has an on-premises solution and a SaaS version.

One of the nicest things about using Azure Pipelines, instead of TeamCity, is how fast your builds start. With TeamCity, every time we needed a new build, a VM would be provisioned, and that could take five to ten minutes. This feedback loop was slow and became really annoying. But with Azure DevOps, Microsoft has an infinite pool of hot, ready-to-go build machines in the cloud, so as soon as somebody pushes in a new commit, and the build happens instantly.

Side note/pro-tip: give your old laptop new life as Build Agent

By the way, if you’re trying to save costs and time, you might want to consider using an old laptop or an existing VM as your build agent. Even though Azure DevOps offers a generous 1800 free cloud build minutes per month (and infinite free minutes for open source projects!), there’s a catch – host builds can be slow. Every time a cloud Hosted Agents starts, it’s a fresh, squeaky clean machine – so it needs to clone all of your source code every time. Although the cloud-to-cloud clone process is quite fast, it’s still a waste of time and money for this to happen for each build. Another advantage of using an old laptop instead is that build artifacts that were already on the machine from the previous build don’t need to be rebuilt. This can save even more precious build minutes.

Continuous Delivery (from manual deployments to Azure Pipelines)

Previously, our deployment process was quite manual, and we just ran a bunch of batch scripts. Using Azure Pipelines has been a pleasure: it’s not just about having a big shiny button that says “Deploy” that pushes the software to production. It’s much more than that: Azure Pipelines gives us perfect visibility. If there’s a problem, or if I just want to know whether a specific commit or change has been entered into the new version of the product, I can get that information from the Azure DevOps pipeline almost immediately.

Azure Pipelines is also customizable. For example, being the paranoid person that I am, I always run multiple virus scans on an installer before I release it to customers. So, we’re now writing a new script to automate this process, so that I don’t have to think about it – we send our installers through VirusTotal automatically, and fail the build if something ever comes up. No matter how weird or unique or eclectic you think your scenario might be, Azure Pipelines can automate it for you.

Step 5: Bug Tracking (from FogBugz to Azure Boards)

Our next move was to perform bug tracking with Azure Boards. Before that, we were using FogBugz, and leveraging the fact FogBugz can work as both a ticketing system and a bug management system combined.

As mentioned, Azure Boards is completely customizable. Of course, nothing is perfect, so I can definitely describe Azure Boards in terms of the good, the bad, and the ugly.

The good, obviously, is the customization part. Let’s say that your goal is to link your bug tracking to customer success and customer support. Azure Boards enabled our support engineer to create an issue whenever a new bug was found by a customer. We also automated our workflow with a custom field that linked back from the Azure Boards Work Item to the ticket in our support system, FreshDesk. Upon resolution of the bug, when we deploy a version that includes the bug fix, the customer success engineer or support engineer now gets an automatic email informing them to contact the customer to let them know that their issue was solved.

The bad is that the number of fields and options can get confusing. However, the system is integrated with Virtual Studio as part of the IDE (even more so in VS2019), which is also very useful.

And the ugly is that the UX is kind of confusing. Best example: the commenting system works differently than any other you’ve ever seen: instead of just hitting Control + Enter to save a comment, you have to save the work item instead (good luck finding that out the first time around!). In general, it’s often not obvious what buttons you’re supposed to be pushing. Although this situation is improving, it’s still kind of archaic, primarily because it comes from TFS, which was a very old-school system.

Step 6: Customize Azure DevOps to Your Taste

Don’t get bogged down in the way Azure DevOps or Azure Boards in particular wants you to work. If having those millions of different statuses like approved, committed, resolved, verified, or succumbing to their definition of Agile or Scrum or whatever doesn’t work for you, just ask yourself what’s the simplest thing that could possibly work, and do that on top of Azure Boards. Don’t force yourself to overthink things just because the people who made Azure Boards probably over-thought some things.

Customization is easy because Azure Boards gives you full customizability over the fields. You can use that to add things but you can also use that to take away things. So, take away whatever doesn’t make sense for you. Keep only the bare minimum. That way, you can get a more Trello-style experience where you only see what matters. You really want to use it as a tool to gain visibility into what your team is doing and communicate priorities, so keep it simple and remove any cruft that isn’t relevant and is just getting in your way.

The Big Picture

The most important thing about adopting Azure DevOps is the sort of aggregate effect it has as a holistic solution. You can go the route of using certain components. But, if you choose to go the full Monty, you can find an overwhelming positive change.

This is not without issues, of course. The switch to DevOps can be tough on many levels, from changing corporate culture to investing in up-to-date software for use across the organization. But this really is a case of short-term pain for long-term gain.

The holistic approach is a winner. Once we adopted the holistic approach, shipping software to our customers became easier, more automatic, and even a good experience because there was only one place to look when things went wrong.

In any case, what’s there to lose? Whether you start with one component or the whole bunch, Azure DevOps provides immediate and noticeable benefits, across the board.