EKS on speed
Welcome
Let's build some stuff. Today on AWS(EKS). Today with popular solutions and almost without coding(in YAML). Today focus on speed and simplicity. Additionally no CI/CD.
Components
I will keep it simple.
Building infrastructure
Setup
First steps. I need to build some infrastructure. As almost everyone use Terraform for building and managing resources I decided to use it too. Based on Terrafrom EKS module I've created a sample manifest. Also, I decided to add ECR and configure output in a specific way.
1# I'd like to have control plane endpoint
2output "cluster_endpoint" {
3 description = "Endpoint for EKS control plane."
4 value = module.eks.cluster_endpoint
5}
6
7# get kubectl config based on cluster_name
8output "cluster_name" {
9 description = "Name of created cluster"
10 value = local.cluster_name
11}
12
13# upload to ECR with dynamic name
14output "ecr_url" {
15 description = "URL of ECR registry"
16 value = aws_ecr_repository.ecr.repository_url
17}
18
19# also region could be dynamic
20output "region" {
21 description = "AWS region."
22 value = var.region
23}
Variables.tf
and main.tf
weren't very interesting, so it will be pushed to the repo.
Commands flow
1# get modules
2terraform init
3
4# take a look at plan, if it's correct go-ahead
5terraform plan | less
6
7# this step will take some time to finish. (9:33.03 total)
8# if correct enter yes or terraform apply -auto-approve
9terraform apply
Kubectl and ECR
Is anybody there?
After successful cluster creation, we could want to check if the cluster is running. First I need to update my kubeconfig for the purpose of cluster authentication. For this event, I will AWS CLI and kubectl.
1# variables are based on Terraform outputs
2aws eks update-kubeconfig \
3 --region $(terraform output -raw region) \
4 --name $(terraform output -raw cluster_name)
1kubectl get pod
Docker login
Now I need to login into ECR and push some images.
1aws ecr get-login-password \
2 --region $(terraform output -raw region) \
3 | docker login --username AWS \
4 --password-stdin $(terraform output -raw ecr_url | cut -d'/' -f1)
Then I can push an awesome Nginx image to ECR.
1docker tag nginx:latest $(terraform output -raw ecr_url):1.0.0
2docker push $(terraform output -raw ecr_url):1.0.0
Helming
After all this preparation we can finally deploy an app. For this process I decided to use helm. It's a standard, very popular, and flexible solution. Again Helm Chart is attached to the repository. There is no hack or magic - just boring templates.
Command flow
1# dry run
2helm template <app name> -f <file with values> --dry-run <chart name>
3# for example
4# helm template example-app -f example-app.yaml --dry-run ./example-app
5
6# install chart
7helm install <app name> -f <file with values> --namespace <namespace> <chart name>
8# for example
9# helm install example-app -f example-app.yaml --namespace example ./example-app
10
11# upgrade app
12helm upgrade <app name> <chart> --set.image=<tag>
13# for example
14# helm upgrade example-app ./example-app --set=image.tag=2.0.0
DNS
Now all I need is a DNS record change. Ah, I forgot about LoadBalancer. For this article, I'm
using LoadBalancer
. After adding a service ELB provides an AWS endpoint for our application.
My primary domain 3sky.dev
is delegated to CloudFlare, so I will add a CNAME record with API.
To do that I need four commands, and sometimes (for DNS propagation).
1# token
2TOKEN=my-private-token
3ZONE=my-domain-zone
4ELB=$(kubectl get svc example-app -n example --output jsonpath='{.status.loadBalancer.ingress[0].hostname}')
5
6curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
7 -H "Authorization: Bearer $TOKEN" \
8 -H "Content-Type: application/json" \
9 --data '{"type":"CNAME","name":"app","content":"'"$ELB"'","ttl":1,"proxied":true}' | jq .
Finally, I can check my app on app.3sky.dev
. Trust me It was working(the app was stopped after checks).
Summary
In case of summary. The whole setup was faster than writing this post based on the ready README.md file. ~10 minutes for EKS, 30 for DNS propagation, command execution was fast - I have a fast keyboard. What can I say more? Testing and implementing stuff is still fun. What next? I don't know. I'm starting Elixir again, so maybe some sophisticated CI/CD for functional language?
- Repository: GitHub