Spring Boot Kamatera Terraform
Published: 2022-10-24 21:35:35

---
title: Spring Boot Kamatera Terraform
published: true
date: 2022-10-24 16:19:03 UTC
tags: 
canonical_url: https://dashaun.com/posts/spring-boot-kamatera-terraform/
cover_image: https://dashaun.com/posts/spring-boot-kamatera-terraform/devto.png
---

Recently, during the [Spring Office Hours](https://bit.ly/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](https://kamatera.com). I’ve never used Kamatera before this, so I’m going document the entire process, and experience, for you.

## Getting an account 

[Kamatera](https://kamatera.com) 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](https://registry.terraform.io/providers/Kamatera/kamatera/latest/docs).

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](https://github.com/Kamatera/terraform-provider-kamatera/blob/master/README.md#usage-guide)and I see that I need:

```
KAMATERA_API_CLIENT_ID
KAMATERA_API_SECRET

```

In the [Kamatera console](https://console.kamatera.com) I easily found where I needed to go [to add keys](https://console.kamatera.com/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](https://github.com/Kamatera/terraform-provider-kamatera/blob/master/README.md#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](https://github.com/dashaun/spring-boot-kamatera-terraform) 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](https://github.com/Kamatera/terraform-provider-kamatera) that I’m using, appears to be created by `Kamatera` and shows up in the [Terraform Registry](https://registry.terraform.io/providers/Kamatera/kamatera/latest). 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.](https://developer.hashicorp.com/terraform/language/resources/provisioners/remote-exec)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](https://hub.docker.com/r/dashaun/spring-boot-native-pi-default)
- Run the [image](https://hub.docker.com/r/dashaun/spring-boot-native-pi-default) 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-boot-kamatera-terraform
cd spring-boot-kamatera-terraform
# 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](https://github.com/dashaun/spring-boot-kamatera-terraform).