Every once in a while, I come across an innovation or new offering in the tech world that makes me grin because it just seems like magic. From hardware wizardry like the HoloLens Minecraft demo in 2015 to software sorcery like the recently-released GPT-3 AI, technical magic captivates me. I recently had some time to dive into Microsoft’s Project Tye and, for reasons I’ll share below, it inspired that same sentiment of awe mixed with excitement.
While not as overtly whimsical as HoloLens or as scary powerful as GPT-3, Tye tugged at my heartstrings nonetheless. Why? Put simply, it solves several related problems that have plagued me, and probably anyone developing and deploying .NET microservices, for years. Let’s cover some common problems of modern software development, the old school solutions, and the magical new tool that is Project Tye.
Three Common Pain Points
- Co-Dependent Microservices
If you’ve been working with microservices lately, you’ve almost certainly run into this scenario: Microservice A needs to talk to Microservice B, and Microservice B needs to talk to Microservice C. You need to work on Microservices A and B. How do you make sure your local environment has access to Microservice C? How do you make sure your changes don’t impact other developers? In spite of the many benefits of microservices, including flexibility and stability, co-dependencies and complexities like this have actually led some people to denounce microservices in recent years.
- Shared Infrastructure
Let’s say you’ve got a complex project, with many developers in the mix. One of the most frustrating aspects of setting up a development environment in this scenario is ensuring you have all of the infrastructure needed. For example, each developer might need a Redis server, a database, a logging product, and a message bus. How can you get these dependencies up and running for all developers in a way that is fast, maintainable, and allows everyone to work without stepping on each other’s toes? More importantly, how can infrastructure changes be made by one developer in a way that is as transparent as possible to other members of the dev team?
Packaging and deploying applications is a whole field unto itself. Ideally, this pipeline would be shared all the way from local dev workstations to production, but usually the local dev deployment pipeline is very different from other “real” environments. How can we unify this process?
The Mundane Way
Most delivery times land on a “shared playground” approach to solving these problems. Generally, the solutions revolve around having a shared dev environment that supports most of the dependencies. Everyone connects to the same dev database instance, Redis instance, logging service, and anything else needed. When working with microservices locally, each is configured to talk to the dev environment version of any dependent downstream microservices. Local deployment is kept disconnected and removed from the rest of the build and deployment pipelines.
The approach above does work; otherwise nobody would do it. But it does come with some pain. Working with several microservices simultaneously can be a nightmare, especially as your microservice dependency chain grows.
With shared infrastructure, it is common for developers to step on each other’s data. In particular, having a shared dev database makes it almost a given that you won’t have the ability to set the database to a data known state. For example, if you have a data configuration that represents a common use case, how can you safely apply that state without stomping on other devs?
The same can be said of some of the non-functional dependencies, such as logging. When using a shared logging environment for local development, it can be challenging to parse out just the log entries that you are generating, especially if those log entries are generated by multiple systems.
As far as deployment is concerned, unless you are already down the path of containerized apps, it’s likely that you simply don’t consider the concept of deployment until after you move beyond the local dev workstation. This certainly works, but it doesn’t allow you to test your deployment pipeline as part of your local dev activities.
The Magic Way: Microsoft’s Project Tye
Ok, are you ready for the magic I promised? Tye started life as something of a side project for the Microsoft ASP.NET dev team during some downtime last year. They, like the rest of us, found themselves asking, “Why does it have to be so hard and clunky to develop microservices in .NET?” They struggled with the same dependency chain issues that the rest of us have, but they were in a unique position to do something about it. Their solution had the potential to be built into the standard Microsoft development environment.
And that’s exactly what they did! Tye is a command-line tool, though I won’t be surprised if it gets baked into the Visual Studio IDE soon. The entire purpose of Tye is to bring together all of the dependencies needed to run an application. Though it started as a method to bring microservices together, it expanded to encompass downloading and running containerized dependencies (databases, Redis, etc.). Later on, the Tye team wrapped everything together by adding the ability to containerize and deploy apps to a Kubernetes cluster.
At its core, Tye is a tool for tying together all of the dependencies in a distributed application. It includes both auto-discovery (in the case of microservices) as well as declarative dependency inclusion (as in the case of things like Redis or databases). There is a fair amount to go over, so I suggest watching this video to get a feel for how the magic works. Pay close attention to how it automatically sets itself up, and make sure you don’t gloss over the extremely useful, built-in dashboard that Tye provides.
If you’re dealing with a complex microservice ecosystem, Tye is a game changer. It allows you to abstract away various dependencies, gives each developer the freedom to do exactly what they need without worrying about setting up a million other things, and enables new developers to drop in and out of projects quickly. I encourage you to look at Tye’s robust documentation. You can get up and running with a basic sample in a matter of a few minutes. Once you get your feet wet there, it’s pretty easy to start adding it to your real code.
At Polaris, we make a point to stay on top of the latest offerings and technical magic that can help our clients meet their critical business priorities. In an upcoming post, I’ll explore Dapr, a portable, event-driven runtime that is synergistic with Tye. If you decide to try Tye, leave a comment below and let me know how it goes. More importantly, drop the Project Tye team a note because they are actively addressing community feedback and questions.