Deploy Multi-App ke AWS EKS dengan 1 Shared ALB

Introduction

Setelah punya cluster EKS + AWS Load Balancer Controller, langkah selanjutnya yang paling impactful adalah: menjalankan banyak aplikasi dalam 1 ALB. Pattern ini bisa menghemat ~$32/bulan untuk 3 apps, plus DNS & TLS management jadi lebih sederhana. Baca artikel sebelumnya di https://blog.igunawan.com/deploying-aws-eks-cluster-using-terragrunt/

Apa yang Akan kita coba lakukan ?

Di artikel ini ini, kita akan punya 3 aplikasi (bisa ditambah) yang berjalan di cluster EKS yang sama, share 1 Application Load Balancer:

AplikasiImagePortDomain
learngunawand/learn-devops-1:v1.080learn.igunawan.com
maintenancegunawand/front-maintenance:bidel3000maintenance.igunawan.com
nodeappgunawand/nodeapp:v13000nodeapp.igunawan.com

Semua di-route oleh 1 ALB lewat IngressGroup, dengan host-based routing.

Why ALB ?

AWS ALB harganya sekitar $0.0225/jam ≈ $16/bulan. Tanpa sharing:

Jumlah AppALBBiaya/bulan
11$16
33$48
55$80
1010$160

Dengan IngressGroup (1 ALB untuk semua):

Jumlah AppALBBiaya/bulan
11$16
31$16 (hemat $32)
51$16 (hemat $64)
101$16 (hemat $144)

Hematannya signifikan. Trade-off-nya: kalau ALB down, semua app down (single point of failure). Untuk dev/prod kecil, ini acceptable.

Architecture

                          ┌─────────────────────────────────────┐
                          │         Internet                    │
                          └─────────────┬───────────────────────┘
                                        │
                            DNS: *.igunawan.com
                                        │
                          ┌─────────────▼────────────────────── ─┐
                          │  AWS Application Load Balancer       │
                          │  "shared-alb"                        │
                          │                                      │
                          │  Listener Rules (by Host header):    │
                          │    learn.igunawan.com       ──┐      │
                          │    maintenance.igunawan.com ──┤      │
                          │    nodeapp.igunawan.com     ──┤      │
                          └───────────────────────────────┼──────┘
                                                          │
                          ┌───────────────────────────────▼────── ┐
                          │   EKS Cluster                         │
                          │   Namespace: "be"                     │
                          │                                       │
                          │   ┌──────────┐ ┌──────────┐  ┌──────┐ │
                          │   │  learn   │ │mainten.  │  │nodeap│ │
                          │   │  :80     │ │  :3000   │  │:3000 │ │
                          │   │  (Svc)   │ │  (Svc)   │  │(Svc) │ │
                          │   └────┬─────┘ └─────┬─────┘ └──┬───┘ │
                          │        │             │          │     │
                          │   ┌────▼─────┐ ┌─────▼─────┐ ┌──▼───┐ │
                          │   │  Pods    │ │  Pods     │ │Pods  │ │
                          │   │  (x2)    │ │  (x2)     │ │(x2)  │ │
                          │   └──────────┘ └───────────┘ └──────┘ │
                          └────────────────────────────────────── ┘

1 ALB, 3 target groups (satu per service), host-based routing.

Syarat

Sudah selesai dari tutorial sebelumnya:

  • ✅ EKS cluster running (lihat tutorial sebelumnya)
  • ✅ AWS Load Balancer Controller ter-install di cluster
  • ✅ kubectl konek ke cluster
  • ✅ Image Docker Hub (public atau private dengan secret)

Domain sendiri (opsional, tapi sangat direkomendasikan):

  • igunawan.com di Cloudflare / Niagahoster / Route53

Step 1: Generic Chart dengan nameOverride & fullnameOverride – Helm Chart

Kunci dari pattern ini: 1 chart, multiple values files. Tidak perlu bikin chart baru tiap app.

Pastikan chart Anda punya:

  • _helpers.tpl yang support nameOverride & fullnameOverride
  • Template yang parameterized via values

Snippet _helpers.tpl:

{{- define "learn.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

Step 2: Values Files Per App

Setiap app punya file values-<nama-app>.yaml sendiri. Lebih mudah maintain dibanding satu file besar dengan if-else.

charts/learn/values-maintenance.yaml

# Override values untuk deployment "maintenance"
nameOverride: maintenance
fullnameOverride: maintenance

image:
  repository: gunawand/front-maintenance
  tag: bidel
  pullPolicy: IfNotPresent

# Container listen di port 3000
containerPort: 3000

service:
  type: ClusterIP
  port: 3000   # ← HARUS sama dengan containerPort (lihat Gotcha #12)

resources:
  requests: { cpu: 100m, memory: 128Mi }
  limits:   { cpu: 500m, memory: 512Mi }

ingress:
  enabled: true
  className: alb

  hosts:
    - host: maintenance.igunawan.com
      paths:
        - path: /
          pathType: Prefix

  alb:
    scheme: internet-facing
    targetType: ip
    healthCheckPath: /
    groupName: shared-alb    # ← SHARE ALB dengan app lain
    tags:
      Environment: dev
      Project: eks-learn

charts/learn/values-nodeapp.yaml

nameOverride: nodeapp
fullnameOverride: nodeapp

image:
  repository: gunawand/nodeapp
  tag: v1
  pullPolicy: IfNotPresent

containerPort: 3000    # atau 8080, tergantung app
service:
  type: ClusterIP
  port: 3000

resources:
  requests: { cpu: 100m, memory: 128Mi }
  limits:   { cpu: 500m, memory: 512Mi }

ingress:
  enabled: true
  className: alb

  hosts:
    - host: nodeapp.igunawan.com
      paths:
        - path: /
          pathType: Prefix

  alb:
    scheme: internet-facing
    targetType: ip
    healthCheckPath: /
    groupName: shared-alb   # ← sama dengan maintenance & learn
    tags:
      Environment: dev
      Project: eks-learn

charts/learn/values-learn.yaml (atau pakai Terragrunt stack)

Untuk app pertama, kita pakai stack Terragrunt (lihat tutorial sebelumnya). Tapi kalau mau konsisten pakai helm install juga, bisa:

# charts/learn/values-learn.yaml
nameOverride: learn
fullnameOverride: learn

image:
  repository: gunawand/learn-devops-1
  tag: v1.0
  pullPolicy: IfNotPresent

containerPort: 80
service:
  type: ClusterIP
  port: 80

# imagePullSecrets (kalau private image):
imagePullSecrets:
  - name: dockerhub-creds

ingress:
  enabled: true
  className: alb

  hosts:
    - host: learn.igunawan.com
      paths:
        - path: /
          pathType: Prefix

  alb:
    scheme: internet-facing
    targetType: ip
    healthCheckPath: /
    groupName: shared-alb    # ← WAJIB sama untuk semua app
    tags:
      Environment: dev
      Project: eks-learn

Step 3: Deploy Semua Apps

kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
# Harus 1/1 Running

3.2. Deploy app pertama (learn)

cd days-5-eks

# Cara A: pakai Terragrunt (recommended untuk GitOps)
cd live/aws/dev/learn
terragrunt apply -auto-approve
cd ../../../..

# Cara B: pakai helm install (untuk testing cepat)
helm upgrade --install learn charts/learn/ \
  -n be \
  --create-namespace \
  -f charts/learn/values-learn.yaml

3.3. Deploy app kedua (maintenance)

helm upgrade --install maintenance charts/learn/ \
  -n be \
  -f charts/learn/values-maintenance.yaml

3.4. Deploy app ketiga (nodeapp)

helm upgrade --install nodeapp charts/learn/ \
  -n be \
  -f charts/learn/values-nodeapp.yaml

3.5. Verifikasi

# Semua pod harus Running
kubectl get pods -n be
# NAME                          READY   STATUS    RESTARTS   AGE
# learn-7c8d4f9b9c-xxxxx       1/1     Running   0          5m
# learn-7c8d4f9b9c-yyyyy       1/1     Running   0          5m
# maintenance-xxx-yyyy         1/1     Running   0          1m
# maintenance-xxx-zzzz         1/1     Running   0          1m
# nodeapp-xxx-aaaaa            1/1     Running   0          30s
# nodeapp-xxx-bbbbb            1/1     Running   0          30s

# Cek Ingress — semua harus share ADDRESS yang sama
kubectl get ingress -n be
# NAME            CLASS   HOSTS                       ADDRESS
# learn           alb     learn.igunawan.com          k8s-be-sharedalb-xxx.elb.amazonaws.com
# maintenance     alb     maintenance.igunawan.com    k8s-be-sharedalb-xxx.elb.amazonaws.com  ← SAMA
# nodeapp         alb     nodeapp.igunawan.com        k8s-be-sharedalb-xxx.elb.amazonaws.com  ← SAMA

Step 4: Setup DNS

Ada 3 domain yang kita perlu setup, kebetulan saya menggunakan Cloudflare amaka kita tambahkan dengan type record CNAME 3 domain tersebut

contoh :

Type:   CNAME
Name:   nodeapp.igunawan.com
Target: k8s-be-sharedalb-xxx.elb.amazonaws.com
TTL:    300
Proxy:  On/Off

Tambahkan sampai 3 domain tsb kemudian tunggu 1-3 menit kemudian coba akses domainya.

  • learn.igunawan.com
  • maintenance.igunawan.com
  • nodeapp.igunawan.com

File reference

── charts/learn/
│   ├── Chart.yaml
│   ├── values.yaml                  # defaults
│   ├── values-learn.yaml            # app-specific override (opsional)
│   ├── values-maintenance.yaml      # override untuk maintenance
│   ├── values-nodeapp.yaml          # override untuk nodeapp
│   └── templates/
│       ├── deployment.yaml
│       ├── service.yaml
│       └── ingress.yaml
└── live/aws/dev/
    ├── vpc/
    ├── eks/
    ├── alb-controller/              # LBC + IRSA
    └── learn/                       # atau pakai helm install langsung

Leave a Reply

Your email address will not be published. Required fields are marked *