
Wed Sep 23 2026

Geçen yıl bir gece yarısı Slack'ten bir mesajla uyanmıştım: "Prod'da API keylerimiz GitHub'a pushlandı, hemen rotate etmemiz lazım!" 😱
O gece 3 saatimizi secret rotation, log temizliği ve müşteri haber verme ile geçirdik. Sorun? Bir junior geliştirici .env dosyasını yanlışlıkla commit'lemişti. Ama asıl sorun aracı yanlış seçmemizdi — local geliştirme için dotenv kullanıyorduk, production'da ise hiçbir merkezi secret yönetimi yoktu.
Bu hikayenin morali basit: gizli anahtar ve yapılandırma yönetiminde yanlış araç seçimi, küçük bir hatayı felakete çevirir. 🎯
| Risk | Ne Olur? |
|---|---|
| 🔓 Hardcoded secret | Git history'de kalır, herkes görür |
| 🔄 Rotation yok | Sızan key yıllarca geçerli kalır |
| 📋 Audit trail eksik | Kim ne zaman erişti? Bilemezsiniz |
| ⚖️ Compliance ihlali | SOC2, ISO, KVKK cezaları |
Hazırsan hadi başlayalım — doğru aracı doğru yerde kullanarak hem güvenli hem de developer-friendly bir yapı kuracağız. 🚀
Hadi iki hizmeti yan yana koyalım ve ne zaman hangisini seçeceğimize hızlıca karar verelim 👇
| Özellik | Secrets Manager | Parameter Store |
|---|---|---|
| Birincil hedef | Hassas veriler (şifreler, API key'ler, DB credential'ları) | Yapılandırma verileri + basit secret'lar |
| Otomatik rotasyon | ✅ Yerleşik (Lambda ile) | ❌ Manuel / custom çözüm gerekir |
| Hiyerarşik yapı | ❌ Flat (düzeyli değil) | ✅ /prod/db/password gibi path desteği |
| Şifreleme | Her secret ayrı KMS key ile (varsayılan AWS managed) | Tek KMS key (paylaşımlı) veya AWS managed |
| Versiyonlama | ✅ Otomatik, her rotation'da yeni versiyon | ✅ Basit versiyon numaraları |
| Cross-account erişim | ✅ Resource policy ile kolay | ✅ Policy ile mümkün ama daha zordur |
| Maliyet | Secret başına $0.40/ay + API call ücreti | Ücretsiz tier (10k parametre) + Standart tier $0.05/param/ay |
Secrets Manager seç 👇
Parameter Store seç 👇
/prod/api/timeout, /staging/api/timeoutSecret mi, config mi?
- Secret → Secrets Manager
- Config → Parameter Store
- İkisi bir arada → Parameter Store (SecureString) başlangıç için yeterli olabilir, sonra büyürse migrate et
Her ikisi de IAM policy ile erişim kontrolü destekler, her ikisi de KMS ile şifreler. Fark odak noktasında ve ek özelliklerde yatar.
Hazırsan sıradaki bölümde Secrets Manager'ı nasıl kurup ilk secret'ımızı oluşturacağımızı görelim 🚀
Serverless dünyasına adım attığında ilk karşılaştığın sürpriz genelde fatura olur 😅 "Ücretsiz katman var ya, neden ödüyorum?" diye soruyorsun kendine. Gelin beraber katman katman açalım bu onion'ı, neye para verdiğimizi anlayalım.
Her üç büyük sağlayıcı (AWS Lambda, Google Cloud Functions, Azure Functions) temelde aynı üç metrik üzerinde faturalandırır:
| Bileşen | Ne Anlama Gelir? | Ölçü Birimi |
|---|---|---|
| İstek Sayısı | Fonksiyonun kaç kez tetiklendiği | Milyon istek başına $ |
| Süre (Duration) | Kodun ne kadar çalıştığı | GB-saniye (GB-s) |
| Hafıza (Memory) | Fonksiyona ayırdığın RAM miktarı | GB (süre ile çarpılır) |
Küçük bir not: Azure'da "Execution Time" olarak geçer, AWS'de "GB-seconds", GCP'de "GHz-seconds" — isimler farklı, mantık aynı ✅
Hadi üç farklı ölçekte bir HTTP API fonksiyonu varsayalım:
İstek maliyeti (AWS Lambda örneği):
- İlk 1M istek: $0.00 (ücretsiz katman)
- Kalan: 0 istek → $0.00
Süre maliyeti:
- 100.000 × 0.2 s × 0.5 GB = 10.000 GB-s
- İlk 400.000 GB-s: $0.00 (ücretsiz katman)
- Toplam: $0.00 🎉
Sonuç: Küçük projelerde hiç para ödemezsin. Ücretsiz katmanlar harika bir "deneme ve öğren" alanı sunar.
İstek maliyeti:
- İlk 1M: $0.00
- Kalan 4M × $0.20/M = $0.80
Süre maliyeti:
- 5.000.000 × 0.2 s × 0.5 GB = 500.000 GB-s
- İlk 400.000 GB-s: $0.00
- Kalan 100.000 GB-s × $0.0000166667 = $1.67
💰 Toplam: ~$2.47 / ay
Ne oluyor burada? İstek maliyeti artıyor ama hâlâ kafe bir kahve fiyatında kalıyorsun ☕
İstek maliyeti:
- İlk 1M: $0.00
- Kalan 49M × $0.20/M = $9.80
Süre maliyeti:
- 50.000.000 × 0.2 s × 0.5 GB = 5.000.000 GB-s
- İlk 400.000 GB-s: $0.00
- Kalan 4.600.000 GB-s × $0.0000166667 = $76.67
💰 Toplam: ~$86.47 / ay
Dikkat! Burada süre maliyeti istek maliyetini geride bırakıyor. Hafıza artırırsan (ör. 1024 MB) süre maliyeti 2 katına çıkar ama kodun daha hızlı çalışabilir — bu bir optimizasyon oyunu 🎮
Kendine bir Excel/Google Sheets hücresi yapıştır, parametreleri değiştir, anında gör:
# Değişkenler
ISTEK_SAYISI = 5_000_000 # ayda kaç istek?
ORTALAMA_SURE_SN = 0.2 # saniye cinsinden
HAZIFA_GB = 0.5 # GB cinsinden (512 MB = 0.5)
# Sabitler (AWS Lambda 2024 fiyatları - bölgeye göre değişir)
UCRETSIZ_ISTEK = 1_000_000
UCRETSIZ_GB_S = 400_000
ISTEK_FIYATI = 0.20 / 1_000_000 # $ per istek
GB_S_FIYATI = 0.0000166667 # $ per GB-s
# Hesaplama
ucretli_istek = max(0, ISTEK_SAYISI - UCRETSIZ_ISTEK)
toplam_gb_s = ISTEK_SAYISI * ORTALAMA_SURE_SN * HAZIFA_GB
ucretli_gb_s = max(0, toplam_gb_s - UCRETSIZ_GB_S)
aylik_maliyet = (ucretli_istek * ISTEK_FIYATI) + (ucretli_gb_s * GB_S_FIYATI)
Bu formülle ne kazanırsın?
HAZIFA_GB değişir → süre azalabilir (daha fazla CPU) → ORTALAMA_SURE_SN düşerAyda 10M+ istek ve/veya ortalama süre > 500ms ise: Serverless hâlâ ucuzdur ama dedicated container (Cloud Run, Fargate, App Service) veya reserved instances ile %30-50 tasarruf edebilirsin.
| Senaryo | Tavsiye |
|---|---|
| < 1M istek/ay, kısa süre | Serverless — ücretsiz katman yeter ✅ |
| 1M–10M istek, değişken trafik | Serverless — ödeme yaptığın kadar kullanırsın 👍 |
| > 10M istek, sabit/yüksek trafik | Container / VM — reserved capacity al 💡 |
| Çok uzun süreli işler (dakikalar) | Serverless değil — timeout ve maliyet riski ⛔ |
AWS Lambda'da Provisioned Concurrency açarsan cold start gider ama saniyede $0.0000041667/GB ek maliyet getirir. 512 MB için ayda ~$1.50 boşta bile yakar. Küçük/orta projelerde açma, trafik öngörülebilir hale gelene kadar bekle ⏳
Özetle: Küçük başla, ücretsiz katmanı tüket, metriklerini izle (CloudWatch / Cloud Monitoring / Azure Monitor). Maliyet grafiğin doğrusal artıyorsa serverless uygun. Eğrisel (üstel) artmaya başladığında alternatifleri değerlendirmeye başla 🎯
İki hizmeti (Secrets Manager & Parameter Store) yan yana koyalım ve hangi yöntemle daha az kod / yapılandırma gerektiğini görelim 🎯
| Hizmet | Python (boto3) | Node.js (AWS SDK v3) | Go (plaintext) |
|---|---|---|---|
| Secrets Manager | python<br>import boto3<br>client = boto3.client('secretsmanager')<br>resp = client.get_secret_value(SecretId='prod/db/password')<br>secret = resp['SecretString']<br> |
javascript<br>const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');<br>const client = new SecretsManagerClient({ region: 'us-east-1' });<br>const data = await client.send(new GetSecretValueCommand({ SecretId: 'prod/db/password' }));<br>const secret = data.SecretString;<br> |
plaintext<br>svc := secretsmanager.New(session.New())<br>out, _ := svc.GetSecretValue(&secretsmanager.GetSecretValueInput{SecretId: aws.String("prod/db/password")})<br>secret := *out.SecretString<br> |
| Parameter Store | python<br>import boto3<br>ssm = boto3.client('ssm')<br>param = ssm.get_parameter(Name='/prod/db/password', WithDecryption=True)<br>value = param['Parameter']['Value']<br> |
javascript<br>const { SSMClient, GetParameterCommand } = require('@aws-sdk/client-ssm');<br>const client = new SSMClient({ region: 'us-east-1' });<br>const data = await client.send(new GetParameterCommand({ Name: '/prod/db/password', WithDecryption: true }));<br>const value = data.Parameter.Value;<br> |
plaintext<br>svc := ssm.New(session.New())<br>out, _ := svc.GetParameter(&ssm.GetParameterInput{Name: aws.String("/prod/db/password"), WithDecryption: aws.Bool(true)})<br>value := *out.Parameter.Value<br> |
Ne oluyor burada?
WithDecryption parametresi zorunlu (Secrets Manager’da varsayılan şifreli döner).| Hizmet | Komut (bash) |
|---|---|
| Secrets Manager | bash<br>aws secretsmanager get-secret-value --secret-id prod/db/password --query SecretString --output text<br> |
| Parameter Store | bash<br>aws ssm get-parameter --name /prod/db/password --with-decryption --query Parameter.Value --output text<br> |
İpucu: --query ile sadece değeri alıp pipeline’larda temiz çıktı elde edersiniz ✅
Secrets Manager gizli anahtarı oluşturma
resource "aws_secretsmanager_secret" "db_password" {
name = "prod/db/password"
description = "Veritabanı şifresi"
}
resource "aws_secretsmanager_secret_version" "db_password_version" {
secret_id = aws_secretsmanager_secret.db_password.id
secret_string = var.db_password # CI/CD'den gelen gizli değer
}
Parameter Store parametresi oluşturma (SecureString)
resource "aws_ssm_parameter" "db_password" {
name = "/prod/db/password"
type = "SecureString"
value = var.db_password
description = "Veritabanı şifresi (Parameter Store)"
}
Ne fark var?
secret + secret_version) → daha fazla blok.aws_ssm_parameter) → daha az yapılandırma.AWS::SecretsManager::Secret + AWS::SecretsManager::SecretTargetAttachment (isteğe bağlı).AWS::SSM::Parameter (tek kaynak).GetSecretValue / GetParameter çağrılarını yeniden deneme (retry) ve önbellekleme ile sarmalayın ❗️secret_string / value alanlarına değişken (var.xxx) verin, hard‑code etmeyin.--output text ile alıp export DB_PASS=$(aws ...) şeklinde ortam değişkenine atayın 🚀Özet:
Hangi yöntem sizin işinize gelirse onu seçin, ikisi de production‑ready ✅
Hazırsan bu konuyu üç ana başlık altında hızlıca özetleyelim: şifreleme seçenekleri, anahtar rotasyonu ve ince taneli IAM kontrolü. Sonunda da PCI‑DSS ve HIPAA gibi standartlar için hangi servisin avantajlı olduğunu göreceksin. 🎯
| Sağlayıcı | KMS Yönetimi (Managed) | Müşteri Yönetili Anahtar (CMK / Customer‑Managed Key) |
|---|---|---|
| AWS KMS | Varsayılan AWS‑owned anahtarlar, şeffaf şifreleme. | Kendi CMK oluşturursun, Key Policy ve Grants ile tam kontrol. |
| Azure Key Vault | Microsoft‑managed anahtarlar, otomatik şifreleme. | Customer‑managed keys (CMK) – HSM‑backed (Premium) veya software‑backed (Standard). |
| GCP Cloud KMS | Google‑managed anahtarlar, varsayılan şifreleme. | Customer‑managed encryption keys (CMEK) – proje/bölge bazında oluşturulur. |
Ne zaman hangisini seçmelisin?
| Sağlayıcı | Varsayılan Rotasyon | Manuel / Özel Rotasyon Desteği |
|---|---|---|
| AWS KMS | Yıllık (365 gün) otomatik – etkinleştirilebilir. | EnableKeyRotation API ile aç/kapat; özel dönem için CreateKey + ScheduleKeyDeletion kombinasyonu. |
| Azure Key Vault | 90 gün (Premium HSM) / 365 gün (Standard) – otomatik. | Rotation Policy (JSON) ile özel aralık (ör. 30 gün) tanımlanabilir. |
| GCP Cloud KMS | 90 gün varsayılan – otomatik. | RotationSchedule (cron‑style) ile gün/hafta/ay bazında özelleştirme. |
Pratik ipucu: Rotasyon politikasını IaC (Terraform, Bicep, Deployment Manager) ile kodla; böylece auditörler “rotasyon etkin mi?” sorusuna tek bir dosya ile cevap verebilirsin. ✅
AWS – Key Policy + IAM Policy + Grants.
Encrypt, Decrypt sadece belirli bir rol için).Azure – RBAC rolleri (Key Vault Crypto User, Key Vault Secrets User) + Access Policies (eski model) + Azure Policy ile zorunlu şifreleme.
GCP – IAM Roles (roles/cloudkms.cryptoKeyEncrypterDecrypter, roles/cloudkms.admin) + Conditions (ör. request.time < timestamp('2025-12-31T00:00:00Z')).
Örnek: AWS Key Policy (JSON)
{
"Version": "2012-10-17",
"Id": "key-policy-example",
"Statement": [
{
"Sid": "AllowAdmin",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:role/AdminRole" },
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowAppEncrypt",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:role/AppRole" },
"Action": [ "kms:Encrypt", "kms:GenerateDataKey" ],
"Resource": "*"
}
]
}
Nasıl çalışıyor?
AdminRole anahtar yaşam döngüsü yönetimini (oluşturma, silme, rotasyon) yapabilir.AppRole sadece veri şifreleme/anahtar üretme yetkisine sahip; Decrypt yetkisi yok → veri sızıntısı riski azalır.| Kriter | AWS KMS | Azure Key Vault | GCP Cloud KMS |
|---|---|---|---|
| FIPS 140‑2 Level 2/3 | ✅ (HSM‑backed CMK) | ✅ (Premium HSM) | ✅ (Cloud HSM) |
| Otomatik Rotasyon + Audit Log | ✅ (CloudTrail) | ✅ (Azure Monitor / Log Analytics) | ✅ (Cloud Audit Logs) |
| İnce Taneli IAM + Condition | ✅ (Key Policy + IAM Conditions) | ✅ (RBAC + Azure Policy) | ✅ (IAM Conditions) |
| PCI‑DSS 3.2.1 Req. 3.5/3.6 | Avantajlı – yönetilen HSM + rotasyon + loglama tek konsolda. | Avantajlı – Azure Policy ile “şifreleme zorunlu” kuralı merkezi. | Avantajlı – CMEK + VPC Service Controls ile veri sızıntısı engelleme. |
| HIPAA “Encryption at Rest & In Transit” | ✅ (TLS 1.2+ + KMS) | ✅ (TLS + Managed HSM) | ✅ (TLS + CMEK) |
Özet:
Hadi şimdi terraform / bicep / deployment manager şablonlarınızda bu politikaları kodlayalım ve gece rahat uyuyalım! 🚀
Hazırsan başlayalım 🚀
Aşağıdaki tabloda satırlar = yaygın kullanım senaryoları, sütunlar = popüler secret/konfig yönetim hizmetleri.
Her hücrede senin ihtiyacına en uygun seçeneği bir bakışta görebilirsin.
| Senaryo \ Hizmet | HashiCorp Vault | AWS Secrets Manager | Azure Key Vault | GCP Secret Manager | Kubernetes Secrets | .env / Dosya | ConfigMap |
|---|---|---|---|---|---|---|---|
| Veritabanı şifreleri | ✅ Önerilen | ✅ Önerilen | ✅ Önerilen | ✅ Önerilen | 🔄 Alternatif (sadece cluster içi) | ❌ Uygun Değil | ❌ Uygun Değil |
| API anahtarları (3rd‑party) | ✅ Önerilen | ✅ Önerilen | ✅ Önerilen | ✅ Önerilen | 🔄 Alternatif | ❌ Uygun Değil | ❌ Uygun Değil |
| Özellik bayrakları (feature flags) | 🔄 Alternatif (dynamic secrets) | 🔄 Alternatif | 🔄 Alternatif | 🔄 Alternatif | ✅ Önerilen (ConfigMap/CRD) | 🔄 Alternatif (basit projeler) | ✅ Önerilen |
| Ortam değişkenleri (env vars) | 🔄 Alternatif (inject via sidecar) | 🔄 Alternatif | 🔄 Alternatif | 🔄 Alternatif | ✅ Önerilen (pod env) | ✅ Önerilen (local/dev) | ✅ Önerilen (non‑secret) |
| Sertifika / TLS anahtarları | ✅ Önerilen (PKI engine) | 🔄 Alternatif (import) | 🔄 Alternatif (import) | 🔄 Alternatif (import) | 🔄 Alternatif (secret type tls) | ❌ Uygun Değil | ❌ Uygun Değil |
| Kısa ömürlü token / OTP | ✅ Önerilen (dynamic secrets) | ❌ Uygun Değil | ❌ Uygun Değil | ❌ Uygun Değil | ❌ Uygun Değil | ❌ Uygun Değil | ❌ Uygun Değil |
Nasıl kullanacaksın?
Bu matrisle karar verme süren dakikadan saniyeye düşer ⚡️
Kolay gelsin! 🚀
Hazırsan boto3 ile AWS Secrets Manager'a nasıl bağlanıp, gizli anahtar oluşturup, okur ve rotasyon tetikleriz buna birlikte bakalım 🚀
Üretim ortamında veritabanı şifrelerini, API anahtarlarını veya herhangi bir hassas veriyi kodda saklamak büyük risk. Secrets Manager bunu merkezi, şifreli ve denetlenebilir hale getirir.
pip install boto3
AWS kimlik bilgileriniz
~/.aws/credentialsveya ortam değişkenlerinde tanımlı olmalı.
Aşağıdaki script tek dosyada üç temel operasyonu gösterir:
create_secret → yeni gizli anahtar oluştururget_secret_value → gizli anahtarı okur (önbellekleme ile)rotate_secret → rotasyonu manuel tetiklerimport os
import json
import time
import logging
from functools import lru_cache
from typing import Optional, Dict, Any
import boto3
from botocore.exceptions import ClientError, BotoCoreError
# ------------------------------------------------------------
# Loglama ayarı — üretimde JSON formatter tercih edin
# ------------------------------------------------------------
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(levelname)-8s | %(message)s",
)
logger = logging.getLogger(__name__)
# ------------------------------------------------------------
# Sabitler — ortam değişkeninden almak en iyisidir
# ------------------------------------------------------------
SECRET_NAME = os.getenv("SECRET_NAME", "prod/db/credentials")
REGION_NAME = os.getenv("AWS_REGION", "eu-central-1")
DESCRIPTION = "Veritabanı bağlantı bilgileri — otomatik rotasyonlu"
KMS_KEY_ID = os.getenv("KMS_KEY_ID") # None → AWS managed key
# ------------------------------------------------------------
# Secrets Manager client — singleton pattern
# ------------------------------------------------------------
_session = boto3.session.Session()
_client = _session.client(service_name="secretsmanager", region_name=REGION_NAME)
# ------------------------------------------------------------
# 1️⃣ Gizli anahtar oluşturma (idempotent)
# ------------------------------------------------------------
def create_secret(
name: str = SECRET_NAME,
secret_value: Optional[Dict[str, str]] = None,
description: str = DESCRIPTION,
kms_key_id: Optional[str] = KMS_KEY_ID,
) -> Dict[str, Any]:
"""
Secret yoksa oluşturur, varsa güncellemez.
`secret_value` dict olarak verilir; JSON string'e dönüştürülür.
"""
if secret_value is None:
secret_value = {
"username": "admin",
"password": "SuperSecretPass123!", # Gerçekte güvenli üretilmeli
"host": "db.example.com",
"port": "5432",
"dbname": "appdb",
}
try:
logger.info("Secret oluşturuluyor → %s", name)
response = _client.create_secret(
Name=name,
Description=description,
SecretString=json.dumps(secret_value),
KmsKeyId=kms_key_id,
Tags=[
{"Key": "Environment", "Value": "production"},
{"Key": "ManagedBy", "Value": "python-script"},
],
)
logger.info("✅ Secret oluşturuldu: %s", response["ARN"])
return response
except _client.exceptions.ResourceExistsException:
logger.warning("⚠️ Secret zaten mevcut: %s", name)
return {"ARN": _client.describe_secret(SecretId=name)["ARN"]}
except (ClientError, BotoCoreError) as exc:
logger.exception("❌ Secret oluşturulamadı: %s", exc)
raise
# ------------------------------------------------------------
# 2️⃣ Gizli anahtarı okuma — LRU önbellek ile
# ------------------------------------------------------------
@lru_cache(maxsize=4)
def get_secret_value(name: str = SECRET_NAME, version_stage: str = "AWSCURRENT") -> Dict[str, str]:
"""
Secrets Manager'dan gizli anahtarı çeker ve **dict** döner.
`lru_cache` sayesinde aynı secret tekrar istenirse ağ çağrısı yapmaz.
⚠️ Rotasyon sonrası cache'i temizlemek için `get_secret_value.cache_clear()` çağrın.
"""
try:
logger.info("Secret okunuyor → %s (stage: %s)", name, version_stage)
response = _client.get_secret_value(SecretId=name, VersionStage=version_stage)
secret_string = response["SecretString"]
logger.debug("Ham secret string: %s", secret_string)
return json.loads(secret_string)
except _client.exceptions.ResourceNotFoundException:
logger.error("❌ Secret bulunamadı: %s", name)
raise
except (ClientError, BotoCoreError, json.JSONDecodeError) as exc:
logger.exception("❌ Secret okunamadı: %s", exc)
raise
# ------------------------------------------------------------
# 3️⃣ Rotasyon tetikleme (manuel)
# ------------------------------------------------------------
def rotate_secret(name: str = SECRET_NAME) -> Dict[str, Any]:
"""
Secrets Manager'ın **rotation lambda**'sını manuel tetikler.
Otomatik rotasyon zamanlaması (örn. 30 günde bir) ayrı ayarlanır.
"""
try:
logger.info("🔁 Rotasyon tetikleniyor → %s", name)
response = _client.rotate_secret(SecretId=name)
logger.info("✅ Rotasyon başlatıldı: VersionId=%s", response["VersionId"])
# Cache'i temizle ki sonraki okuma yeni versiyonu alsın
get_secret_value.cache_clear()
logger.debug("🗑️ LRU cache temizlendi")
return response
except _client.exceptions.ResourceNotFoundException:
logger.error("❌ Secret bulunamadı, rotasyon yapılamaz: %s", name)
raise
except (ClientError, BotoCoreError) as exc:
logger.exception("❌ Rotasyon hatası: %s", exc)
raise
# ------------------------------------------------------------
# 🎬 Demo / CLI entry point
# ------------------------------------------------------------
if __name__ == "__main__":
print("\n" + "=" * 60)
print("🛠 Secrets Manager Demo Başlıyor")
print("=" * 60 + "\n")
# 1️⃣ Oluştur / zaten varsa atla
create_secret()
# 2️⃣ Oku (ilk çağrı ağa gider)
secret = get_secret_value()
print(f"\n🔐 Okunan secret (ilk çağrı):\n{json.dumps(secret, indent=2, ensure_ascii=False)}")
# 3️⃣ Tekrar oku (cache'den gelir — loglarda ağ çağrısı yok)
_ = get_secret_value()
logger.info("📦 İkinci okuma cache'den servis edildi")
# 4️⃣ Rotasyon tetikle (isteğe bağlı — Lambda hazırsa)
# rotate_secret() # Yorum satırından kaldırın eğer rotation lambda'nız varsa
print("\n" + "=" * 60)
print("✅ Demo tamamlandı")
print("=" * 60 + "\n")
| Konu | Ne Yapıyor? |
|---|---|
| Singleton client | _client bir kere oluşturulur, her çağrıda yeniden bağlanmaz 🚀 |
create_secret idempotent |
ResourceExistsException yakalanır, script tekrar çalıştırılabilir |
@lru_cache |
Aynı secret tekrar istenirse ağ çağrısı yapmaz — latency & cost düşer 💰 |
cache_clear() |
Rotasyon sonrası eski cache temizlenir, yeni versiyon okunur 🔁 |
| Hata yakalama | ClientError, BotoCoreError, ResourceNotFoundException ayrı ayrı loglanır 🛡 |
| Tip ipuçları | Dict[str, str] dönüş tipi sayesinde IDE autocomplete çalışır ✨ |
logger.debug sadece demo içindir, prod'da kapatın ⛔KMS_KEY_ID vererek kendi anahtarınızla şifreleyin 🔐secretsmanager:GetSecretValue + DescribeSecret verin 🎯RotationRules ile 30/60/90 günlük zamanlama ayarlayın ⏰lru_cache sonsuzdur; prod'da cachetools.TTLCache veya custom wrapper ile TTL (örn. 5 dk) ekleyin ⏱AWSCURRENT / AWSPREVIOUS stage'leri ile rollback kolaydır 🔙export SECRET_NAME="prod/db/credentials"
export AWS_REGION="eu-central-1"
python secrets_demo.py
Çıktıda ilk okuma ağa gider, ikinci okuma cache'den gelir. Rotasyon lambda'nız hazırsa rotate_secret() satırını açın ve versiyon değişimini izleyin 🎉
Kısa özet: boto3 + lru_cache + doğru hata yakalama = güvenli, hızlı ve tekrar denetlenebilir secret yönetimi. Bir sonraki bölümde bu yapıyı FastAPI / Django içine nasıl entegre edeceğimize bakacağız 😉
Hazırsan başlayalım 🚀
AWS Systems Manager Parameter Store, hiyerarşik yapıda (ör. /prod/db/password) parametre tutmamızı sağlar.
İki ana tür vardır:
Uygulama ayağa kalkarken bu parametreleri tek seferde çekip ortam değişkenlerine atmak en pratik yoludur.
aws ssm get-parameters-by-path \
--path "/prod/" \
--recursive \
--with-decryption
--recursive → alt yolları da getirir--with-decryption → SecureString’leri çözerek dönerimport os
import boto3
def load_config(path: str = "/prod/") -> None:
"""
Parameter Store'dan hiyerarşik parametreleri çeker,
SecureString'leri çözer ve os.environ'a yazar.
"""
client = boto3.client("ssm")
paginator = client.get_paginator("get_parameters_by_path")
for page in paginator.paginate(Path=path, Recursive=True, WithDecryption=True):
for param in page["Parameters"]:
# Parametre adı: /prod/db/password -> ortam değişkeni: PROD_DB_PASSWORD
env_key = param["Name"].lstrip("/").replace("/", "_").upper()
os.environ[env_key] = param["Value"]
print(f"✅ {env_key} ayarlandı")
if __name__ == "__main__":
load_config()
Ne oluyor burada?
get_parameters_by_path + Recursive=True → /prod/ altındaki tüm parametreleri getirir.WithDecryption=True → SecureString’ler otomatik çözülür (KMS yetkisi varsa).PROD_DB_PASSWORD gibi ortam değişkeni formatına çevirip os.environ’a atarız.load_config() çağrılır → kodun her yerinden os.getenv("PROD_DB_PASSWORD") ile erişiriz.ssm:GetParametersByPath + kms:Decrypt (SecureString için) izni verilmeli./prod/ yoluna erişim verin, * vermeyin.Artık konfigürasyon merkezi, güvenli ve tek noktadan yönetilebilir 🎉
Hazırsan bu aşamada bir adım ileri gidelim 🚀. Basit yapılandırmadan çıkıp, production‑ready ve güvenli bir mimari kurmak için şu stratejileri deneyebilirsin:
Secrets Manager + Parameter Store kombinasyonu 🔐
Cost Explorer ile etiket tabanlı maliyet takibi 💰
Environment, Team, Project etiketleri ekle.CloudTrail entegrasyonu ile güvenlik denetimi 🛡️
DeleteSecret çağrısı) yap ve Slack/e‑posta bildirimi gönder.Infrastructure as Code (IaC) ile tekrarlanabilir dağıtımlar 🛠️
Gözlemleme ve alarm 📈
Bu yolculukta küçük adımlarla büyük farklar yarattık. Şimdi sıra sende: bir proje seç, yukarıdaki ipuçlarından en az ikisini uygula ve farkı kendin hisset. Hata yapmaktan korkma — her hata bir öğrenme fırsatıdır. Keşfet, dene, paylaş! 🚀✨
Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.
All rights reserved