-
Notifications
You must be signed in to change notification settings - Fork 1
VSS Vision
I've spent the last few weeks pondering what problem should the VSS solve and to what developer pains it should be an answer for. The initial plan for VSS left a lot of space for interpretation: it describes VSS as a stack, a set of libraries that go well together and are a good match to solve a common set of problems. While this is a valid idea and it addresses a real concern which is: "What to use now that akka+akka-*+alpakka are behind a paywall?" it is not an answer that allows us to differentiate ourselves from the competition in the long run. For instance, there are templates for Typelevel stack that allow developers to quickly start with something. Typesafe/Lightbend also had a huge library of project templates that didn't take off. ZIO ecosystem also has some project templates (and even a base for an interactive project scaffolder). SoftwareMill's bootzooka is also quite known (given the number of stars on GH) but it is not a go-to solution, not a "let's use Spring", not a differentiated offering that people want to use. So what could be? What VSS should be designed to evolve into that would set us apart from all the other templates/scaffolders that are already available and not often used?
My answer would be: let's build something that really helps to build bulletproof production-grade scala apps. We have the know-how - we build apps like that. What constitutes a bulletproof, maintainable and production-grade app? All the greenfield stuff that has to be correctly set up, the best practices that have to be ingrained and enforced, and the things that hurt if done as an afterthought like security and proper management.
Let me give you a small demo of what I envision as a CLI tool, one that I would be happy to use:
$ vss new $project
Creating a new project in directory ./$project!
Where would you want to host this project?
[X] Github
[ ] Gitlab
[ ] Custom git repo
Provide github repository url (make sure you have push rights!):
https://github.com/VirtusLab/nice-project
Select application stack [typelevel, zio, akka]: t
Using typelevel stack
Choose infrastructure platform to deploy your application to:
[ ] AWS
[X] GCP
[ ] Azure
[ ] ...
Select observability provider:
[X] GCP monitoring (default for this platform) [ ] Dynatrace
[ ] Datadog [ ] New Relic
[ ] Splunk [ ] ...
What should the first app / service in the project called? $app
Select all necessary components and integrations that you would like to use in $app:
[*] http (TAPIR+http4s) [*] Cloud SQL for Postgres (doobie)
[ ] gRPC (fs2-grpc) [*] GCP Pub/Sub (fs2-google-pubsub)
[ ] Kafka (fs2-kafka) [ ] ...
How many replicas should the app have initially? (3): 1
Should $app be autoscaled? (y/N): y
What metric should be used for autoscaling?
[*] CPU
[*] Memory
[ ] Average latency
[ ] P99 latency
Add another app? (y/N): y
What should the second app / service in the project called? $svc
...
Generating walking skeleton...
Done! Enter the ./$project directory and run vss deploy dev to deploy your app to the dev environment.
This VSS is a tool that is different. That does more. That helps more. The first step, vss new $name
, is something common and known for ages (decades in IT). It's a simple interactive scaffolding step that sets up a folder with 1-n apps using chosen technologies and additional plugins. What is quite different is that it goes beyond just application code, it ties infrastructure code (for now we can leverage pulumi-ts, besom will make it all-scala in the future) with application code and sets up things that were almost always skipped in scaffolders - infrastructure for the deployment, observability setup, deployment itself and autoscaling. The next different thing is the vss deploy dev
step which ties all of the project building and deployment stuff together and does the whole rollout of the walking skeleton in one go. This should be a metric that we should strive for - a way to set up a prod-grade walking skeleton of a project with 1-n services in 2 commands.
Our solution, by necessity, has to be opinionated and it has to enforce what we see as good practices. Therefore I suggest that we enable enforcement of quality controls by default such as:
- autoformatting and scala code style (scalafmt, scalafix)
- testing and coverage measurement
- proper management of compiler quality flags (
-Xfatal-warnings
and friends) in CI vs developer environment (more permissible) …
We can take it even further - assuming we use TAPIR for http or scalapb for gRPC we can introduce more interesting options like automatic (based on OpenAPI / AsyncAPI docs) load test generation and management using Gatling. Alternatively, a simple way to run JMH benchmarks just by enabling them.
We should also set up the CI/CD for the project, provided we have plugins for that (this area tends to be more custom in many projects but on generic cloud setups it's usually either Github + Actions or whatever the cloud provides). Whether additional CD tools like ArgoCD should be also included remains to be discussed. What should not be debatable is the setup of monitoring for all of the projects - we should cover logging, spans, tracing and JVM metrics out of the box. This might prove to be difficult given the diversity of tracing ecosystems (and related lack of supported integrations in scala ecosystems) but is a goal worth pursuing - a project that starts with a proper setup of logging and cross-service tracing is massively easier to work with.
Configuration management can be done in multiple ways for different project needs. An immutable infrastructure approach (without dynamic configuration) can be easily executed by using pulumi configuration (it's kept in the source code with secrets safely encrypted) and if the dynamic configuration is required an additional component based on ZooKeeper / etcd / Consul / Vault / cloud-based tool can be deployed along with integration to services that need it.
I see vss
command (or however we decide to call it) as more than a scaffolder though. I think that we should turn it into a central codebase/project (in terms of running services and not tickets on jira boards) management tool that is helpful on more than the initial steps of the project. For instance, it would be awesome if vss
was able to add more services to the project (another scaffolding job) but also generate integration code based on existing code (ie.: based on TAPIR definitions or proto files). It could also provide information about the project (from pulumi configuration lookup, from pulumi state / cloud provider information / kubectl lookup). It would be good if it was capable of adding new features to existing codebases (hard! it shouldn't break anything that the user has already built). Maybe an LLM integration would also be an option?
Either way, VSS should, in my opinion, become a way to set up and manage production-ready complex enterprise systems that behave correctly from the get-go.