Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Production-grade microservices on Amazon EKS

Designed and deployed a multi-service architecture on AWS EKS with independent service scaling, zero-downtime rolling updates, automated DNS management via Route53, and transactional email delivery through SES — validating three distinct deployment strategies with full rollback capability.


Architecture

Internet
   │
   ▼
ALB Ingress (HTTPS, SSL termination, HTTP→HTTPS redirect)
   │  ← External DNS auto-creates Route53 A records on deploy
   ▼
User Management Service  (:8095, NodePort)
   │                         │
   │ ClusterIP DNS            │ ExternalName DNS alias
   ▼                         ▼
Notification Service     RDS MySQL
(:8096, ClusterIP)       (ExternalName service)
   │
   │ ExternalName DNS alias
   ▼
AWS SES SMTP

Why ClusterIP for the Notification service? It has no legitimate reason to be reachable externally. ClusterIP enforces this at the network layer, reduces attack surface, and avoids unnecessary load balancer cost.

Why ExternalName for SMTP and RDS? Application code references stable in-cluster DNS names (smtp-service, mysql). Swapping endpoints — region failover, DB migration — is a one-line manifest change with no redeployment.

Why one ALB Ingress instead of per-service LoadBalancers? A single ALB means one billing unit, centralised SSL, and HTTP→HTTPS redirect handled at the edge. External DNS automates Route53 record creation on every deploy.


Tech stack

Layer Technology
Container orchestration Amazon EKS (Kubernetes 1.28)
Networking ALB Ingress Controller, ClusterIP, NodePort, ExternalName
DNS automation External DNS + Route53
Database AWS RDS (MySQL 8), bridged via ExternalName service
Email delivery AWS SES SMTP, credentials in Kubernetes Secrets
IAM Scoped SMTP credentials, least-privilege policy
Containers Docker (images on Docker Hub)
Validation kubectl, Postman

Prerequisites

  1. EKS cluster running with managed node group
  2. ALB Ingress Controller installed (aws-load-balancer-controller)
  3. External DNS installed with Route53 write permissions
  4. AWS RDS instance (MySQL) in the same VPC
  5. AWS SES SMTP credentials generated, sender email verified
  6. ACM certificate issued for your domain

Verify controllers are running before deploying:

# ALB Ingress Controller
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller

# External DNS
kubectl get pods -n kube-system -l app=external-dns

Quick start

1. Configure secrets

Do not edit 00-smtp-secret.yml directly. Create the secret from the command line instead:

kubectl create secret generic smtp-credentials \
  --from-literal=username=YOUR_SES_SMTP_USERNAME \
  --from-literal=password=YOUR_SES_SMTP_PASSWORD \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl create secret generic mysql-db-password \
  --from-literal=db_password=YOUR_RDS_PASSWORD \
  --dry-run=client -o yaml | kubectl apply -f -

2. Update placeholders

File Field Replace with
01-mysql-externalname-service.yml externalName Your RDS endpoint
07-alb-ingress.yml certificate-arn Your ACM cert ARN
07-alb-ingress.yml external-dns.alpha.kubernetes.io/hostname Your domain
05-notification-deployment.yml AWS_MAIL_SERVER_FROM_ADDRESS Verified SES sender

3. Deploy

chmod +x scripts/deploy.sh
./scripts/deploy.sh deploy

Or apply directly:

kubectl apply -f kube-manifests/v1/
kubectl rollout status deployment/usermgmt-microservice
kubectl rollout status deployment/notification-microservice

Rollout strategies

Three strategies were validated with rollback confirmation. All produce zero downtime (maxUnavailable: 0 in the rolling update policy).

Strategy 1 — Imperative set-image

Fastest path for hotfixes. No manifest change needed.

kubectl set image deployment/notification-microservice \
  notification-service=stacksimplify/kube-notifications-microservice:2.0.0

kubectl rollout status deployment/notification-microservice
kubectl rollout history deployment/notification-microservice

# Rollback
kubectl rollout undo deployment/notification-microservice

Strategy 2 — Live manifest edit

Useful when reviewing the full spec in context before committing.

kubectl edit deployment/notification-microservice
# Update: image: stacksimplify/kube-notifications-microservice:2.0.0
# Save and exit — Kubernetes triggers the rolling update immediately

kubectl rollout status deployment/notification-microservice

# Rollback
kubectl rollout undo deployment/notification-microservice

Strategy 3 — Declarative apply (recommended)

The GitOps-aligned approach. Idempotent, auditable, and the natural precursor to ArgoCD or Flux.

# Update image tag in kube-manifests/v2/05-notification-deployment.yml, then:
kubectl apply -f kube-manifests/v2/

kubectl rollout status deployment/notification-microservice

# Rollback
kubectl rollout undo deployment/notification-microservice

Secrets management

Approach When
kubectl create secret (current) Development and demo environments
Kubernetes Secrets + RBAC Multi-team clusters
AWS Secrets Manager + External Secrets Operator Production
IRSA + Secrets Manager + envelope encryption Production (hardened)

The manifests in this repo use Kubernetes Secrets sourced from secretKeyRef — credentials never appear as literal values in YAML. The .gitignore blocks any *-secret.yml files from being committed.


Validation

# Service health
curl https://services.yourdomain.com/usermgmt/health-status
curl https://services.yourdomain.com/usermgmt/notification-health-status

# Pod logs
kubectl logs -f -l app=usermgmt-restapp
kubectl logs -f -l app=notification-restapp

# Full status
./scripts/deploy.sh status

Import docs/postman-collection.json into Postman to run the full create-user → verify-email flow.


Known limitations and production improvements

Synchronous notification coupling — User creation calls Notification Service synchronously. If the notification service is unavailable, user creation degrades. Production fix: decouple with SQS. User creation publishes an event; Notification Service consumes and retries asynchronously.

Single replica per service — Manifests run one replica for demo purposes. Production would set replicas: 2+ per service with a PodDisruptionBudget to guarantee availability during node maintenance.

No HPA — Horizontal Pod Autoscaler is not configured. A real workload would define CPU/memory thresholds and min/max replica bounds.

CI/CD — The declarative apply strategy is the natural entry point for GitOps. Next step: GitHub Actions pipeline that lints manifests with kubeval, runs kubectl diff, and applies on merge to main via ArgoCD.


Teardown

./scripts/deploy.sh teardown
# or
kubectl delete -f kube-manifests/v1/

Route53 records created by External DNS are cleaned up automatically when the Ingress resource is deleted.

About

A multi-service architecture template for AWS EKS with featuring independent service scaling, zero dwontime rolling updates, automated DNS management via Route53 and transactional email delivery through SES.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages