Congratulations, your company has just acquired another smaller company to expand your product line! Pop the champagne, dress up the puppies, eat so much cake that you wake up full of regret! Now that the dust has settled and you've met your new teammates, you all come to the sudden realization that...
Your out-of-date documentation? It'll be on full display to a new group of developers. That important business logic you wrote 2 years ago with the
TODO: Write some tests above it? Better scramble to get some in there! The spreadsheet that product shares around for features, well... you get the idea. And that doesn't even start to cover what the other folks have stewing in their code cauldron.
Never fear! Many have been there before you. Many are currently in the middle of their own jungle of curly braces. When I joined Terminus about a year ago, they had already acquired 3 different companies and have since purchased another 2. Your mileage may vary, but here are some ways we've worked our way through the proverbial jungle.
After a merger the product team, investors, and executives will want to see progress made towards merging the companies' product offerings. This is a good thing for the business! However, you're still going to have figure out how to talk - in just about every sense of the word.
Documentation is a four-letter word, I know. But when you start interfacing with OtherCorp's whizzbang analytics dashboard, you're going to wish they'd documented it.
If you haven't documented your services yet... you're not alone! But to make it easier for you to work on your new buddies' services (or vice versa), you'll need to have things documented. Whether it's via a wiki (we have one conveniently named
man) or through testing, you'll want to have an understood method of documentation.
When you're smashing together multiple products' codebases, you're likely going to have several different languages floating around. At Terminus, we've had/still have services written in Ruby, Groovy, Elixir, Go, Node (both JS and TS), Angular, and React. They all have their purpose and their reasons for being used, but moving forward you've gotta be able to have folks work across different repositories. People have their pet languages for sure. But people who have only ever written JS/TS are not going to want to "pick up Haskell" for that one service that Kelly wrote before leaving for AnotherCorp. (This is just an example, not trying to pick on JS/TS devs!)
As much as it pains me to say it, coming up with a common set of languages to use is going to pay dividends in the end. I've worked on projects in different areas of our platform, and because they're in languages that are common across our product suite (and sometimes documented and tested well!) I spent minimal time ramping up to contribute to those services. It doesn't feel like it while you're adjusting, but it really does make things better in the long run.
So we've identified the end goal: merging our codebases into a more cohesive platform! But where do we start? Just like with constructing a house, we need to have a good foundation to build everything on. We need... infrastructure!
You've got an AWS account... for most of your stuff. You've got that one Heroku experiment that too that we try not to mention often. And now your new coworkers are bringing all of their cloud accounts as well! I swear, if they even mention on prem hardware...
The end goal is more than likely going to be a single cloud provider account. So how do you get there? It's not going to be an easy or short-term fix. Environment variables to different services are scattered around everywhere. Identity and Access Management (IAM) roles and policies exist in more places than you realize. Let's make sense of all this.
You don't want to inadvertently put your users' data at risk especially now that you're growing as a company! If I haven't hammered it home enough yet, security will have to be something people agree on. How should we encrypt data at rest? How do we protect services that are meant for internal use from outside snooping? Whether that's configured with IAM roles/policies, cordoned off in different VPCs/VPNs, use of some sort of protocol or token-based security (JWTs for example), work together to figure out the best (possibly not the easiest) way to keep data secure with minimal impact to performance.
In the beginning, you and/or your founders were probably tinkering around with the cloud, learning new concepts, and breaking all the things. This is perfectly normal in the startup world, but eventually it gets to be unwieldy.
Now that you're joining forces with others, you'll want to keep track of things in a more programmatic way. Using an Infrastructure as Code tool such as Terraform is a great way to express platform configuration in an understandable fashion. You can import existing infrastructure into Terraform for configuration management, and when you want to modify your architecture you can see what will change before you pull the metaphorical trigger. And with IaC, you can version control all of your infrastructure changes in Git just like application code!
Everyone monitors differently. Papertrail, New Relic, Datadog, Kibana, a shell into k8s pods... I've seen LOTS of ways that people monitor things, but y'all are going to have to figure out a unified way to keep an eye on services. If there's one thing I've learned, it's that people do not want to check more tools than they have to. Settling on one monitoring platform (if possible) will take effort, but in the end it'll make everyone's life easier.
CI/CD pipelines are another thing that people can be strongly opinionated about. I'll just echo here what I'd said about monitoring - there's a lot of ways to do the things. Bring everyone together to work out a common solution that everyone hates the least. Keeping stuff the same across the now singular organization will help folks move around as needed to different projects more easily.
So what's the big takeaway here? You're going to need common practices, common definitions, and common languages. It will take time to do it, but do as much of it up front as you can. Product will still want to ship new features and that's fine; you can do that while integrating everything together.
Our CEO has said this multiple times in regards to business strategy, but it applies to engineering as well: "Sometimes you have to slow down to speed up." When you take the time to blend together up front (or at least start executing a plan to unify processes 'n' such), it's going to help you to execute more quickly in the future.
I hope you enjoyed this! If you have experience with uniting codebases post-M&A, I'm happy to hear your comments below!