Microservices Architecture
Key concepts
Service decomposition
API-first design
Service discovery
Container orchestration
Independent deployability
Overview
Microservices architecture is an approach to building applications as a collection of small, independent services that communicate over well-defined APIs. Each service is developed, deployed, and scaled independently, owned by small teams, and focused on a specific business capability.
Understanding microservices architecture is essential for the SAA-C03 exam because it represents a fundamental shift from monolithic applications. You must know when to recommend microservices over monoliths, how to choose between container orchestration options (ECS vs EKS vs Fargate), implement service discovery and communication patterns, and design for resilience in distributed systems.
Microservices vs Monolith
Microservices break applications into independently deployable services. Each service has its own database, can use different technologies, and scales independently. This enables faster deployments but adds complexity in service discovery, distributed transactions, and monitoring.
Exam questions often present scenarios involving monolithic applications with scaling or deployment challenges. The solution typically involves breaking the application into microservices using ECS, EKS, or Lambda with API Gateway and SQS/SNS for decoupling.
Key Concepts
Microservices Overview

Microservices Principles
Microservices are built around these core principles:
- Single Responsibility: Each service does one thing well
- Independent Deployment: Deploy without affecting other services
- Decentralized Data: Each service manages its own data store
- API-First Design: Services communicate via well-defined APIs
- Failure Isolation: One service failure doesn't cascade to others
- Technology Agnostic: Teams can choose appropriate tech stack
Monolith vs Microservices
Monolith vs Microservices
| Aspect | Monolithic | Microservices |
|---|---|---|
| Deployment | All-or-nothing | Independent per service |
| Scaling | Scale entire application | Scale individual services |
| Technology | Single stack | Polyglot (different stacks) |
| Data | Shared database | Database per service |
| Team Structure | Large, coordinated teams | Small, autonomous teams |
| Complexity | Simpler initially | Distributed system complexity |
| Failure Impact | Can bring down entire app | Isolated to single service |
CHOOSE MONOLITH WHEN:
├── Small team (< 10 developers)
├── Simple domain with clear boundaries
├── Startup MVP or rapid prototyping
├── Limited operational expertise
└── Predictable, stable requirements
CHOOSE MICROSERVICES WHEN:
├── Large organization with multiple teams
├── Different services have different scaling needs
├── Need for technology flexibility
├── Frequent, independent deployments required
├── High availability requirements
└── Complex domain with clear bounded contextsAWS Container Services

Amazon ECS (Elastic Container Service)
Amazon ECS
Amazon ECS is AWS's native container orchestration service that simplifies running Docker containers at scale. It integrates deeply with AWS services and offers two launch types:
- EC2 Launch Type: You manage EC2 instances in your cluster
- Fargate Launch Type: Serverless - AWS manages infrastructure
ECS ARCHITECTURE:
CLUSTER
├── Logical grouping of tasks and services
└── Can span multiple Availability Zones
TASK DEFINITION
├── Blueprint for your application
├── Specifies container images
├── Defines CPU, memory, networking
├── IAM roles for containers
└── Similar to a Docker Compose file
SERVICE
├── Runs and maintains desired task count
├── Integrates with load balancers
├── Supports rolling deployments
├── Auto Scaling capabilities
└── Health check monitoring
TASK
├── Running instance of task definition
├── One or more containers
├── Ephemeral (can be replaced)
└── Runs on EC2 or FargateAmazon EKS (Elastic Kubernetes Service)
Amazon EKS
Amazon EKS runs Kubernetes on AWS without needing to install and operate your own Kubernetes control plane. Choose EKS when you need Kubernetes-specific features, cross-cloud portability, or have existing Kubernetes expertise.
EKS ARCHITECTURE:
CONTROL PLANE (AWS Managed)
├── Kubernetes API server
├── etcd (cluster state storage)
├── Controller manager
└── Scheduler
DATA PLANE (You manage or Fargate)
├── Worker Nodes (EC2 instances)
├── Node Groups (managed scaling)
└── Fargate Profiles (serverless)
KUBERNETES RESOURCES:
POD
├── Smallest deployable unit
├── Contains one or more containers
└── Shared networking and storage
DEPLOYMENT
├── Manages replica sets
├── Rolling updates
└── Rollback capabilities
SERVICE
├── Stable network endpoint
├── Load balancing across pods
└── Service discovery (DNS)AWS Fargate
AWS Fargate
AWS Fargate is a serverless compute engine for containers that works with both ECS and EKS. You don't provision or manage servers - just specify CPU and memory requirements for your containers.
ECS vs EKS vs Fargate
| Feature | ECS (EC2) | ECS (Fargate) | EKS |
|---|---|---|---|
| Management | Manage EC2 instances | Serverless | Manage nodes or use Fargate |
| Learning Curve | AWS-native, simpler | Very simple | Kubernetes expertise needed |
| Portability | AWS only | AWS only | Multi-cloud with K8s |
| Pricing | EC2 + ECS (free) | Per vCPU/memory/second | EKS fee + EC2 or Fargate |
| Scaling | EC2 Auto Scaling | Automatic | HPA + Cluster Autoscaler |
| Best For | AWS-native workloads | Serverless containers | Kubernetes workloads |
Service Discovery

Service Discovery Options
Service Discovery
In a microservices architecture, services need to find each other dynamically. AWS provides several service discovery mechanisms:
- AWS Cloud Map: Native service discovery for all AWS resources
- ECS Service Discovery: Integrates with Route 53 Auto Naming
- Kubernetes DNS: Built-in DNS for EKS services
- Application Load Balancer: Layer 7 routing and discovery
CLIENT-SIDE DISCOVERY:
├── Service queries registry directly
├── Client chooses instance to call
├── Examples: Consul, Eureka
└── More complex client logic
SERVER-SIDE DISCOVERY (AWS Recommended):
├── Request goes to load balancer/DNS
├── Router queries registry and forwards
├── Examples: ALB, Route 53, Cloud Map
└── Simpler client, transparent discovery
AWS CLOUD MAP:
├── Define namespace (e.g., production.local)
├── Register service (e.g., orders.production.local)
├── Health checks update DNS records
├── Auto-removes unhealthy instances
└── API and DNS query support
ECS SERVICE DISCOVERY:
├── Automatic registration with Cloud Map
├── DNS A or SRV records
├── Integrates with Route 53
└── Health check integrationAWS Cloud Map Configuration
{
"Namespace": {
"Name": "production.local",
"Type": "DNS_PRIVATE",
"Vpc": "vpc-123456"
},
"Service": {
"Name": "order-service",
"DnsConfig": {
"RoutingPolicy": "MULTIVALUE",
"DnsRecords": [
{ "Type": "A", "TTL": 60 }
]
},
"HealthCheckCustomConfig": {
"FailureThreshold": 3
}
}
}Communication Patterns
Synchronous Communication
Synchronous (Request-Response)
Synchronous communication is when a service makes a request and waits for a response. This is common for real-time operations but creates tight coupling between services.
AWS Services: API Gateway, ALB, NLB
REST API (Most Common):
├── HTTP/HTTPS protocols
├── Stateless requests
├── JSON/XML payloads
└── Good for: CRUD operations, web APIs
gRPC:
├── High-performance RPC framework
├── Protocol Buffers for serialization
├── HTTP/2 with bidirectional streaming
└── Good for: Low-latency service-to-service
API GATEWAY PATTERN:
Internet → API Gateway → Microservices
├── Single entry point for clients
├── Request routing by path/header
├── Authentication & authorization
├── Rate limiting & throttling
├── Request/response transformation
└── CachingAsynchronous Communication
Asynchronous (Event-Driven)
Asynchronous communication decouples services by using message queues or event streams. Services don't wait for responses, improving resilience and scalability.
AWS Services: SQS, SNS, EventBridge, Kinesis
MESSAGE QUEUES (SQS):
├── Point-to-point communication
├── Guaranteed delivery
├── Message persistence
├── Dead-letter queues for failures
└── Good for: Work distribution, decoupling
PUBLISH/SUBSCRIBE (SNS):
├── One-to-many messaging
├── Multiple subscriber types
├── Fan-out pattern
└── Good for: Notifications, broadcasting
EVENT STREAMING (Kinesis/EventBridge):
├── Real-time data streams
├── Event sourcing patterns
├── Multiple consumers
└── Good for: Analytics, real-time processingCommunication Pattern Selection
| Pattern | Coupling | Use Case | AWS Service |
|---|---|---|---|
| Sync REST API | Tight | CRUD, real-time queries | API Gateway + ALB |
| Async Queue | Loose | Background processing | SQS |
| Pub/Sub | Loose | Event notifications | SNS + SQS |
| Event Stream | Loose | Real-time analytics | Kinesis, EventBridge |
API Gateway Pattern

API Gateway Pattern
The API Gateway pattern provides a single entry point for all client requests, routing them to appropriate microservices. It handles cross-cutting concerns like authentication, rate limiting, and monitoring.
API GATEWAY PATTERN:
┌──────────────────┐
│ API Gateway │
│ ───────────── │
Mobile ───────────→ │ • Authentication │
Web App ──────────→ │ • Rate Limiting │ ──→ Microservices
Partners ─────────→ │ • Routing │
│ • Transformation │
│ • Caching │
└──────────────────┘
AMAZON API GATEWAY FEATURES:
├── REST APIs (full-featured)
│ ├── Request/response transformation
│ ├── SDK generation
│ └── API caching
│
├── HTTP APIs (simpler, faster, cheaper)
│ ├── Lower latency
│ ├── Native OpenID Connect/OAuth 2.0
│ └── 71% cheaper than REST APIs
│
└── WebSocket APIs
├── Real-time bidirectional
├── Chat, gaming, trading
└── Connection state managementAPI Gateway Integration Types
API Gateway Integration Types
| Integration | Description | Use Case |
|---|---|---|
| Lambda Proxy | Passes entire request to Lambda | Serverless backends |
| HTTP Proxy | Forwards to HTTP endpoints | ECS/EKS services, external APIs |
| VPC Link | Private integration to VPC resources | Internal microservices |
| Mock | Returns hardcoded response | Testing, stubs |
Distributed Transaction Patterns
Saga Pattern
Saga Pattern
The Saga pattern manages distributed transactions across microservices. Instead of a single ACID transaction, it uses a sequence of local transactions with compensating actions for rollbacks.
SAGA PATTERN (Order Processing Example):
SUCCESS PATH:
1. Create Order → Order Service
2. Reserve Inventory → Inventory Service
3. Process Payment → Payment Service
4. Ship Order → Shipping Service
✓ Complete
COMPENSATING TRANSACTIONS (on failure):
If Payment fails:
├── 3. Payment Failed → Trigger compensation
├── 2. Release Inventory → Inventory Service
├── 1. Cancel Order → Order Service
└── Return error to user
AWS STEP FUNCTIONS FOR SAGA:
├── Visual workflow designer
├── Error handling & retries
├── Timeout management
├── Parallel execution
├── State machine definition
└── Integration with Lambda, ECS, SQSBest Practices
Design Principles
- Design for Failure: Implement circuit breakers, retries, and timeouts
- Decentralize Data: Each service owns its data store
- API Versioning: Version APIs to enable independent deployments
- Stateless Services: Store state externally (DynamoDB, ElastiCache)
- Automate Everything: CI/CD pipelines for each microservice
- Monitor Extensively: Distributed tracing, centralized logging
- Start Simple: Begin with a monolith if uncertain, extract later
Container Best Practices
IMAGE OPTIMIZATION:
├── Use minimal base images (Alpine, distroless)
├── Multi-stage builds to reduce size
├── Scan images for vulnerabilities (ECR scanning)
└── Tag images with git SHA, not just 'latest'
RESOURCE MANAGEMENT:
├── Set CPU and memory limits
├── Use appropriate instance types (Fargate vCPU/memory)
├── Implement health checks
└── Configure graceful shutdown
SECURITY:
├── Run as non-root user
├── Use IAM roles for tasks (not embedded credentials)
├── Enable secrets management (Secrets Manager)
├── Network isolation with security groups
└── Enable encryption in transit
DEPLOYMENT:
├── Blue/green or canary deployments
├── Rolling updates with health checks
├── Automated rollback on failures
└── Immutable infrastructureCommon Exam Scenarios
Exam Scenarios
| Scenario | Solution | Why |
|---|---|---|
| Monolith with scaling issues | Refactor to microservices on ECS/EKS | Independent scaling per service |
| Team needs Kubernetes portability | Amazon EKS | Standard Kubernetes APIs |
| Serverless containers, no infra | AWS Fargate | No servers to manage |
| Services need to discover each other | AWS Cloud Map + Route 53 | Dynamic service discovery |
| Decouple order processing | SQS between services | Async, fault-tolerant |
| Single API entry point | API Gateway | Routing, auth, rate limiting |
| Distributed transaction across services | Step Functions (Saga) | Orchestration with compensation |
| Container images with secrets | Secrets Manager + IAM roles | No embedded credentials |
Common Pitfalls
Pitfall 1: Distributed Monolith
Mistake: Creating microservices that are tightly coupled through synchronous calls.
Why it fails: Defeats the purpose of microservices; one service failure cascades.
Correct Approach: Use async communication (SQS, SNS) for loose coupling; design for failure.
Pitfall 2: Shared Database
Mistake: Multiple microservices accessing the same database.
Why it fails: Creates tight coupling; schema changes affect multiple services.
Correct Approach: Each service owns its database; use APIs or events to share data.
Pitfall 3: Wrong Container Orchestrator
Mistake: Choosing EKS when team has no Kubernetes experience.
Why it fails: Steep learning curve; operational overhead; potential misconfigurations.
Correct Approach: Start with ECS/Fargate for simpler operations; migrate to EKS if needed.
Pitfall 4: No Service Discovery
Mistake: Hardcoding service endpoints or IP addresses.
Why it fails: Services can't scale or failover; manual updates required.
Correct Approach: Use Cloud Map, ALB, or Kubernetes DNS for dynamic discovery.
Pitfall 5: Missing Observability
Mistake: Deploying microservices without centralized logging and tracing.
Why it fails: Debugging distributed systems becomes impossible.
Correct Approach: Use X-Ray for tracing, CloudWatch for logs, Container Insights for metrics.
Related Services
Quick Reference
Container Service Decision Matrix
Container Service Selection
| Requirement | Recommended Service |
|---|---|
| Simplest container deployment | ECS + Fargate |
| Kubernetes required | EKS (+ Fargate optional) |
| Need to manage EC2 instances | ECS or EKS with EC2 |
| Maximum portability | EKS |
| Lowest operational overhead | Fargate |
| Cost-sensitive, steady workload | ECS EC2 + Reserved/Spot |
Communication Pattern Quick Reference
CHOOSE SYNCHRONOUS (API Gateway, ALB):
├── Real-time response required
├── Simple request-response
├── User-facing operations
└── Query operations
CHOOSE ASYNCHRONOUS (SQS, SNS, EventBridge):
├── Can tolerate latency
├── Need fault tolerance
├── Background processing
├── Event broadcasting
├── Workload decoupling
└── Fan-out scenariosECS Task Definition Example
{
"family": "order-service",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789012:role/orderServiceRole",
"containerDefinitions": [
{
"name": "order-api",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/order-service:v1.2.3",
"portMappings": [
{ "containerPort": 8080, "protocol": "tcp" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/order-service",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3
},
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:db-password"
}
]
}
]
}Test Your Knowledge
A company is migrating a monolithic application to microservices. Different services have different scaling requirements - one handles thousands of requests per second while another processes batch jobs hourly. Which is the primary benefit of microservices for this scenario?
A solutions architect needs to choose between ECS and EKS for a new container workload. The team has no Kubernetes experience but needs to deploy quickly with minimal operational overhead. What is the recommended approach?
How should microservices discover each other's endpoints in an AWS environment?
A distributed e-commerce application needs to process orders across multiple microservices (inventory, payment, shipping). If the payment service fails, previous operations must be rolled back. Which pattern should be used?