The specifics of PaaS deployment for JHipster
We see a lot of people trying to deploy JHipster applications on Clever Cloud. It does not seem to be fully understood all the time. Especially with the differences between deploying on IaaS and PaaS. And since JHipsterConf is around the corner, it's the perfect time to write about it, to explain a bit what it is and how it can be deployed on PaaS platform like Clever Cloud.
What is JHipster?
If you are not familiar with JHipster, it's a scaffolding system to bootstrap applications using Spring Boot and AngularJS or React. You can choose to scaffold a monolithic application (Which are great and modular and everything because Spring Boot lets you build modular monolith. If you have no idea what you are doing you should start with this) or microservices architecture with an API Gateways and a registry.
When scaffolding microservices, you are using the Spring Boot and Netflix OSS stack. That’s something you want to know in general when looking for documentation online. Most of the things you will read here apply both to JHipster and to Spring Boot + Netflix OSS deployments.
JHipster or NetflixOSS versus IaaS or PaaS
Is there an incompatibility between JHipster/Netflix OSS and PaaS deployment? The reason I am raising this question is that this stack was pretty much made for IaaS deployment, more particularly AWS, where fewer things are managed than on any PaaS platform.
And as such JHipster comes up with lots of nifty tools to compensate the absence of services usually provided by higher level solutions like CaaS or PaaS. This is especially true when you are deploying a microservices architecture. So, will this overlap when deploying on Clever Cloud? Are things even compatible? Yes, it is, and in this post, I will show you some exciting things you can do.
Reverse proxy and Service Registry
One of the central question raised by our users doing microservices is how do you configure the JHipster Registry (Eureka in Netflix OSS terms). It maintains a registry of all the instances of your architecture services.
Going back to a classic AWS deployment, the typical behavior when you manage several instances of the same application is to deploy those apps to VMs. They all have their own set of IP/port. In their configuration, they have the different addresses of their Eureka server. They will register to that server as an instance of a particular application, identified by that IP/port couple. It is great when you manage your private network and plan to expose everything through an API gateway or your reverse proxy.
But as it turns out, this is already managed by PaaS providers like Clever Cloud or Heroku. So you don't have access to that IP/port for each instance. But it's OK. Eureka can be configured to support setup like these. You can use the URL given by the proxy instead.
The only issue with that is that you won’t be able to go on one specific instance since you go through the proxy. In some cases, this can become a problem. Like with the JHipster Registry.
JHipster Registry’s Statefulness Exception
Let’s say you want to scale out your registry for failover. It seems like a legitimate thing to do. If you only have one JHipster registry instance and it’s down, you lose your service registry(Eureka) and your configuration server (Spring Cloud config, embedded in the JHipster registry, more on that later). It means your architecture is down. So you want to have several instances of the registry in case one goes down.
Something also worth to know is that the service registry(Eureka in Netflix OSS terms) stores things in memory. You cannot store the information in a shared database that all your instances could use. It makes the registry stateful. They all have their datastore(their RAM). So you need to have your services register themselves to each registry instance to make sure they always have the same copy of the data.
If you were to use the URL of your JHipster registry application given by a PaaS, so behind a reverse proxy, the service would register to a random. It depends on the PaaS load balancer. In that case, you have no guarantee that your service will have registered itself with every instance of the registry.
If you use an IaaS, you will have all the IP/PORT couples at your disposal to make sure each service can register to each registry.
If you use PaaS autoscaling, each instance is hidden behind a reverse proxy with only one URL, and you have no way to have the clients register themselves to each instance (Now you could use sticky sessions, but you would have to craft the sticky session cookie manually, and this is cumbersome). So it is much simpler to create one application with its URL instead.
In that case, what you need to do is deploy an application for each instance you would like. That way you get a different URL for each, and you ask all your services to register to each URL.
Another feature that comes up with most Platform as a Service and overlap with JHipster or the Netflix OSS stack is configuration management. In JHipster case, the registry is also a Spring Cloud Config server. As such it supports different backends to store your configuration: Git, native filesystem, Databases or Vault. By default JHipster uses git. Using GitHub, in particular, is excellent as you can benefit from their WebHooks. Each time you change the configuration, your server will receive the updates and broadcast it through an AMQP system with Spring Cloud Bus if you have configured one. So, you are sure that all your architecture is up to date with the latest configuration.
And of course, Spring Cloud Config also supports environment variables which is what we offer by default with Clever Cloud, with some exciting orchestration tricks.
The PaaS granularity level being Application(as oppose to VMs in IaaS), you can assign environment variables to Applications. All these variables are injected into all the instances of the app when we boot the VM. Applications can also expose some variables for others. How does it work?
Applications or add-ons can be linked together. It merely means that their exposed variables will be injected into the linked app. And the great thing about this is that when an exposed variable is modified, all the linked apps are restarted in blue/green so without service interruption. So you get an up to date architecture without having to setup Webhooks and an AMQP with Spring Cloud Bus 🙂 Note that Clever Cloud also offers a configuration provider addon that lets you define configuration without having to tied it to an app. It is a bit like a configuration server. And it works exactly like described above. It's mostly here to make a semantic distinction.
JHipster and the Netflix OSS do provide some overlap to what PaaS can offer. But fear not because it’s still compatible and can benefit from the high-level feature supplied by PaaS. In the next post, I will show you all the steps to deploy this on Clever Cloud 🙂