---
title: "AWS Istanbul Local Zone ile KVKK Uyumlu Cloud Mimarisi - Bölüm 3: Node'lar ve Servisler"
description: EKS cluster, Istanbul worker node group, Karpenter v1, EBS CSI ve ALB Controller - AWS Istanbul Local Zone kurulumunun tüm adımları gerçek Terragrunt koduyla.
---

[Hepapi Blog - hepapi.com](https://hepapi.com/blog)

# [AWS Istanbul Local Zone ile KVKK Uyumlu Cloud Mimarisi - Bölüm 3: Node'lar ve Servisler](https://hepapi.com/blog/aws-istanbul-local-zone-ile-kvkk-uyumlu-cloud-mimarisi-bölüm-3-nodelar-ve-servisleri)

 Written by [Berat Uyanık](https://hepapi.com/blog/author/berat-uyanık) | Jun 4, 2026 7:43:55 AM

### Bu blog, [AWS Istanbul Local Zone ile KVKK Uyumlu Cloud Mimarisi - Bölüm 2: Temel Altyapı](https://hepapi.com/blog/aws-istanbul-local-zone-ile-kvkk-uyumlu-cloud-mimarisi-b%C3%B6l%C3%BCm-2-temel-altyap%C4%B1)'nın devamıdır.

 

Bu yazıda EKS cluster, Istanbul worker node group, Karpenter ile dinamik scaling, EBS CSI driver ve ALB Controller kurulumunu gerçek kod örnekleriyle anlatıyorum.

 

#### 6. EKS Cluster Kurulumu

**Control Plane Kısıtlaması**

EKS control plane Local Zone subnet'lerini **kabul etmez** ve minimum 2 farklı standart AZ gerektirir. slice() ile ilk iki subnet seçilir:

```
# env/hepapi/eu-central-1/prod/eks/eks/terragrunt.hcl
terraform {
  source = "tfr:///terraform-aws-modules/eks/aws//?version=${local.env_vars.locals.module_versions.eks}"

  # apply sonrası kubeconfig otomatik güncellenir
  after_hook "after_hook" {
    commands = ["apply"]
    execute  = [
      "aws", "eks", "update-kubeconfig",
      "--region",  "${include.root.locals.region}",
      "--name",    "${local.env_vars.locals.eks.cluster_name}",
      "--profile", "${local.env_vars.locals.aws_profile}"
    ]
  }
}

inputs = {
  cluster_name    = local.env_vars.locals.eks.cluster_name
  cluster_version = "1.35"

  vpc_id = dependency.vpc.outputs.vpc_id

  # KRITIK: Local Zone control plane'de çalışmaz
  # Sadece index 0 (eu-central-1a) ve 1 (eu-central-1b)
  subnet_ids = slice(dependency.vpc.outputs.private_subnets, 0, 2)

  authentication_mode             = "API"
  cluster_endpoint_private_access = true
  cluster_endpoint_public_access  = true
  cluster_service_ipv4_cidr       = "10.240.0.0/16"
  enable_irsa                     = true

  cluster_addons = {
    coredns = {
      addon_version = "v1.13.2-eksbuild.3"
    }
    eks-pod-identity-agent = {}
    vpc-cni = {
      addon_version = "v1.21.1-eksbuild.1"
      configuration_values = jsonencode({
        env = {
          # Prefix delegation: node başına daha fazla pod IP'si
          ENABLE_PREFIX_DELEGATION = "true"
          WARM_PREFIX_TARGET       = "1"
        }
      })
    }
  }

  # Karpenter node discovery için security group tag'i
  node_security_group_tags = {
    "karpenter.sh/discovery/${local.env_vars.locals.eks.cluster_name}" = local.env_vars.locals.eks.cluster_name
  }
}
```

 

**SSO ile EKS Erişimi**

EKS access entry için **IAM user ARN değil, SSO permission set role ARN** kullanın. Bu yaklaşımla o permission set'e sahip tüm kullanıcılar tek tanımla admin yetkisi alır ve her kullanıcı için ayrı access entry yazmaya gerek kalmaz.

SSO role ARN'ını bulun:

```
aws iam list-roles --profile hepapi-sso \
  --query 'Roles[?contains(RoleName, `AWSReservedSSO`)].{Name:RoleName,Arn:Arn}' \
  --output table
```

```
# env.hcl — access_entries
access_entries = {
  hepapi = {
    # Tüm SSO AdministratorAccess kullanıcıları bu role ile gelir
    principal_arn = "arn:aws:iam::xxxxxxxxxxxxx:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccess_xxxxxxxxxxxxxxxx"
    policy_associations = {
      policy = {
        policy_arn   = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
        access_scope = { type = "cluster" }
      }
    }
  }
}
```

 

#### 7. Istanbul Worker Node Group

Node group yalnızca private\_subnets\[2\] (Istanbul) subnet'ine kurulur:

```
# env/hepapi/eu-central-1/prod/eks/node-group/terragrunt.hcl
inputs = {
  name            = "hepapi-istanbul-node-group"
  cluster_name    = dependency.eks.outputs.cluster_name
  cluster_version = dependency.eks.outputs.cluster_version

  # Sadece Istanbul Local Zone subnet (index 2)
  subnet_ids = slice(dependency.vpc.outputs.private_subnets, 2, 3)

  instance_types = ["m7i.xlarge"]
  capacity_type  = "ON_DEMAND"  # Local Zone'da Spot desteklenmez

  min_size     = 1
  max_size     = 2
  desired_size = 1

  block_device_mappings = {
    xvda = {
      device_name = "/dev/xvda"
      ebs = {
        volume_size = 80
        volume_type = "gp3"
      }
    }
  }

  # SSM ile SSH yerine güvenli node erişimi
  iam_role_additional_policies = {
    AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  }

  # Workload scheduling için node label'ları
  # Bu label'lar Deployment nodeSelector'da kullanılır
  labels = {
    topology = "local-zone"
    zone     = "istanbul"
  }
}
```

Node'un Istanbul'da çalıştığını doğrulayın:

```
kubectl get nodes -o custom-columns='NAME:.metadata.name,ZONE:.metadata.labels.topology\.kubernetes\.io/zone'
```

 

#### 8. Karpenter ile Dinamik Scaling

Static node group yetmediğinde Karpenter devreye girer. Istanbul için özel yapılandırma gerektiriyor - yanlış yapılandırılırsa Karpenter Frankfurt'ta node açar, Istanbul'da değil.

**Karpenter IAM Modülü**

```
# env/hepapi/eu-central-1/prod/eks/karpenter/karpenter-module/terragrunt.hcl
terraform {
  source = "tfr:///terraform-aws-modules/eks/aws//modules/karpenter//?version=20.33.1"
}

inputs = {
  cluster_name                    = dependency.eks.outputs.cluster_name
  enable_v1_permissions           = true
  enable_irsa                     = true
  enable_pod_identity             = true
  create_pod_identity_association = true

  node_iam_role_additional_policies = {
    AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  }
}
```

 

**Karpenter Helm Chart**

```
# env/hepapi/eu-central-1/prod/eks/karpenter/karpenter-controller-helm/terragrunt.hcl
inputs = {
  name          = "karpenter"
  namespace     = "kube-system"
  chart_version = "1.1.2"
  helm_repo_url = "oci://public.ecr.aws/karpenter"

  sets = [
    { name  = "serviceAccount.name",
      value = dependency.karpenter-module.outputs.service_account },
    { name  = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn",
      value = dependency.karpenter-module.outputs.iam_role_arn },
    { name  = "settings.interruptionQueue",
      value = dependency.karpenter-module.outputs.queue_name },
    { name  = "settings.clusterName",
      value = dependency.eks.outputs.cluster_name },
    { name  = "settings.clusterEndpoint",
      value = dependency.eks.outputs.cluster_endpoint },
    { name  = "replicas", value = "1" }
  ]
}
```

 

**NodePool - Istanbul'a Özgü Yapılandırma**

Bu NodePool tanımında **iki kritik requirement** var:

- **topology.kubernetes.io/zone: eu-central-1-ist-1a** → Sadece Istanbul'da node aç
- **instance-generation Gt 6** → Sadece 7. nesil seç (c7i/m7i/r7i) — 6. nesil desteklenmiyor

```
# modules/karpenter/karpenter_node_pool.tf
resource "kubectl_manifest" "karpenter_node_pool" {
  yaml_body = <<-YAML
    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: hepapi-istanbul
      labels:
        capacity-type: on-demand
    spec:
      template:
        metadata:
          labels:
            capacity-type: on-demand
            topology: local-zone
            zone: istanbul
        spec:
          nodeClassRef:
            group: karpenter.k8s.aws
            kind: EC2NodeClass
            name: default
          requirements:
            - key: "karpenter.k8s.aws/instance-category"
              operator: In
              values: ["c", "m", "r"]
            - key: "karpenter.k8s.aws/instance-generation"
              operator: Gt
              values: ["6"]           # 7. nesil ve üzeri: c7i, m7i, r7i
            - key: "kubernetes.io/arch"
              operator: In
              values: ["amd64"]
            - key: "karpenter.sh/capacity-type"
              operator: In
              values: ["on-demand"]   # Spot yok!
            - key: "topology.kubernetes.io/zone"
              operator: In
              values: ["eu-central-1-ist-1a"]  # Sadece Istanbul
      limits:
        cpu: 50
      disruption:
        consolidationPolicy: WhenEmptyOrUnderutilized
        consolidateAfter: 60s
  YAML
}
```

Karpenter'ın doğru çalıştığını doğrulayın:

```
# Karpenter pod'u çalışıyor mu?
kubectl get pods -n kube-system -l app.kubernetes.io/name=karpenter

# NodePool durumu
kubectl get nodepool hepapi-istanbul

# Karpenter tarafından açılan node'lar
kubectl get nodes -l karpenter.sh/nodepool=hepapi-istanbul
```

Pod'ları Istanbul node'larına yönlendirmek için nodeSelector ekleyin:

```
spec:
  nodeSelector:
    topology: local-zone
    zone: istanbul
```

 

#### 9. EBS CSI Driver - Zone-Aware Storage

Local Zone'da storage kurulumunda yapılan en yaygın hata: StorageClass'a hardcoded zone topology eklemek.

**Yanlış yaklaşım:**

```
# BUNU YAPMAYIN — pod başka node'a taşınırsa volume erişilemez
volumeBindingMode: Immediate
allowedTopologies:
  - matchLabelExpressions:
    - key: topology.kubernetes.io/zone
      values: ["eu-central-1-ist-1a"]
```

**Doğru yaklaşım:** WaitForFirstConsumer - volume, pod'un schedule edildiği node'un zone'unda oluşturulur. Zone değişirse volume de değişir.

```
# modules/ebs-csi/main.tf
resource "helm_release" "aws_ebs_csi_driver" {
  name       = "aws-ebs-csi-driver"
  namespace  = "kube-system"
  repository = "https://kubernetes-sigs.github.io/aws-ebs-csi-driver/"
  chart      = "aws-ebs-csi-driver"
  version    = var.chart_version

  set = [
    { name  = "controller.serviceAccount.create", value = "true" },
    { name  = "controller.serviceAccount.name",   value = "ebs-csi-controller-sa" },
    { name  = "controller.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn",
      value = var.ebs_csi_role_arn },
  ]
}

resource "kubectl_manifest" "storageclass" {
  yaml_body = <<-YAML
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: ${var.storageclassname}
    provisioner: ebs.csi.aws.com
    parameters:
      tagSpecification_1: "Name=-"
      tagSpecification_2: "Namespace="
    allowVolumeExpansion: true
    volumeBindingMode: WaitForFirstConsumer  # Pod'u takip et, zone hardcode etme
  YAML
}
```

 

#### 10. AWS Load Balancer Controller

ALB'yi Istanbul Local Zone'da oluşturmak için alb.ingress.kubernetes.io/subnets annotation'ına Local Zone subnet adını vermek yeterli.

**IAM IRSA Role**

```
# modules/aws-alb-controller-role/main.tf
module "lb_role" {
  source  = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
  version = "~> 5.52.0"  # v6 dizin yapısını değiştirdi, pinlemek şart

  role_name                              = "eks-lb-controller-${var.cluster_name}"
  attach_load_balancer_controller_policy = true

  oidc_providers = {
    main = {
      provider_arn               = var.oidc_provider_arn
      namespace_service_accounts = ["kube-system:aws-load-balancer-controller"]
    }
  }
}

resource "kubernetes_service_account" "service-account" {
  metadata {
    name      = "aws-load-balancer-controller"
    namespace = "kube-system"
    annotations = {
      "eks.amazonaws.com/role-arn"               = module.lb_role.iam_role_arn
      "eks.amazonaws.com/sts-regional-endpoints" = "true"
    }
  }
}
```

 

**Helm Chart**

```
# env/hepapi/eu-central-1/prod/eks/alb-controller/aws-alb-controller/terragrunt.hcl
inputs = {
  name          = "aws-load-balancer-controller"
  namespace     = "kube-system"
  chart_version = "1.11.0"
  helm_repo_url = "https://aws.github.io/eks-charts"

  sets = [
    { name = "serviceAccount.create", value = "false" },
    { name = "serviceAccount.name",   value = "aws-load-balancer-controller" },
    { name = "clusterName",           value = dependency.eks.outputs.cluster_name },
    { name = "vpcId",                 value = dependency.vpc.outputs.vpc_id },
    # eu-central-1 ECR mirror (us-east-1 değil!)
    { name = "image.repository",
      value = "602401143452.dkr.ecr.eu-central-1.amazonaws.com/amazon/aws-load-balancer-controller" }
  ]
}
```

 

**Ingress Örneği - Local Zone İçin Annotation'lar**

ALB'yi Istanbul Local Zone'da oluşturmak için tek yapmanız gereken alb.ingress.kubernetes.io/subnets annotation'ına Local Zone subnet adını vermek. AWS Load Balancer Controller bu subnet'i okuyarak ALB'yi doğrudan Istanbul'da açar.

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
  namespace: default
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    # ZORUNLU: pod IP'lerine doğrudan yönlendirme için IP modunu kullan
    alb.ingress.kubernetes.io/target-type: ip
    # ALB'yi Istanbul Local Zone subnet'inde oluştur
    alb.ingress.kubernetes.io/subnets: eu-central-1-ist-1a
    alb.ingress.kubernetes.io/healthcheck-path: /health
spec:
  ingressClassName: alb
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80
```

 

← **Önceki:** [Bölüm 2: Temel Altyapı](https://hepapi.com/blog/aws-istanbul-local-zone-ile-kvkk-uyumlu-cloud-mimarisi-b%C3%B6l%C3%BCm-2-temel-altyap%C4%B1)   

**Serinin devamı →** Bölüm 4: Production'a Taşımak - Sorunlar, Maliyet ve Best Practices için takipte kalın.

[View full post](https://hepapi.com/blog/aws-istanbul-local-zone-ile-kvkk-uyumlu-cloud-mimarisi-bölüm-3-nodelar-ve-servisleri)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Berat Uyanık"
  },
  "dateModified" : "2026-06-04T07:44:51.246Z",
  "datePublished" : "2026-06-04T07:43:55Z",
  "headline" : "AWS Istanbul Local Zone ile KVKK Uyumlu Cloud Mimarisi - Bölüm 3: Node'lar ve Servisler",
  "image" : {
    "@type" : "ImageObject",
    "height" : 1536,
    "url" : "https://8810897.fs1.hubspotusercontent-na1.net/hubfs/8810897/03.jpeg",
    "width" : 2752
  },
  "mainEntityOfPage" : "https://hepapi.com/blog/aws-istanbul-local-zone-ile-kvkk-uyumlu-cloud-mimarisi-bölüm-3-nodelar-ve-servisleri",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "Hepapi Blog"
  }
}
```