Recently, during the Spring Office Hours, we have been discussing Spring to Production
as a topic.
There are so many ways to get Spring Boot application to production.
If your Spring Boot application is delivered as a container, all you really need is a Docker or Kubernetes dial tone.
In this post, I’m starting from nothing, and delivering a Spring Boot application to Kamatera. I’ve never used Kamatera before this, so I’m going document the entire process, and experience, for you.
Getting an account Link to heading
Kamatera provides a 30-Day Free Trial
which sounds wonderful!
After validating my email address, I was required to add a billing profile.
This makes sense.
However, before signing up for the free trial, I did verify that there was a Terraform provider for Kamatera.
While I was adding my billing profile, I saw more details of the 30-Day free trial.
30 days Free Usage:
1 Cloud Server (of up to 100 USD)
1000 GB Cloud Block Storage
1000 GB Outgoing Internet Traffic
This is plenty to work with, so I continued to proceed. The only option I had was to use a credit card. The process was pretty painless and only took a couple of minutes.
The UI is easy to understand and navigate. I just don’t want to use the UI. I want to automate all the things. Now that my account is set up, I want to set up my infrastructure as code.
Kamatera Terraform Provider Link to heading
A quick glance at the Terraform Provider for Kamatera usage guide and I see that I need:
KAMATERA_API_CLIENT_ID
KAMATERA_API_SECRET
In the Kamatera console I easily found where I needed to go to add keys.
I clicked the + Create New Key
button. A description
box is presented.
I put Spring Boot to Production with Kamatera
in the description and clicked Create Key
to move forward.
At that point, I am provided with my Client ID
and API Secret
which I then copy to a safe place.
The Terraform Provider for Kamatera usage guide also provided an example Terraform file.
I copied that and separated their main.tf
into different files, that makes things easier for me to understand later.
I started a github repository to capture my changes.
At this point, I determined that I couldn’t configure Docker as an option via Terraform using one of their images. They have a tool that generates Terraform files, but the image ID never worked for me. I didn’t spend much time investigating, probably user error.
That is ok, because I can use an executable JAR and deploy that as a service. Or I can just install Docker as part of the startup scripts.
I chose to use Ubuntu
and their 22.04 64bit_optimized
image.
Docker Link to heading
I attempted to install Docker using the startup_script
value of the kamatera_server
but I struggled with getting that to work consistently.
The problem appeared to be timing.
I’m still unsure about when the startup script gets executed.
I needed to wait for the network, then wait for DNS, and sometimes it would just fail.
I couldn’t figure out a way to access the logs during the build process either.
At one point, a server appeared to have been built and completed successfully, but the startup script was stuck in a loop, waiting for something.
I couldn’t access the server though, and my Terraform was stuck, for 15+ minutes.
Interesting Side Note Regarding The Stuck Server Link to heading
I opened a ticket, asking for the server to be destroyed, for two reasons.
When I cancelled the stuck Terraform apply
my local state didn’t show the server, so I couldn’t Terraform destroy
it.
In the Kamatera console, the task was showing completed, but the server didn’t show up in my server list, so I couldn’t delete it from there either.
The response was quick, less than 30 minutes, but confusing.
Unfortunately, we do not provide support for Terraform.
The Terraform Provider that I’m using, appears to be created by Kamatera
and shows up in the Terraform Registry.
Therefore, I can only assume that the 30-day support is not going to troubleshoot Terraform related issues.
I later realized that every server creation and destroy sends out an email receipt. I did not get a receipt for the server creation, so maybe, hopefully, their system cleaned it up properly, automatically.
Docker via remote-exec Link to heading
I don’t recommend this approach.
Nobody recommends this approach.
The Terraform documentation states Use provisioners as a last resort.
It’s marked Important
and highlighted at the top of the page.
Well, it is my last resort. The purpose of this exercise was to show that getting Spring to production is doable, and Spring Boot makes it really easy. Different providers are going to have different pain points, but also, different strengths.
At this point, I use the remote-exec
provisioner to do a few things:
- Download the
Docker
install script viacurl
- Execute the install script
- Pull down the image
- Run the image on
Docker
Using remote-exec
required setting up a connection
to the host.
For this example, I chose to use a public/private key pair for access.
Execute Link to heading
In order to take this for a spin yourself:
#clone the repository
git clone https://github.com/dashaun/spring-to-production-kamatera
cd spring-to-production-kamatera
# configure Terraform with your credentials
export KAMATERA_API_CLIENT=...
export KAMATERA_API_SECRET=...
export TF_VAR_ssh_public_key="$(cat ~/.ssh/id_rsa.pub)"
export TF_VAR_ssh_private_key="$(cat ~/.ssh/id_rsa)"
# Initialize Terraform to pull down the provider
terraform init
# Validate your credentials config by using the plan
terraform plan
# Apply the Terraform, ETC < 5min
terraform apply -auto-approve
# Access the Spring Boot application using the newly created server
curl $(terraform output -raw public_ips):8080/actuator/health | jq .
When you are done, clean up behind yourself:
# Destroy the Terraform, ETC < 1min
terraform destroy -auto-approve
Summary Link to heading
While exploring multi-cloud architectures, I really wanted to get outside my comfort zone.
Things like Terraform
and Spring Boot
make getting applications up and available really simple.
I am going to continue to explore and experiment with other cloud providers.
Soon, I will deploy a reference architecture, with different Spring Boot services, each deployed to different cloud providers.
My theory is that you don’t have to be a certified Azure|GCP|AWS cloud architect to be productive with Spring Boot.
Feedback Link to heading
I did not harden this deployment, and I wouldn’t call it production ready. If you would like to see me expand and harden this example, please let me know, via the GitHub repository.