Skip to content
~/sph.sh

Multi-Account AWS Mimarisi: Ölçeklenebilir Event-Driven Sistemler

Dayanıklı event-driven sistemler için multi-account AWS mimari pattern'lerini öğrenin. Hesap yapısı, EventBridge routing, servisler arası iletişim ve dağıtık sistemlerde operasyonel zorlukları keşfedin.

Single-Account Mimarisinin Sınırları

Multi-account AWS mimarisi, organizasyonlar belirli ölçek ve karmaşıklık eşiklerine ulaştığında gerekli hale gelir. Bu pattern'i ne zaman ve nasıl implement edeceğinizi anlamak, sürdürülebilir büyüme ile operasyonel kaos arasındaki farkı belirleyebilir.

Dokuz geliştirme takımının aynı AWS hesabına deploy ettiği çok servisli bir platform düşünün. Bu yaklaşım küçük organizasyonlar için işe yarayabilen, ölçek arttıkça çeşitli kritik zorluklar yaratır.

Yaygın Single-Account Anti-Pattern'leri

Birden fazla takımın aynı AWS hesabını paylaşması kaynak çakışmalarına, güvenlik sorunlarına ve operasyonel karmaşıklığa yol açar. Örnek bir anti-pattern konfigürasyonu:

yaml
# "Her-şey-tek-hesapta" anti-patternResources:  CustomerWebLambda:    Type: AWS::Lambda::Function    Properties:      FunctionName: quickgrocer-customer-web-api      # Umarım başka kimsenin bu role ihtiyacı yoktur...      Role: !GetAtt SharedLambdaRole.Arn
  DriverAppLambda:    Type: AWS::Lambda::Function    Properties:      FunctionName: quickgrocer-driver-app-api      # Aynı rol, çünkü kimin least privilege için zamanı var?      Role: !GetAtt SharedLambdaRole.Arn
  OrderProcessingLambda:    Type: AWS::Lambda::Function    Properties:      FunctionName: quickgrocer-order-processing      # Tahmin ettiniz...      Role: !GetAtt SharedLambdaRole.Arn
  SharedLambdaRole:    Type: AWS::IAM::Role    Properties:      AssumeRolePolicyDocument:        # Herkes her şeyi alıyor!        Version: '2012-10-17'        Statement:          - Effect: Allow            Principal:              Service: lambda.amazonaws.com            Action: 'sts:AssumeRole'      ManagedPolicyArns:        # "Sonra düzeltiriz" policy'si        - arn:aws:iam::aws:policy/PowerUserAccess

Bu yaklaşım birkaç sorun yaratır:

  1. Patlama Yarıçapı: Bir takımın kaynak değişiklikleri diğerlerini etkileyebilir
  2. İzin Karmaşıklığı: IAM policy'leri denetlenmesi zor hale gelir
  3. Maliyet Atfı: Takım veya servis başına kaynak kullanımını izlemek zorlaşır
  4. Deployment Çakışmaları: Paylaşılan CI/CD pipeline'lar darboğaz yaratır
  5. Güvenlik Sınırları: Tüm takımlar aynı güvenlik çevresinde çalışır

Multi-Account Mimari Paterni

Multi-account mimarisi, merkezi altyapı üzerinden kontrollü iletişim sağlayarak servisler arasında net sınırlar sunar. Etkili bir yapı:

Merkezi Identity Service: Güven Sınırımız

Her multi-account mimarisinin authentication ve authorization için tek doğruluk kaynağına ihtiyacı var. Identity Service'imizi tüm servislerin token'ları ve izinleri doğruladığı tek nokta olarak inşa ettik. Kullandığımız gerçek trust policy:

json
{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "AllowIdentityServiceToAssumeRole",      "Effect": "Allow",      "Principal": {        "AWS": "arn:aws:iam::000000000000:role/identity-service-validator"      },      "Action": "sts:AssumeRole",      "Condition": {        "StringEquals": {          "sts:ExternalId": "${IDENTITY_SERVICE_EXTERNAL_ID}",          "aws:PrincipalOrgID": "o-quickgrocer123"        },        "IpAddress": {          "aws:SourceIp": [            "10.0.0.0/8"  // VPC CIDR aralığı          ]        }      }    }  ]}

Bu merkezileşme tutarlı kimlik doğrulama sağlarken dağıtık JWT validation karmaşıklığını önler.

EventBridge: Sinir Sistemi

Servislerin birbirini doğrudan çağırması yerine (ve bağımlılık kabusunu yaratması), EventBridge'i iletişim omurgamız olarak kullandık. Her hesap merkezi event bus'a event'ler yayınlıyor, o da ilgilenen subscriber'lara yönlendiriyor.

Order processing akışımızdan gerçek bir EventBridge rule:

typescript
// Cross-account event routing için CDK koduimport { Rule, EventBus } from 'aws-cdk-lib/aws-events';import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
const orderPlacedRule = new Rule(this, 'OrderPlacedRule', {  eventBus: EventBus.fromEventBusArn(    this,    'CentralEventBus',    'arn:aws:events:us-east-1:121212121212:event-bus/central-bus'  ),  eventPattern: {    source: ['quickgrocer.customer-web'],    detailType: ['Order Placed'],    detail: {      orderStatus: ['PENDING'],      paymentMethod: ['CREDIT_CARD', 'DEBIT_CARD', 'APPLE_PAY']    }  },  targets: [    new LambdaFunction(orderProcessingLambda, {      retryAttempts: 2,      deadLetterQueue: orderProcessingDLQ,      maxEventAge: Duration.hours(2)    })  ]});
// Cross-account event publishing için izinlerconst centralBusArn = 'arn:aws:events:us-east-1:121212121212:event-bus/central-bus';const publishPolicy = new PolicyStatement({  effect: Effect.ALLOW,  actions: ['events:PutEvents'],  resources: [centralBusArn],  conditions: {    StringEquals: {      'events:detail-type': [        'Order Placed',        'Order Updated',        'Order Cancelled'      ]    }  }});

Event-Driven Veri Akış Desenleri

Event-driven mimari servisler arası veri akışının dikkatli orkestrasyonunu gerektirir. Abonelik yükseltme iş akışı, event'lerin birden fazla hesapta durum değişikliklerini nasıl koordine ettiğini gösterir.

Cross-Service Veri Senkronizasyonu

Abonelik durumu hesap veritabanları arasında doğrudan erişim olmadan birden fazla serviste kullanılabilir olmalı. Event-sourced state replication ve local cache ile çözülür.

typescript
// Subscription Service - authoritative event yayınlarexport class SubscriptionService {  async upgradeSubscription(userId: string, planId: string) {    const subscription = await this.subscriptionRepo.create({      userId, planId, status: 'ACTIVE',      startDate: new Date(), features: this.getFeaturesByPlan(planId)    });    await this.eventPublisher.publish({      source: '"quickgrocer".subscription-service',      detailType: 'Subscription Activated',      detail: { userId, subscriptionId: subscription.id, plan: { id: planId, features: ['priority_delivery'] } }    });    return subscription;  }}
// Order Processor - local subscription cache ileexport class OrderProcessor {  private subscriptionCache = new Map<string, SubscriptionInfo>();  @EventHandler('Subscription Activated')  async onSubscriptionActivated(event: SubscriptionEvent) {    this.subscriptionCache.set(event.detail.userId, { plan: event.detail.plan, features: event.detail.plan.features });  }  async processOrder(order: Order) {    const subscription = this.subscriptionCache.get(order.userId);    if (subscription?.features.includes('priority_delivery')) order.priority = 'HIGH';  }}

Event Choreography vs Orkestrasyon

Orchestration tek bir servisin tüm akışı kontrol etmesi sıkı coupling ve single point of failure yaratır. Choreography her servisin kendi kısmını bilmesiyle daha gevşek coupling sağlar.

typescript
// Choreography - her servis kendi parçasını bilirexport class PaymentEventHandlers {  @EventHandler('Subscription Upgrade Requested')  async handleUpgradeRequest(event: UpgradeEvent) {    const result = await this.processPayment(event.detail);    await this.publishEvent('Payment Processed', { userId: event.detail.userId, amount: result.amount });  }}export class SubscriptionEventHandlers {  @EventHandler('Payment Processed')  async activateSubscription(event: PaymentEvent) {    const subscription = await this.create(event.detail.userId);    await this.publishEvent('Subscription Activated', { userId: event.detail.userId, subscriptionId: subscription.id });  }}

Hesap Yapısı ve İzolasyon

Her takım net sınırlarla kendi kum havuzunu aldı:

bash
# Hesap yapımızquickgrocer-org/├── production/│   ├── customer-facing/│   │   ├── customer-web-111111111111/│   │   ├── mobile-apps-222222222222/│   │   ├── partner-portal-333333333333/│   │   ├── driver-app-444444444444/│   │   └── merchant-dashboard-555555555555/│   ├── core-services/│   │   ├── inventory-mgmt-666666666666/│   │   ├── order-processing-777777777777/│   │   ├── delivery-orchestration-888888888888/│   │   └── payment-service-999999999999/│   └── shared-services/│       ├── identity-service-000000000000/│       ├── event-bus-121212121212/│       └── monitoring-131313131313/├── staging/│   └── [production yapısını yansıtır]└── development/    └── [geliştirici takımı başına bir hesap]

Gerçekten İşe Yarayanlar (İyi Kısımlar)

1. Takım Özerkliği

Takımlar sonunda kendi hızlarında ilerleyebildi. Mobile takım Black Friday'de beş güncelleme yayınlarken order processing takımı code freeze'deydi. Slack'te artık "lütfen deploy etmeyin, production'ı debug ediyoruz" mesajları yok.

2. Patlama Yarıçapı Kontrolü

DynamoDB silme olayını hatırlıyor musunuz? Yeni mimaride, delivery orchestration takımı yanlışlıkla 100.000 duplicate event işlediğinde (başka bir günün hikayesi), sadece kendi hesapları Lambda concurrent execution limitini vurdu. Müşteri siparişleri akmaya devam etti.

3. Net Maliyet Atfı

CFO'muz hangi takımın AWS kredilerimizi yaktığını tam olarak görebildiğinde neredeyse sevinç gözyaşları döktü:

typescript
// Maliyet tahsis etiketlerimizfunction applyCostTags(resource: any, teamName: string, serviceName: string): Record<string, string> {    return {        'Team': teamName,        'Service': serviceName,        'Environment': process.env.ENVIRONMENT || 'dev',        'CostCenter': TEAM_COST_CENTERS[teamName],        'Owner': TEAM_LEADS[teamName],        'CreatedDate': new Date().toISOString(),        'ManagedBy': 'CDK'    };}
// Aylık maliyet dağılımı kristal berraklıkta oldu:// Customer Web:         $12,450 (%25)// Mobile Apps:          $8,230  (%17)// Order Processing:     $15,670 (%32)// Delivery Orchestration: $7,890 (%16)// Identity Service:     $4,760  (%10)

4. Mantıklı Güvenlik Sınırları

Her hesabın kendi güvenlik çevresi vardı. Payment service takımı tüm şirketi compliance tiyatrosuna zorlamadan PCI compliance kontrollerini etkinleştirebildi:

typescript
// Payment service hesap güvenlik baseline'ıconst paymentServiceBaseline = new SecurityHub(this, 'PCICompliance', {  standards: [    SecurityHubStandard.PCI_DSS_V321,    SecurityHubStandard.AWS_FOUNDATIONAL_SECURITY  ],  enabledRegions: ['us-east-1', 'us-west-2'],  // Sadece payment service hesabı için  accountId: '999999999999'});

İşe Yaramayanlar (Acı Dersler)

1. Event Schema Evolution Cehennemi

Distributed sistemde event schema'ları değiştirmenin otoyolda giderken arabanın motorunu değiştirmek gibi olduğunu zor yoldan öğrendik. "Order Placed" event'imiz basit başladı:

json
// Versiyon 1 (Mart 2020){  "orderId": "ord-123",  "customerId": "cust-456",  "items": ["item-1", "item-2"],  "total": 45.99}

Birçok "hızlı düzeltme" sonrası:

json
// Versiyon 7 (Aralık 2020){  "orderId": "ord-123",  "customerId": "cust-456",  "customerIdV2": "usr_cust-456",  // Yeni ID formatı  "items": ["item-1", "item-2"],   // Deprecated, itemsV2 kullan  "itemsV2": [    {      "id": "item-1",      "quantity": 2,      "price": 12.99,      "modifiers": []  // v4'te eklendi    }  ],  "total": 45.99,            // v5'te deprecated  "totalAmount": {            // v5'te eklendi    "value": 45.99,    "currency": "USD"  },  "metadata": {               // v6'da eklendi    "source": "mobile-app",    "version": "2.3.1"  }}

Versiyonlama kabusu consumer'larımızda bu ucubeye yol açtı:

typescript
// "Schema registry kullanmalıydık" handler'ıexport const handleOrderPlaced = async (event: any) => {  // Hangi versiyonla uğraştığımızı kontrol et  const version = event.metadata?.schemaVersion ||                  (event.customerIdV2 ? 7 :                   event.totalAmount ? 5 :                   event.items?.[0]?.modifiers ? 4 : 1);
  switch(version) {    case 1:    case 2:    case 3:      return handleLegacyOrder(event);    case 4:      return handleV4Order(migrateV4ToV7(event));    case 5:    case 6:      return handleV5Order(migrateV5ToV7(event));    case 7:      return handleCurrentOrder(event);    default:      // Logla ve dua et      console.error('Bilinmeyen order versiyonu:', event);      throw new Error('Bilinmeyen schema versiyonu');  }};

2. Cross-Account Debugging Kabusu

Bir isteği birden fazla AWS hesabı boyunca takip etmek zordur. PagerDuty alert'inden Lambda retry döngüsüne, oradan EventBridge rule'daki typo'ya kadar iz sürmek saatler alabilir. Çözüm: OpenTelemetry ile distributed tracing.

typescript
// Distributed tracing akıl sağlığımızı kurtardıimport { trace, context, SpanStatusCode } from '@opentelemetry/api';
const tracer = trace.getTracer('quickgrocer-order-service', '1.0.0');
export const processOrder = async (event: any) => {  // EventBridge event'inden trace context'i çıkar  const traceParent = event.detail?.traceContext?.traceparent;  const traceState = event.detail?.traceContext?.tracestate;
  // Upstream service'ten trace'i devam ettir  const extractedContext = propagation.extract(context.active(), {    traceparent: traceParent,    tracestate: traceState  });
  return context.with(extractedContext, () => {    const span = tracer.startSpan('process-order', {      attributes: {        'order.id': event.detail.orderId,        'order.account': process.env.AWS_ACCOUNT_ID,        'order.region': process.env.AWS_REGION,        'order.service': 'order-processing'      }    });
    try {      // Siparişi işle      const result = await actuallyProcessOrder(event);      span.setStatus({ code: SpanStatusCode.OK });      return result;    } catch (error) {      span.recordException(error);      span.setStatus({        code: SpanStatusCode.ERROR,        message: error.message      });      throw error;    } finally {      span.end();    }  });};

3. Maliyet Patlaması

Multi-account multi-budget anlamına gelmiyor, ama birisi AWS faturamıza söylemeyi unuttu. Cross-account data transfer, EventBridge maliyetleri ve duplicate kaynaklar toplandı:

bash
# "Faturamız neden bu kadar yüksek" dökümüEventBridge Events:           $3,450/ay    # 345 milyon eventCross-AZ Data Transfer:       $2,100/ay    # Event'leri regional tutmalıydıkNAT Gateway (9 hesap):        $3,215/ay    # Hesap başına $35CloudWatch Logs:              $4,500/ay    # Herkes her şeyi logluyorduSecrets Manager:              $1,800/ay    # Secret'lar her yerde kopyalandıParameter Store API calls:    $890/ay      # Cache yok = API limit hit'leri
Toplam beklenmeyen maliyetler: $13,955/ay

Maliyet optimizasyon sprint'imiz:

typescript
// Önce: Her servis her istekte secret'ları çekiyorconst getSecret = async (secretName: string) => {  const client = new SecretsManagerClient({});  const response = await client.send(    new GetSecretValueCommand({ SecretId: secretName })  );  return response.SecretString;};
// Sonra: TTL ile cachingclass SecretCache {  private cache = new Map<string, {value: string, expiry: number}>();  private ttl = 3600000; // 1 saat
  async getSecret(secretName: string): Promise<string> {    const cached = this.cache.get(secretName);    if (cached && cached.expiry > Date.now()) {      return cached.value;    }
    const client = new SecretsManagerClient({});    const response = await client.send(      new GetSecretValueCommand({ SecretId: secretName })    );
    this.cache.set(secretName, {      value: response.SecretString!,      expiry: Date.now() + this.ttl    });
    return response.SecretString!;  }}
// Secrets Manager maliyetlerini %94 azalttı

Kritik Olay: Event Bus Sessizliği

Yoğun bir dönemde merkezi EventBridge bus aniden event teslim etmeyi bıraktı. Bus sağlıklı görünüyordu ama sıfır event yönlendiriliyordu. Birden fazla hesapta saatler süren debugging sonucu kök neden bulundu:

json
// $2.3 milyon kayıp siparişe mal olan typo{  "eventBusName": "central-bus",  "rules": [{    "name": "route-all-events",    "state": "DISABLED",  // <-- Birisi "hızlı düzeltme" sırasında yanlış tuşa bastı    "eventPattern": {      "source": [{ "prefix": "quickgrocer." }]    }  }]}

Birisi alakasız bir sorunu debug ederken ana routing rule'u devre dışı bırakmış ve yeniden etkinleştirmeyi unutmuştu. Bir checkbox. Dokuz hesap etkilendi. Yoğun sezonda 90 dakika kesinti.

Bu "Bir Daha Asla" protokollerimize yol açtı:

typescript
// Event bus sağlığı için otomatik monitoringconst eventBusMonitor = new Lambda(this, 'EventBusMonitor', {  runtime: Runtime.NODEJS_18_X,  handler: 'monitor.handler',  environment: {    EXPECTED_EVENTS_PER_MINUTE: '1000',    ALERT_THRESHOLD: '100',    SLACK_WEBHOOK: process.env.SLACK_WEBHOOK  }});
// Her dakika çalıştırnew Rule(this, 'MonitorSchedule', {  schedule: Schedule.rate(Duration.minutes(1)),  targets: [new LambdaFunction(eventBusMonitor)]});
// Gerçek monitoring mantığıexport const handler = async () => {  const cloudWatch = new CloudWatchClient({});
  // Son dakikada yayınlanan event'leri kontrol et  const metrics = await cloudWatch.send(new GetMetricStatisticsCommand({    Namespace: 'AWS/Events',    MetricName: 'SuccessfulRuleMatches',    StartTime: new Date(Date.now() - 120000),  // 2 dakika önce    EndTime: new Date(),    Period: 60,    Statistics: ['Sum']  }));
  const eventCount = metrics.Datapoints?.[0]?.Sum || 0;
  if (eventCount < parseInt(process.env.ALERT_THRESHOLD!)) {    // YÜKSEK SESLE BAĞIR    await sendSlackAlert({      text: `🚨 EVENT BUS KRİTİK: Son dakikada sadece ${eventCount} event!`,      color: 'danger'    });
    // Otomatik iyileşme denemesi    await enableAllRules();  }};

Farklı Yapacaklarımız (Geçmişe Bakış 20/20)

Bu mimariyi üç yıl çalıştırdıktan sonra geriye bakınca, geçmişteki kendime şunları söylerdim:

1. İlk Günden Schema Registry ile Başla

Sonunda AWS EventBridge Schema Registry'yi implement ettik, ama migration acı vericiydi:

typescript
// Baştan yapmalıydıkimport { SchemaRegistry } from '@aws-sdk/client-schemas';
const registry = new SchemaRegistry({});
// Schema'yı versiyonlama ile tanımlaconst orderSchema = {  openapi: '3.0.0',  info: {    version: '1.0.0',    title: 'OrderPlaced'  },  paths: {},  components: {    schemas: {      OrderPlaced: {        type: 'object',        required: ['orderId', 'customerId', 'items', 'totalAmount'],        properties: {          orderId: { type: 'string', pattern: '^ord-[0-9a-f]{8} },          customerId: { type: 'string', pattern: '^cust-[0-9a-f]{8} },          items: {            type: 'array',            items: {              $ref: '#/components/schemas/OrderItem'            }          },          totalAmount: {            $ref: '#/components/schemas/Money'          }        }      }    }  }};
// Yayınlamadan önce doğrulaconst validateAndPublish = async (event: any) => {  const validation = await registry.validateSchema(event, 'OrderPlaced', '1.0.0');  if (!validation.valid) {    throw new Error(`Schema doğrulama başarısız: ${validation.errors}`);  }  return await eventBridge.putEvents({ Entries: [event] });};

2. Önce Observability'ye Yatırım Yap, Son Değil

Monitoring'i sonradan düşündük. Şöyle olmalıydı:

typescript
// Observability-first yaklaşımclass InstrumentedEventPublisher {  private metrics: MetricsClient;  private tracer: Tracer;
  async publish(event: Event): Promise<void> {    const span = this.tracer.startSpan('event.publish');    const timer = this.metrics.startTimer('event.publish.duration');
    try {      // Event'e trace context ekle      event.traceContext = {        traceparent: span.spanContext().traceId,        tracestate: span.spanContext().traceState      };
      await this.eventBridge.putEvents({        Entries: [{          ...event,          Detail: JSON.stringify({            ...JSON.parse(event.Detail),            _metadata: {              timestamp: Date.now(),              account: process.env.AWS_ACCOUNT_ID,              service: process.env.SERVICE_NAME,              version: process.env.SERVICE_VERSION,              traceId: span.spanContext().traceId            }          })        }]      });
      this.metrics.increment('event.published', {        type: event.DetailType,        source: event.Source      });
    } catch (error) {      this.metrics.increment('event.publish.error', {        type: event.DetailType,        error: error.name      });      span.recordException(error);      throw error;    } finally {      timer.end();      span.end();    }  }}

3. Baştan Account Vending Machine

İlk başta hesapları manuel oluşturduk. Büyük hata:

typescript
// Hemen inşa etmeliydikimport { Organizations } from '@aws-sdk/client-organizations';import { ControlTower } from '@aws-sdk/client-controltower';
class AccountVendingMachine {  async createTeamAccount(team: TeamConfig): Promise<AWSAccount> {    // 1. Control Tower üzerinden hesap oluştur    const account = await this.controlTower.createAccount({      accountName: `quickgrocer-${team.name}-${team.environment}`,      accountEmail: `aws+${team.name}+${team.environment}@quickgrocer.com`,      organizationalUnit: this.getOUForTeam(team),
      // Baseline konfigürasyon      baselineConfig: {        enableCloudTrail: true,        enableConfig: true,        enableSecurityHub: true,        enableGuardDuty: true,        budgetLimit: team.monthlyBudget      }    });
    // 2. Takıma özel SCP'leri uygula    await this.applyServiceControlPolicies(account.id, team.permissions);
    // 3. Cross-account rolleri kur    await this.setupCrossAccountRoles(account.id, {      identityServiceRole: 'arn:aws:iam::000000000000:role/identity-validator',      eventBusRole: 'arn:aws:iam::121212121212:role/event-publisher'    });
    // 4. Baseline altyapıyı deploy et    await this.deployBaseline(account.id, {      vpcCidr: this.allocateVpcCidr(team),      eventBusArn: 'arn:aws:events:us-east-1:121212121212:event-bus/central-bus',      logGroupRetention: 30    });
    return account;  }}

4. Regional Strateji Global Olmalıydı

"Basit tutmak" için her şeyi us-east-1'de tuttuk. Sonra EU compliance'a ihtiyacımız oldu:

typescript
// İlk günden multi-region ayları kurtarırdıconst multiRegionStack = new Stack(app, 'MultiRegionInfra', {  env: {    account: process.env.CDK_DEFAULT_ACCOUNT,    region: process.env.CDK_DEFAULT_REGION  }});
// Birden fazla bölgeye deploy et['us-east-1', 'eu-west-1', 'ap-southeast-1'].forEach(region => {  new RegionalStack(app, `Regional-${region}`, {    env: { region },    eventBusArn: `arn:aws:events:${region}:121212121212:event-bus/central-bus`,    // Regional event routing    eventRouting: {      primary: region,      failover: getFailoverRegion(region)    }  });});

Özet

Multi-account mimari üç yıl çalıştırıldığında tipik metrikler:

Örnek sayılar:

  • Günlük event: 450 milyon
  • Cross-account API çağrıları: 12 milyon/gün
  • Ortalama gecikme: 47ms (340ms'den düştü)
  • Deployment sıklığı: 340 deployment/hafta (12'den yükseldi)
  • Production olayları: 2/ay (31'den düştü)
  • AWS faturası: $127,000/ay (ama her doların nereye gittiğini biliyoruz)

Takımlar kendi hızlarında ilerleyebiliyor, hatalar izole kalıyor.

Ana Çıkarımlar

Organizasyonunuz için multi-account mimari düşünüyorsanız, üç yıl siperlerde geçirdikten sonra öğrendiklerim:

  1. İhtiyacınız Olmadan Başlayın: Krizi beklemeyin. Baskı altında migration 10 kat daha zor
  2. Event-Driven Opsiyonel Değil: Multi-account'ta doğrudan service-to-service çağrılar sizi rahatsız edecek
  3. İlk Günden Schema Registry: Versiyonlama olmadan event schema evrimi organizasyonel borç
  4. Observability Bir Özellik Değil: Temel. Önce inşa edin, sonra kendinize teşekkür edin
  5. Account Vending Kritik: Manuel hesap oluşturma 3-4 hesaptan fazlasında ölçeklenmiyor
  6. Maliyet Sizi Şaşırtacak: Multi-account overhead için %30 fazla bütçe ayırın, sonra optimize edin
  7. Takım Eğitimi Önemli: Herkes distributed sistemleri nasıl idare edeceğini bilmiyor. Eğitime yatırım yapın

Multi-account yolculuğu sadece teknoloji değil - takımlara organizasyonel tutarlılığı korurken yenilik yapma özerkliği vermek. Karmaşık, pahalı ve kompleks, ama bir sonraki 10x büyüme dalgası vurduğunda hazır olacaksınız.

Unutmayın: distributed sistemler zor, multi-account AWS daha zor, ama hızlı büyüme sırasında monolithic karmaşa hepsinden zor.

İlgili Yazılar