Bulut Kaynak Etiketleme Stratejileri: Maliyet ve Güvenliği Kontrol Altına Alın

Bulut maliyetleri patlamış, kim ne harcıyor belli değil, hangi kaynak hangi projeye ait kimse bilmiyor. Tanıdık geldi mi? İşte bu kaosun tam ortasında etiketleme (tagging) stratejisi devreye giriyor. Etiketler kulağa basit geliyor, ama kurumsal bir ortamda doğru bir etiketleme politikası olmadan bulut yönetimi kör adam kör değneğini arıyor misali bir hal alıyor.

Bu yazıda AWS, Azure ve GCP üzerinden gerçek dünya senaryolarıyla, sıfırdan kurgulanmış ya da mevcut kaotik ortamı düzene sokmaya çalışan sysadminler için pratik bir etiketleme rehberi hazırladım.

Etiketleme Neden Bu Kadar Önemli?

Birçok şirkette bulut göçü hızlıca yapılıyor, ama governance yani yönetişim kısmı hep sonraya bırakılıyor. Altı ay sonra 50 farklı EC2 instance var, hangisi test hangisi production kimse bilmiyor. Fatura geliyor, 80.000 TL, ama hangi ekibin harcaması bu? CFO sana bakıyor, sen de buluta bakıyorsun.

Etiketler tam burada işe yarıyor:

  • Maliyet tahsisi: Hangi ekip, hangi proje ne kadar harcıyor
  • Güvenlik ve uyumluluk: Hangi kaynak hangi güvenlik seviyesinde
  • Operasyonel yönetim: Otomatik kapatma, yedekleme politikaları
  • Erişim kontrolü: ABAC (Attribute-Based Access Control) için temel
  • Raporlama ve denetim: Audit süreçlerinde kaynakları hızlı filtreleme

Temel Etiket Kategorileri

Önce evrensel olarak kullanılan etiket kategorilerini anlayalım. Bunları doğrudan kopyalayıp yapıştırabilirsiniz:

Kimlik Etiketleri:

  • Name: Kaynağın insan tarafından okunabilir adı
  • Owner: Kaynağı kim oluşturdu, kim sorumlu
  • Team: Hangi ekibe ait (platform, backend, data, security)
  • Project: Hangi projeye bağlı

Maliyet Etiketleri:

  • CostCenter: Muhasebe maliyet merkezi kodu
  • BillingProject: Faturalandırma projesi
  • Environment: prod, staging, dev, test

Operasyonel Etiketler:

  • AutoShutdown: true/false, otomatik kapatma gerekiyor mu
  • BackupPolicy: daily, weekly, none
  • MaintenanceWindow: Bakım penceresi
  • Criticality: critical, high, medium, low

Uyumluluk Etiketleri:

  • DataClassification: public, internal, confidential, restricted
  • ComplianceScope: pci, hipaa, gdpr, none
  • RetentionPolicy: 30d, 90d, 1y, 7y

AWS Üzerinde Etiketleme

AWS en olgun etiketleme ekosistemini sunuyor. Tag Editor, AWS Config, ve Cost Explorer ile birlikte güçlü bir yönetim sağlanabiliyor.

Zorunlu Etiket Politikası – AWS Organizations

AWS Organizations kullanıyorsanız, tag policy ile zorunlu etiket kuralları koyabilirsiniz:

# AWS CLI ile tag policy oluşturma
aws organizations create-policy 
  --name "MandatoryTagsPolicy" 
  --type TAG_POLICY 
  --description "Zorunlu etiket politikasi" 
  --content '{
    "tags": {
      "Environment": {
        "tag_key": {
          "@@assign": "Environment"
        },
        "tag_value": {
          "@@assign": ["prod", "staging", "dev", "test"]
        },
        "enforced_for": {
          "@@assign": ["ec2:instance", "rds:db", "s3:bucket"]
        }
      },
      "CostCenter": {
        "tag_key": {
          "@@assign": "CostCenter"
        },
        "enforced_for": {
          "@@assign": ["ec2:instance", "rds:db"]
        }
      }
    }
  }'

Terraform ile Zorunlu Etiket Modülü

Infrastructure as Code kullanıyorsanız, merkezi bir etiket modülü oluşturmak hayat kurtarır:

# variables.tf - merkezi etiket değişkenleri
cat > /opt/terraform/modules/tags/variables.tf << 'EOF'
variable "environment" {
  description = "Ortam: prod, staging, dev, test"
  type        = string
  validation {
    condition     = contains(["prod", "staging", "dev", "test"], var.environment)
    error_message = "Environment sadece prod, staging, dev veya test olabilir."
  }
}

variable "project" {
  description = "Proje adi"
  type        = string
}

variable "cost_center" {
  description = "Maliyet merkezi kodu"
  type        = string
}

variable "team" {
  description = "Sorumlu ekip"
  type        = string
}

variable "owner" {
  description = "Kaynak sahibi (email)"
  type        = string
}

variable "data_classification" {
  description = "Veri siniflandirmasi"
  type        = string
  default     = "internal"
  validation {
    condition     = contains(["public", "internal", "confidential", "restricted"], var.data_classification)
    error_message = "Gecersiz veri siniflandirmasi."
  }
}
EOF

echo "Etiket modulu olusturuldu"
# outputs.tf - standart etiket outputu
cat > /opt/terraform/modules/tags/outputs.tf << 'EOF'
output "common_tags" {
  value = {
    Environment        = var.environment
    Project            = var.project
    CostCenter         = var.cost_center
    Team               = var.team
    Owner              = var.owner
    DataClassification = var.data_classification
    ManagedBy          = "terraform"
    CreatedAt          = timestamp()
  }
}
EOF

# Kullanim ornegi
cat > /opt/terraform/environments/prod/main.tf << 'EOF'
module "tags" {
  source = "../../modules/tags"
  
  environment         = "prod"
  project             = "e-commerce-platform"
  cost_center         = "CC-2024-ECOMM"
  team                = "platform"
  owner               = "[email protected]"
  data_classification = "confidential"
}

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"
  
  tags = merge(module.tags.common_tags, {
    Name            = "web-server-01"
    AutoShutdown    = "false"
    BackupPolicy    = "daily"
  })
}
EOF

Mevcut AWS Kaynaklarını Etiketleme

Zaten etiketlenmemiş kaynaklar için toplu etiketleme scripti:

#!/bin/bash
# bulk_tagger.sh - Etiketsiz AWS kaynaklarini bul ve etiketle

AWS_REGION="eu-west-1"
ENVIRONMENT="prod"
TEAM="platform"
COST_CENTER="CC-2024-INFRA"

echo "=== Etiketsiz EC2 instance'lari tespit ediliyor ==="

# Environment etiketi olmayan instance'lari bul
UNTAGGED_INSTANCES=$(aws ec2 describe-instances 
  --region "$AWS_REGION" 
  --filters "Name=tag-key,Values=Environment" 
  --query 'Reservations[*].Instances[?!Tags[?Key==`Environment`]].InstanceId' 
  --output text 2>/dev/null)

# Alternatif: Hic etiketi olmayan instance'lar
ALL_INSTANCES=$(aws ec2 describe-instances 
  --region "$AWS_REGION" 
  --query 'Reservations[*].Instances[*].InstanceId' 
  --output text)

for INSTANCE_ID in $ALL_INSTANCES; do
  TAGS=$(aws ec2 describe-tags 
    --filters "Name=resource-id,Values=$INSTANCE_ID" 
    --query 'Tags[?Key==`Environment`]' 
    --output text)
  
  if [ -z "$TAGS" ]; then
    echo "Etiketsiz bulundu: $INSTANCE_ID - Etiketleniyor..."
    
    aws ec2 create-tags 
      --resources "$INSTANCE_ID" 
      --tags 
        "Key=Environment,Value=$ENVIRONMENT" 
        "Key=Team,Value=$TEAM" 
        "Key=CostCenter,Value=$COST_CENTER" 
        "Key=ManagedBy,Value=bulk-tagger" 
        "Key=TaggedAt,Value=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
    
    echo "  Etiketlendi: $INSTANCE_ID"
  fi
done

echo "=== Islem tamamlandi ==="

Azure Üzerinde Etiketleme

Azure’da etiketleme politikası Azure Policy ile uygulanıyor. Subscription ve Resource Group seviyesinde kalıtım da destekleniyor.

Azure Policy ile Zorunlu Etiket

# Azure CLI ile etiket politikası oluşturma
az policy definition create 
  --name "require-environment-tag" 
  --display-name "Environment etiketi zorunlu" 
  --description "Tum kaynaklar Environment etiketine sahip olmali" 
  --mode "Indexed" 
  --rules '{
    "if": {
      "field": "tags[Environment]",
      "exists": "false"
    },
    "then": {
      "effect": "deny"
    }
  }'

# Politikayı subscription'a ata
az policy assignment create 
  --name "enforce-environment-tag" 
  --policy "require-environment-tag" 
  --scope "/subscriptions/$(az account show --query id -o tsv)"

# Resource Group'taki tüm kaynaklara etiket uygula
az tag update 
  --resource-id "/subscriptions/SUB_ID/resourceGroups/my-rg" 
  --operation merge 
  --tags Environment=prod Team=platform CostCenter=CC-2024

Azure Tüm Kaynakları Etiketleme Scripti

#!/bin/bash
# azure_bulk_tag.sh - Resource Group icerisindeki kaynaklari etiketle

RESOURCE_GROUP="myapp-prod-rg"
SUBSCRIPTION_ID=$(az account show --query id -o tsv)

# Ortak etiketler
ENVIRONMENT="prod"
TEAM="backend"
COST_CENTER="CC-2024-BACKEND"
PROJECT="myapp"

echo "Resource Group: $RESOURCE_GROUP icin etiketleme basliyor..."

# RG'deki tüm kaynak ID'lerini al
RESOURCE_IDS=$(az resource list 
  --resource-group "$RESOURCE_GROUP" 
  --query "[].id" 
  --output tsv)

for RESOURCE_ID in $RESOURCE_IDS; do
  RESOURCE_NAME=$(echo "$RESOURCE_ID" | awk -F'/' '{print $NF}')
  
  echo "Isleniyor: $RESOURCE_NAME"
  
  az tag update 
    --resource-id "$RESOURCE_ID" 
    --operation merge 
    --tags 
      Environment="$ENVIRONMENT" 
      Team="$TEAM" 
      CostCenter="$COST_CENTER" 
      Project="$PROJECT" 
      ManagedBy="azure-cli" 
      LastTagged="$(date -u +%Y-%m-%d)" 
    2>/dev/null && echo "  OK: $RESOURCE_NAME" || echo "  HATA: $RESOURCE_NAME"
done

echo "Etiketleme tamamlandi."

GCP Üzerinde Label Yönetimi

GCP’de “tag” yerine “label” kullanılıyor, ama konsept aynı. Önemli fark: GCP label key ve value’ları lowercase ve belirli formatlara uygun olmak zorunda.

#!/bin/bash
# gcp_label_manager.sh - GCP instance labellarini yonet

PROJECT_ID="my-gcp-project"
ZONE="europe-west1-b"

# GCP label kuralları: sadece lowercase, rakam, tire kullanılabilir
ENVIRONMENT="prod"
TEAM="data-engineering"
COST_CENTER="cc-2024-data"

# Tüm instance'ları listele ve label ekle
gcloud compute instances list 
  --project="$PROJECT_ID" 
  --format="value(name,zone)" | while IFS=$'t' read -r INSTANCE_NAME INSTANCE_ZONE; do
  
  echo "Instance labellaniyor: $INSTANCE_NAME ($INSTANCE_ZONE)"
  
  gcloud compute instances add-labels "$INSTANCE_NAME" 
    --project="$PROJECT_ID" 
    --zone="$INSTANCE_ZONE" 
    --labels=
"environment=$ENVIRONMENT,
team=$TEAM,
cost-center=$COST_CENTER,
managed-by=gcloud,
last-labeled=$(date +%Y-%m-%d)"
  
  if [ $? -eq 0 ]; then
    echo "  Basarili: $INSTANCE_NAME"
  else
    echo "  HATA: $INSTANCE_NAME labeli yapilamadi"
  fi
done

Maliyet Raporlama Otomasyonu

Etiketler düzgün kurulunca, maliyet raporlaması çok kolaylaşıyor. AWS Cost Explorer API’yi kullanarak ekip bazlı rapor çıkaralım:

#!/bin/bash
# cost_report_by_team.sh - Ekip bazinda aylik maliyet raporu

START_DATE=$(date -d "first day of last month" +%Y-%m-%d 2>/dev/null || 
             date -v1d -v-1m +%Y-%m-%d)
END_DATE=$(date -d "first day of this month" +%Y-%m-%d 2>/dev/null || 
           date -v1d +%Y-%m-%d)

echo "=== Ekip Bazinda Maliyet Raporu ==="
echo "Donem: $START_DATE - $END_DATE"
echo ""

# Tüm takımların listesi
TEAMS=("platform" "backend" "frontend" "data" "security")

TOTAL=0

for TEAM in "${TEAMS[@]}"; do
  COST=$(aws ce get-cost-and-usage 
    --time-period "Start=$START_DATE,End=$END_DATE" 
    --granularity MONTHLY 
    --filter "{
      "Tags": {
        "Key": "Team",
        "Values": ["$TEAM"]
      }
    }" 
    --metrics "UnblendedCost" 
    --query 'ResultsByTime[0].Total.UnblendedCost.Amount' 
    --output text 2>/dev/null)
  
  if [ -n "$COST" ] && [ "$COST" != "None" ]; then
    COST_ROUNDED=$(printf "%.2f" "$COST")
    echo "  $TEAM: $$COST_ROUNDED USD"
    TOTAL=$(echo "$TOTAL + $COST" | bc)
  else
    echo "  $TEAM: Veri yok"
  fi
done

echo ""
echo "Toplam: $$(printf '%.2f' $TOTAL) USD"
echo ""

# Etiketsiz kaynakların maliyeti
UNTAGGED_COST=$(aws ce get-cost-and-usage 
  --time-period "Start=$START_DATE,End=$END_DATE" 
  --granularity MONTHLY 
  --filter '{
    "Not": {
      "Tags": {
        "Key": "Team",
        "MatchOptions": ["ABSENT"]
      }
    }
  }' 
  --metrics "UnblendedCost" 
  --query 'ResultsByTime[0].Total.UnblendedCost.Amount' 
  --output text 2>/dev/null)

if [ -n "$UNTAGGED_COST" ]; then
  echo "UYARI - Etiketsiz kaynak maliyeti: $$(printf '%.2f' $UNTAGGED_COST) USD"
  echo "Bu kaynaklar icin etiketleme yapilmali!"
fi

Etiket Tutarlılığını Kontrol Etme

Büyük ortamlarda etiket yazım hataları sık görülür. “Prod”, “prod”, “PROD”, “production” hepsi farklı değer olarak işleniyor. Bunu önlemek için düzenli audit şart:

#!/bin/bash
# tag_audit.sh - Etiket tutarliligini denetle

AWS_REGION="eu-west-1"
REPORT_FILE="/tmp/tag_audit_$(date +%Y%m%d).txt"

echo "=== Etiket Denetim Raporu ===" > "$REPORT_FILE"
echo "Tarih: $(date)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

# Geçersiz Environment değerlerini bul
echo "--- Gecersiz Environment Degerleri ---" >> "$REPORT_FILE"

VALID_ENVS=("prod" "staging" "dev" "test")

aws ec2 describe-instances 
  --region "$AWS_REGION" 
  --query 'Reservations[*].Instances[*].[InstanceId,Tags[?Key==`Environment`].Value|[0]]' 
  --output text | while read -r INSTANCE_ID ENV_VALUE; do
  
  VALID=false
  for VALID_ENV in "${VALID_ENVS[@]}"; do
    if [ "$ENV_VALUE" == "$VALID_ENV" ]; then
      VALID=true
      break
    fi
  done
  
  if [ "$VALID" == "false" ]; then
    echo "  HATA: $INSTANCE_ID - Environment='$ENV_VALUE' gecersiz" >> "$REPORT_FILE"
  fi
done

# Zorunlu etiketleri olmayan kaynaklar
echo "" >> "$REPORT_FILE"
echo "--- Eksik Zorunlu Etiketler ---" >> "$REPORT_FILE"

MANDATORY_TAGS=("Environment" "Team" "CostCenter" "Owner")

aws ec2 describe-instances 
  --region "$AWS_REGION" 
  --query 'Reservations[*].Instances[*].[InstanceId,Tags]' 
  --output json | python3 -c "
import json, sys

data = json.load(sys.stdin)
mandatory = ['Environment', 'Team', 'CostCenter', 'Owner']

for item in data:
  for instance_data in item:
    if isinstance(instance_data, list) and len(instance_data) == 2:
      instance_id = instance_data[0]
      tags = instance_data[1] or []
      tag_keys = [t['Key'] for t in tags] if tags else []
      missing = [m for m in mandatory if m not in tag_keys]
      if missing:
        print(f'  EKSIK: {instance_id} - {missing}')
" >> "$REPORT_FILE"

cat "$REPORT_FILE"
echo ""
echo "Rapor kaydedildi: $REPORT_FILE"

Gerçek Dünya Senaryosu: Kaos’tan Düzene

Bir fintech şirketinde 200’den fazla EC2 instance’ı vardı, hiçbirinin tutarlı etiketi yoktu. Aylık bulut faturası 45.000 dolar geliyordu ve CTO “hangi proje ne harcıyor” diye soruyordu. İşte uygulanan strateji:

Birinci Hafta: Envanter çıkarma

Tüm kaynaklar listelendi, mevcut etiket durumu spreadsheet’e aktarıldı. Tag Editor ile hızlıca genel tablo çıkarıldı.

İkinci Hafta: Standartlar belirlendi

Tek sayfalık bir “Tagging Standard” dokümanı hazırlandı. Ekip liderleriyle onaylandı. Zorunlu etiketler: Environment, Team, CostCenter, Owner, Project.

Üçüncü Hafta: Toplu etiketleme

Yukarıdakine benzer bulk tagger scriptleri çalıştırıldı. Her kaynak için sorumlu ekip belirlendi ve atandı.

Dördüncü Hafta: Önleyici tedbirler

AWS Config rules aktif edildi. Terraform modülleri merkezi etiket çıktısı verecek şekilde güncellendi. CI/CD pipeline’a etiket validasyonu eklendi. SCP ile etiketsiz kaynak oluşturmak yasaklandı.

Sonuç: Bir ay içinde ekip bazlı maliyet görünürlüğü sağlandı. Dev ortamlarında AutoShutdown etiketi sayesinde gece boyunca çalışan instance’lar kapatılmaya başlandı ve %23 maliyet düşüşü yaşandı.

Etiketleme İçin Altın Kurallar

  • Standartları baştan belirle: İlk günden convention’ları netleştir, sonradan değiştirmek çok acı verir
  • Az ama öz: Her tag için bir değer olmalı, 30 tane tag kimse okumaz. 8-10 tag yeterli
  • Büyük/küçük harf tutarlılığı: Ya hep CamelCase ya hep lowercase. Karışık olursa maliyet raporları yanlış gruplar
  • Otomatikleştir: Manuel tagging hata üretir. Her zaman IaC veya deployment pipeline üzerinden etiket uygula
  • Düzenli audit: Ayda bir tag audit çalıştır, eski ve yanlış etiketleri temizle
  • Ekibi eğit: Developer’lar neden etiketlediğinizi anlamazsa kurala uymaz
  • Cost center’ı muhasebe ile eşleştir: Etiket değerleri muhasebe kodlarıyla birebir örtüşmeli
  • Etiketlenmemiş kaynağa izin verme: Organizations veya Policy seviyesinde enforce et

Sonuç

Etiketleme stratejisi, bulut maliyetlerini kontrol altına almanın ve operasyonel görünürlüğü artırmanın en temel adımı. Ama tek seferlik bir iş değil; canlı, sürekli bakım gerektiren bir süreç. Bugün 10 instance’ın var, yarın 500 olabilir ve o noktada etiketleme altyapısı olmadan maliyet yönetimi neredeyse imkansız hale geliyor.

Başlangıç için pratik önerim: Önce zorunlu etiket listeni 5-6 ile sınırla, IaC modülüne merkezi tag çıktısı ekle, mevcut kaynaklar için bulk tagger çalıştır ve AWS Config ya da Azure Policy ile enforcement koy. Bu dört adımı tamamlarsan, bulut ortamında çok daha sağlıklı bir görünürlük elde edersin. Gerisi kademeli olarak gelir.

Maliyet raporlarının teamize göre net görünmesi, güvenlik denetimlerinin dakikalar içinde tamamlanması ve “bu instance ne işe yarıyor ki?” sorusunun ortadan kalkması, iyi bir etiketleme stratejisinin somut getirileri. Bunu erken kuranlar, büyüdükçe bunun değerini çok daha iyi anlıyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir