Spring Boot Kamatera Terraform

Spring Boot Kamatera Terraform

Deploy a Spring Boot Image to a Kamatera server in about 5 minutes using Terraform

·

5 min read

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

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

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

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

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

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 via curl
  • 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

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

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

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.