As consultants, we get opportunities to work with a variety of clients in different industries. We’re often advising and helping with new ideas and technology and it’s critical that we are up to date and aware of industry trends.
We’ll often trial new ideas and technologies on internal projects before fully recommending them to clients. This post is an effort to share some of the trends that I’m seeing and some of the ideas that I find interesting or believe can be used by teams to build better software.
In 2015, it got a lot harder to ignore the cloud. It seems like every major tech company is either providing their own cloud infrastructure or using the cloud heavily in their solutions. These tech giants have a huge influence on where we are headed as an industry. Startups have been quick to embrace the potential of the cloud, utilizing IaaS and PaaS, touting benefits such as the ability to focus more on the product in the critical early stages.
Many enterprises are a bit hesitant to jump in and fully commit to cloud infrastructure, but still see the benefits of hybrid cloud solutions, combining the cloud with on-premise infrastructure, utilizing the cloud for certain types of projects, or provisioning infrastructure on-demand when needed.
We’ve recently delivered a number of solutions on Azure and, while there is definitely a learning curve and a few gotchas that you become wiser to with experience, as a developer I appreciate the continual improvement of the services offered and the simplicity of provisioning new environments and ease of scaling that the cloud allows.
Even if the cloud isn’t on your horizon currently, it’s essential to invest in learning how to plan and build for the cloud as demand for these skills are going to increase significantly over the next several years.
The way that we build software is constantly in flux. As new ideas and tools are shared with the community, we try to build our software to be more efficient and more maintainable than was possible before. Currently, a lot of the dialog about software architecture is being heavily influenced by movement toward the cloud.
Microservices and Monoliths
One of the most discussed (debated?) architectures right now is the idea of microservices. Instead of looking at an application as monolithic, where typically all features reside alongside each other in the same components, we can build an application as a suite of focused, distinct, re-usable services that we can combine to compose the system. With recent preference toward lightweight communication like HTTP RESTful services over previous technologies like SOAP and the trend toward better build and deployment tools and practices, this approach can be used to build more maintainable systems.
Although this approach works great for many teams, just because it’s trending doesn’t mean that it is appropriate for everyone. Care must be taken to determine if it is the best direction for your team. What works in one context, may not be the best choice in another. Solid build and deployment automation is essential for success when an application is composed of many pieces. For many teams and types of software being built, a monolithic approach might truly be the best option.
You say monolith, I say integrated. Potato, potatoe.
— DHH (@dhh) February 20, 2015
A Few Good Ideas
We all want our teams to be effective and our capability to deliver amazing software to continue to improve. There’s no end of community discussion on how we can improve. Here are a few ideas that I’ve come across that stand out:
Products over projects – When we think of building software for a business, we often think of it in terms of a project. We’ll have a start and end date for development work and after the solution is deployed, the system will stay stable for a while and the team will go on to work on other projects. The development team is rarely involved with ongoing support and maintenance of the application. When we think of a product, however, we think of something that is continually maintained and improved with feedback from users – the team is stable and is invested in the evolution and maintenance of the application.
When teams are able to think of their software as a product they are responsible for, they are motivated to invest in building the application to ensure that issues can be quickly detected and resolved. When a system is being evolved alongside real-world users, we can better take advantage of techniques like A/B testing and using genuine user feedback to drive frequent releases to improve the software.
Committing to our software longer-term enables us to not only ensure that it can keep pace with business changes and competition, but also increases team ownership, resulting in higher quality and continuously improved systems that are not possible with the project mindset.
When we really care about the software we are releasing, we can also look to define what “done” should really mean. Take a feature or change as an example. Does done mean that we’ve got some code ready for release and it passed some tests? Or should done mean that our feature has been tweaked and perfected until it has achieved the desired impact for our users?
Focus on Making Releasing Easy
There’s just no excuse for releases that involve a bunch of manual steps in 2015. Anything that is manual is likely both slow and error prone. Releasing to production should be no more than a single click. If you’re scared to make changes and releases are stressful, then you likely won’t be frequently releasing and continually improving your software.
There are a number of options for build and deployment automation, depending on the technology stack that you’re using, but for the deployment automation of our .NET projects we’ve had great success using Octopus Deploy both for applications hosted on-premise as well as those deployed to the cloud. Tools like Octopus do a great job of managing the deployment process and make it easy for you to see at a glance exactly which version of each component is currently deployed to each of your environments.
When releasing is easy, you can more quickly react to issues and keep your users impressed with your responsiveness and commitment to making them happy.
Mean Time to Recovery
When we think about the reliability of our software, we tend to describe it in terms of uptime. We naturally think that the best way to ensure uptime is to make sure that our application just never goes down. While it is essential that the software we build is stable and fault-tolerant, we cannot realistically expect that the system will never go down. Imagine the worst situation, possibly even a dependency that is out of your control.
Focus on improving mean time to recovery. It is important to also focus on being able to recover from a failure as quickly as possible. How long would it take your team to restore an application, or worse, rebuild an entire environment to get the system going again?
There are multiple aspects to improving MTTR, including:
- improving detection time
- improving notification time
- reducing diagnosis and repair time
Focusing on these areas to improve your team’s ability to recover will most certainly pay off in increasing uptime and keeping your users happy.
Tools for Productive Teams
Slack for Communication
We’ve been using slack on some of our projects and I’ve seen it result in a positive impact on team communication by making continuous discussion easier. It helps ensure everyone is kept in the loop when hallway discussions or email conversations are moved to slack. More engaged teams result in better decisions and integrating with other services gives us notifications for build, deployment, and production issues right in the channel.
When you think about your software as a product instead of a project, you really start to care about having insight into what’s going on when the system is running. There is an abundance of tools available that teams can use to vastly improve logging and issue notifications for live systems and get deep insight into the performance of the system as users are active. We’ve used New Relic, Microsoft’s Application Insights, and recently had success using Raygun’s error reporting.
There are many services that provide slightly different features and slightly different takes on logging so you’ll need to evaluate and choose something that’s appropriate for your team. The important thing, though, is that you do have insight into what’s happening in your live system in order to be able to react quickly to issues and keep your system running smoothly and continuing to improve.
I think that dashboards are currently underused and many teams may just not be aware of their benefits. There are tools like Dashing that can be used to create live dashboards fairly easily and run them on an office screen. Dashboards have the potential to keep teams united and motivated around specific goals or quickly alert them to issues.
You could create a dashboard with any number of metrics, for example:
- system or server status – stable, time since last failure, duration of last issue
- system performance – number of users in the system, average response time, number of actions processed
- build and deployment alerts
- social media – recent tweets, Facebook likes, etc. related to your product or company
One Last Thing…
There were a couple of really great videos from Spotify on how their teams work together to create software here and here that I just discovered this year and that had an impact on some of the things that I was thinking about. If you haven’t seen them yet, check them out.