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.
# I'd like to have control plane endpoint
output "cluster_endpoint" {
description = "Endpoint for EKS control plane."
value = module.eks.cluster_endpoint
}
# get kubectl config based on cluster_name
output "cluster_name" {
description = "Name of created cluster"
value = local.cluster_name
}
# upload to ECR with dynamic name
output "ecr_url" {
description = "URL of ECR registry"
value = aws_ecr_repository.ecr.repository_url
}
# also region could be dynamic
output "region" {
description = "AWS region."
value = var.region
}
Variables.tf
and main.tf
weren’t very interesting, so it will be pushed to the repo.
Commands flow
# get modules
terraform init
# take a look at plan, if it's correct go-ahead
terraform plan | less
# this step will take some time to finish. (9:33.03 total)
# if correct enter yes or terraform apply -auto-approve
terraform 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.
# variables are based on Terraform outputs
aws eks update-kubeconfig \
--region $(terraform output -raw region) \
--name $(terraform output -raw cluster_name)
kubectl get pod
Docker login
Now I need to login into ECR and push some images.
aws ecr get-login-password \
--region $(terraform output -raw region) \
| docker login --username AWS \
--password-stdin $(terraform output -raw ecr_url | cut -d'/' -f1)
Then I can push an awesome Nginx image to ECR.
docker tag nginx:latest $(terraform output -raw ecr_url):1.0.0
docker 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
# dry run
helm template <app name> -f <file with values> --dry-run <chart name>
# for example
# helm template example-app -f example-app.yaml --dry-run ./example-app
# install chart
helm install <app name> -f <file with values> --namespace <namespace> <chart name>
# for example
# helm install example-app -f example-app.yaml --namespace example ./example-app
# upgrade app
helm upgrade <app name> <chart> --set.image=<tag>
# for example
# 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).
# token
TOKEN=my-private-token
ZONE=my-domain-zone
ELB=$(kubectl get svc example-app -n example --output jsonpath='{.status.loadBalancer.ingress[0].hostname}')
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--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