EKS complete with eksctl / Sprint 3

Marc Enschede
7 min readAug 19, 2022

In this sprint we are going GitOps!

Since sprint 2 we are able to deploy a spring boot app to an EKS cluster and publish it to the world. Unfortunately it is all scripted using unix shells. That is not what we want. So in this sprint we are going to start GitOps.

In this article we are going to use 4 repo’s on GitHub; the parent repo that will contain the EKS scripts and a sub repo that will contain the Spring Boot app.

git clone https://github.com/enschede/eks-demo.git
git checkout tag/sprint3
git submodule update

You can clone it and, please, check out tag “sprint3”.

Sprint 3

The goal of this sprint is to introduce GitOps. And we are going GitOps with FluxCD.

I’m not going into the reasons why GitOps and declarative descriptors are better than maintaining shell scripts, there are enough discussions on that subject to be found on the Internet. My focus is on implementing GitOps.

In this sprint we will introduce FluxCD and start the load balancer controller and the app from FluxCD.

As a bonus I added a short script to start the the Kubernetes dashboard from FluxCD as well, just as a showcase to show how simple starting an application from FluxCD can be.

For those of you who want to know more about FluxCD, there is a marvelous track of video’s created by Geert Baeke on this subject and on Kustomize. Please check Youtube.

Overview

Introducing FluxCD comes with 2 new repo’s; the infra repo and the load balancer controller repo.

The infra repo (blue) is loaded from the eks-demo.yaml in eksctl (red).

The load balancer controller (green) and app (purple) repo’s are referenced from the infra repo (blue).

Creating a FluxCD infra (blue) repo

To use FluxCD, it is necessary to create a FluxCD repo. This repo defines the infrastructure of FluxCD. Before creating the infra repo, we need to define 2 shell variables that contain the username and token that we will use for FluxCD.

export GITHUB_TOKEN=...
export GITHUB_USER=...

Now it is time to install FluxCD on your computer. On a Mac you can use brew install fluxctl to install flux.

The following command will create a FluxCD infra repo on GitHub

flux bootstrap github \
--owner=$GITHUB_USER \
--repository=eks-demo-infra \
--branch=main \
--path=app-cluster \
--personal

I personally added the infra repo to main project with the following command. (It up to you to organise your code on your computer the way you want it, of course)

git submodule add https://github.com/enschede/eks-demo-infra.git

Important, please keep the variables and fluxctl on your computer. In the next steps we will see that eksctl has some FluxCD options. The truth is that eksctl just forks fluxctl as an underwater process, so are gonna need fluxctl in the future.

More information on FluxCD can be found on https://fluxcd.io

Use FluxCD from eks-demo.yaml (red)

The next step is to use the infra repo from eksctl. We can do that by just adding a gitops branch to our eks-demo.yaml file:

As mentioned before, eksctl just spawns fluxctl as a subprocess to activate to activate FluxCD, so the github variables need to be there.

Just (re)start your cluster using the following start.sh

Or add FluxCD to an already running cluster using

eksctl enable flux -f eks-demo.yaml

When everything is done we can see FluxCD running using k9s

Running the loadbalancer controller (green)

Now that FluxCD is running, it is time to install de load balancer controller from FluxCD.

To do so, we can create a load balancer controller repo. Giving it an own repo may be a little bit overdone, but I like to give a seperate repo the as app or controller.

The load balancer controller repo has the following content

eks-demo-load-balancer-controller % tree
.
`-- deployment
|-- helm.yaml
`-- kustomization.yaml

With the following files

deployment/kustomization.yaml

deployment/helm.yaml

It tells that:

  • there is a source in a HelmRepository on the given url
  • and there is a helm chart from the given HelmRepository. It is using the aws-load-balancer-controller service account that we defined in sprint 2.

Now back to our infra repo. FluxCD needs to know about the existents of the load balancer controller. To do so we have to create a load-balancer-controller folder in the infra repo, like this

eks-demo-infra % tree
.
`-- app-cluster
|-- flux-system
| |-- gotk-components.yaml
| |-- gotk-sync.yaml
| `-- kustomization.yaml
`-- load-balancer-controller
|-- kustomization.yaml
`-- load-balancer-controller.yaml

app-cluster/load-balancer-controller/kustomization.yaml (blue repo)

app-cluster/load-balancer-controller/load-balancer-controller.yaml (blue repo)

The kustomization.yaml and the load-balancer-controller.yaml are telling FluxCD about a the load balancer repo and how to load it.

After committing it all the repo’s FluxCD load the kustomization in the infra repo and learns about the load balancer repo. Once it is loaded, the HelmRepository and HelmRelease are loaded and activated, resulting in the load balancer controllers being loaded.

This all can be seen in k9s:

Well, now that we arrived here we do have the load balancer controller running, same as in Sprint 2. Except that it is started from FluxCD and not from a shell script!

Finally, I added the green repo as a submodule of my main project using the following command. You can do something likewise.

git submodule add \
https://github.com/enschede/eks-demo-load-balancer-controller.git

Running the app (purple)

Ok, now that we have the load balancer controller running in FluxCD, it is time to add the app too. To do so, we need to create a kustomization file in the deployment directory of the app. For maintainability I merged the three descriptor files in one; spring-boot-app.yaml.

The deployment directory is like this

eks-demo-app % tree
.
|-- deployment
| |-- kustomization.yaml
| `-- spring-boot-app.yaml
...

deployment/kustomization.yaml (purple repo)

The kustomization file simply calls the other yaml file

deployment/spring-boot-app.yaml (purple repo)

The spring-boot-app file contains the deployment, service and ingress descriptors.

And of course the app should be defined in the FlusCD infra repo. The structure will be like this

eks-demo-infra % tree
.
`-- app-cluster
|-- eks-demo-app
| `-- eks-demo-app.yaml
|-- flux-system
| |-- gotk-components.yaml
| |-- gotk-sync.yaml
| `-- kustomization.yaml
`-- load-balancer-controller
|-- kustomization.yaml
`-- load-balancer-controller.yaml

And the descriptor file will be like this

eks-demo-app/eks-demo-app.yaml (blue repo)

This descriptor refers to the eks-demo-app.git and looks for a file called kustomization.yaml in the /deployment directory.

Now, after committing all changes:

  • The kustomization file in the infra repo points to the kustomization file in the app repo.
  • The kustomization file in the app repo refers to the descriptor file in the app repo.
  • And the descriptor file will work like before

Now, if we are looking in k9s we will see the eks-demo-app container spinning up after a few minutes.

Like in sprint 2, we have to find the DNS name of the load balancer to access the app from the browser.

Retro

Well, time for the retro.

Plus; we introduced GitOps using FluxCD. Starting and stopping is a repetitive task now and it allows us to grow.

Minus; still not a fixed DNS-name for the app.

So, in the next sprint it is time to fix the DNS-name problem. And we going to introduce a configurable item in the Kubernetes scripts, configurable from FluxCD.

Extra; adding the K8S dashboard

I promised to add the Kubernetes dashboard to FluxCD, just to show how simple it is to enable an extra app.

To define the dashboard app on the cluster we are going to add a new set of files in a directory called dashboard. Like this:

eks-demo-infra % tree
.
`-- app-cluster
|-- dashboard
| |-- clusterrolebinding.yaml
| |-- dashboardrelease.yaml
| |-- dashboardrepo.yaml
| |-- kustomization.yaml
| |-- namespace.yaml
| `-- serviceaccount.yaml
|-- eks-demo-app
| `-- eks-demo-app.yaml
|-- flux-system
| |-- gotk-components.yaml
| |-- gotk-sync.yaml
| `-- kustomization.yaml
`-- load-balancer-controller
|-- kustomization.yaml
`-- load-balancer-controller.yaml

app-cluster/dashboard/namespace.yaml

app-cluster/dashboard/serviceaccount.yaml

app-cluster/dashboard/clusterrolebinding.yaml

app-cluster/dashboard/dashboardrepo.yaml

app-cluster/dashboard/dashboardrelease.yaml

app-cluster/dashboard/kustomization.yaml

After committing the dashboard app will be loaded as a new customization. This is probably not the best configuration, so please let me know if there is a better solution!

In k9s the dashboard app can be shown:

Happy developing and till sprint 4!

--

--

Marc Enschede

Java, Spring Boot and Kotlin developer. The backend guy!