見出し画像

Microservice DevOps with Monorepo

日本語版:

Author:Yuta Shimakawa, Software Engineer at MODE

On March 9th, 2023, I participated in an event hosted by Findy called "National and International Architecture Lightning Talks for a Better Developer Experience - AWS Edition," and gave a lightning talk titled "Development and Operation of Microservice Architecture with Monorepo." In this article, I will introduce the contents of my slides in blog format.

Backend architecture of MODE

Behind the products offered by MODE, there are various services that provide diverse functionalities. For public-facing systems, there are WEB API gateway servers, MQTT servers, bulk data download servers, and others. On the other hand, for internal backends, there are many different systems with different purposes, such as time-series database services, video processing services, data stream services, and data external integration services.

Managing microservices codebase with Monorepo

The Monorepo mentioned in the theme refers to a codebase management technique using version control tools for microservices. Managing all microservices using a single source code repository is commonly referred to as a Monorepo (mono-repository). Conversely, separating each service into separate source code repositories is sometimes called a Polyrepo (poly-repository). As mentioned above, MODE's backend system manages microservices in a Monorepo using a single repository.

Advantages of Monorepo

The author believes that the following are some of the benefits of adopting Monorepo:

Better glance of services

When managing microservices with a poly-repo approach, it's possible to use external tools, documents, or naming conventions to enforce management, but with a mono-repo approach, since everything is managed in a single repository, it's relatively easy to manage what is for what purpose through file tree operation or documentation.

Easier to run multiple services locally

During local development, there are cases where multiple services are needed. Of course, depending on the scale, it may be more efficient to use dependent services in the development and sandbox environment, but there are also many situations where it is necessary to launch them locally. In such cases, the fact that all the code exists in the same repository is a great advantage.

Easier to manage common library

Also, especially when developing backend microservices in a single or few languages, library management becomes easier.

Easier to change the code in multple services and libraries

In particular, in cases where you want to make changes to multiple libraries or services for the same purpose (although such opportunities are often rare due to other issues), in the case of a Monorepo, it is possible to manage all changes in the same branch, making it easier.

Easier to set the soft/hard common rules for configurations, deployment, conventions, etc

In addition to the above-mentioned benefits, there are also benefits such as commonization and sharing of settings, deployment methods, and development rules.

Of course, these benefits are relative, and depending on the scale, there may be situations where the above-mentioned benefits cannot be utilized. However, in the current situation where MODE is developing and operating various services with a small team, I feel that we are gaining many benefits.

Disadvantages of Monorepo

On the other hand, there are also some disadvantages to adopting a Monorepo.

One is that there is no one-size-fits-all solution for CICD pipelines. It can be difficult to adopt templated workflows commonly used in various CICD tools such as Jenkins, GitHub Actions, and CircleCI. If naive methods are taken, such as building and testing all services for every pull request or deploying all services at once, the execution of the CICD pipeline will become sluggish and there will be many constraints on the release timing. Avoiding such issues is a challenge.

Another disadvantage is that, due to the nature of a Monorepo, there tends to be a larger number of people involved in a single repository. As a result, it may become difficult to maintain consistency in the source code and resolve conflicts without careful consideration.

Tips in deployment pipeline management

At MODE, we have created the following structure to efficiently execute CICD pipelines as described below.

  • Automated build and testing for PRs and branches have constraints in GitHub Actions workflows to ensure that unrelated tests do not run, preventing unnecessary build and test occurrences.

  • Deployment is primarily done by combining GitHub Actions and AWS CodePipeline as shown in the diagram below.

  • In the deployment flow, we separate GitHub Actions workflows and AWS CodePipeline for each service and environment, allowing for independent deployment for each service.

  • For merging into the master branch, we have put constraints in place in the service-specific workflows so that only deployment for the code related to the service is executed in the event of changes, preventing unnecessary service deployments.

  • For releases to staging and production environments, we use git tags to trigger the execution of the deployment workflow manually to control the timing.

Tips in Monorepo management

As measures against the increase in human and organizational scale related to Monorepo, we implement the following two approaches:

  • Keep the branch management rules of the repository as simple as possible. Also, since the risk of conflicts increases when branches remain open for a long time, we make it possible to merge to the main branch as frequently as possible. We also make implementation efforts such as the feature toggle mechanism for this purpose.

  • Although it is called a Monorepo, not all source code is stored in it. At MODE, we manage the software that runs on the edge device called gateway and the code for mobile apps in separate repositories because there are not many benefits to unifying them.

Since the severity and nature of this issue change with the change in human and organizational size and structure, there is no absolute answer, and regular review is necessary.

Conclusion

Before joining MODE, I had no personal experience with Monorepos, so I had some difficulty with the way they were managed, and I had many doubts at first. These are the disadvantages I listed.

However, after some system improvements, I have started to experience more benefits. I think that the benefits are even greater when there is a certain degree of language standardization (in our company, all backend microservices are implemented in Go).

Finally, we are always looking for engineers who are interested in the development of microservices and backend systems, including Monorepo approaches. So, if you are interested, please feel free to contact us!