π― Amazon Route 53 - Complete Architecture
graph TB
subgraph "DNS Query Resolution Flow"
Browser[π User Browser]
Recursive[π Recursive Resolver]
Root[π Root Name Server]
TLD[π’ .com TLD Server]
Auth[π― Route 53 Authoritative]
end
subgraph "Route 53 Core Components"
HZ[π Hosted Zone
example.com]
Records[π DNS Records
A, AAAA, CNAME, MX, TXT]
HC[β€οΈ Health Checks
HTTP/HTTPS/TCP]
Policies[ποΈ Routing Policies]
TF[π Traffic Flow
Visual Editor]
end
subgraph "Routing Policy Types"
Simple[π― Simple Routing
Single Resource]
Weighted[βοΈ Weighted Routing
Load Distribution]
Latency[β‘ Latency-based
Performance]
Failover[π Failover
Active/Passive]
Geo[π Geolocation
Geographic]
GeoProx[π Geoproximity
Distance + Bias]
Multi[π² Multivalue Answer
Multiple IPs]
end
subgraph "Target Infrastructure"
ALBEast[βοΈ ALB us-east-1
Primary]
ALBWest[βοΈ ALB us-west-2
Secondary]
ALBEU[βοΈ ALB eu-west-1
European]
CFDist[β‘ CloudFront
Global CDN]
S3Site[πͺ£ S3 Static Website]
ELB[π Classic ELB]
EIP[π Elastic IP]
end
Browser -->|1. Query example.com| Recursive
Recursive -->|2. Query Root| Root
Root -->|3. Refer to .com| TLD
TLD -->|4. Refer to Route 53| Auth
Auth -->|5. Return IP| Recursive
Recursive -->|6. Return IP| Browser
Auth --> HZ
HZ --> Records
Records --> Policies
HC --> Policies
TF --> Policies
Policies --> Simple
Policies --> Weighted
Policies --> Latency
Policies --> Failover
Policies --> Geo
Policies --> GeoProx
Policies --> Multi
Simple --> ALBEast
Weighted --> ALBEast
Weighted --> ALBWest
Latency --> ALBEast
Latency --> ALBWest
Latency --> ALBEU
Failover --> ALBEast
Failover --> ALBWest
Geo --> ALBEast
Geo --> ALBWest
Geo --> ALBEU
GeoProx --> ALBEast
GeoProx --> ALBWest
Multi --> CFDist
Multi --> S3Site
Multi --> EIP
HC -.->|Monitor| ALBEast
HC -.->|Monitor| ALBWest
HC -.->|Monitor| ALBEU
style HZ fill:#ff9999,stroke:#cc0000,stroke-width:3px
style HC fill:#ffcc99,stroke:#ff9900,stroke-width:3px
style TF fill:#99ccff,stroke:#0066cc,stroke-width:3px
π Route 53 Architecture Deep Dive
DNS Resolution Process (Steps 1-6):
- User browser queries recursive resolver for example.com
- Recursive resolver contacts root name servers
- Root servers refer to .com TLD servers
- TLD servers refer to Route 53 authoritative servers
- Route 53 returns the appropriate IP based on routing policy
- Recursive resolver returns final IP to user browser
Routing Policies Enable: Traffic distribution, geographic routing, failover, performance optimization, and load balancing across multiple AWS regions and resources.
π Route 53 Setup Command Flow
graph TD
Start[π Start Route 53 Setup]
subgraph "Phase 1: Foundation"
HZ[1οΈβ£ Create Hosted Zone
aws route53 create-hosted-zone]
NS[2οΈβ£ Update Domain Registrar
NS Records]
end
subgraph "Phase 2: Health Monitoring"
HC1[3οΈβ£ Create Health Check - Primary
aws route53 create-health-check]
HC2[4οΈβ£ Create Health Check - Secondary
aws route53 create-health-check]
end
subgraph "Phase 3: DNS Records"
Simple[5οΈβ£ Simple A Record
aws route53 change-resource-record-sets]
Weighted[6οΈβ£ Weighted Records
aws route53 change-resource-record-sets]
Latency[7οΈβ£ Latency Records
aws route53 change-resource-record-sets]
Failover[8οΈβ£ Failover Records
aws route53 change-resource-record-sets]
end
subgraph "Phase 4: Advanced Features"
TF[9οΈβ£ Traffic Flow Policy
aws route53 create-traffic-policy]
TFI[π Traffic Policy Instance
aws route53 create-traffic-policy-instance]
end
subgraph "Phase 5: Monitoring"
Log[1οΈβ£1οΈβ£ Query Logging
aws route53 create-query-logging-config]
CW[1οΈβ£2οΈβ£ CloudWatch Metrics
aws cloudwatch put-metric-alarm]
end
Start --> HZ
HZ --> NS
NS --> HC1
HC1 --> HC2
HC2 --> Simple
Simple --> Weighted
Weighted --> Latency
Latency --> Failover
Failover --> TF
TF --> TFI
TFI --> Log
Log --> CW
style HZ fill:#ff9999
style HC1 fill:#ffcc99
style HC2 fill:#ffcc99
style TF fill:#99ccff
style Log fill:#99ff99
π Route 53 Setup Command Flow Explanation
This diagram shows the precise order for Route 53 configuration:
- Phase 1: Establish DNS authority with hosted zone and domain configuration
- Phase 2: Set up health monitoring before creating dependent DNS records
- Phase 3: Create DNS records with various routing policies
- Phase 4: Implement advanced traffic management with Traffic Flow
- Phase 5: Enable monitoring and alerting for operational visibility
Step 1: Create Hosted Zone (Foundation)
aws route53 create-hosted-zone \
--name example.com \
--caller-reference "hz-$(date +%s)" \
--hosted-zone-config Comment="Production zone for example.com",PrivateZone=false
ποΈ Hosted Zone Creation Parameters
- --name: The domain name for the hosted zone (required)
- --caller-reference: Unique identifier using timestamp (required)
- Comment: Human-readable description
- PrivateZone: false = public zone, true = VPC-only zone
Alternative Options: --vpc for private zones, --delegation-set-id for reusable delegation sets
What This Does: Creates the DNS zone that will contain all DNS records for your domain. This is the foundation that must be created first before any DNS records can be added.
Next Step: Note the returned name servers and configure them at your domain registrar.
Step 2: Create Health Checks (Before DNS Records)
{
"Type": "HTTP",
"ResourcePath": "/health",
"FullyQualifiedDomainName": "api.example.com",
"Port": 80,
"RequestInterval": 30,
"FailureThreshold": 3,
"MeasureLatency": true,
"Regions": ["us-east-1", "us-west-2", "eu-west-1"]
}
aws route53 create-health-check \
--caller-reference "hc-primary-$(date +%s)" \
--health-check-config file://health-check-config.json
β€οΈ Health Check Configuration Parameters
- Type: HTTP, HTTPS, HTTP_STR_MATCH, HTTPS_STR_MATCH, TCP, CALCULATED, CLOUDWATCH_METRIC
- ResourcePath: URL path to check (for HTTP/HTTPS types)
- FullyQualifiedDomainName: The endpoint to monitor
- Port: Port number (80 for HTTP, 443 for HTTPS, custom for TCP)
- RequestInterval: 10 or 30 seconds between checks
- FailureThreshold: Number of consecutive failures before marking unhealthy (1-10)
- MeasureLatency: Track response times for CloudWatch metrics
- Regions: AWS regions to perform health checks from
Alternative Options: SearchString for string matching, AlarmRegion for CloudWatch alarms, InsufficientDataHealthStatus for handling missing data
What This Does: Creates a health monitor that continuously checks endpoint availability. Essential for failover and weighted routing policies.
Next Step: Create DNS records that reference this health check ID.
Step 3: Simple DNS Record
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "www.example.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{"Value": "192.0.2.1"}
]
}
}]
}
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://simple-a-record.json
π― Simple DNS Record Parameters
- Action: CREATE, DELETE, or UPSERT (update or insert)
- Name: The DNS name (subdomain.domain.com)
- Type: A, AAAA, CNAME, MX, TXT, SRV, PTR, NS, SOA
- TTL: Time to live in seconds (300 = 5 minutes)
- ResourceRecords: Array of values for the record
Alternative Options: AliasTarget for AWS resources, SetIdentifier for routing policies, Weight for weighted routing
What This Does: Creates a basic DNS record that maps a name to an IP address. This is the simplest form of DNS routing.
Next Step: Add more complex routing policies for advanced traffic management.
Step 4: Weighted Routing Records
{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "A",
"SetIdentifier": "primary-us-east-1",
"Weight": 80,
"TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.1"}],
"HealthCheckId": "12345678-1234-1234-1234-123456789012"
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "A",
"SetIdentifier": "secondary-us-west-2",
"Weight": 20,
"TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.2"}],
"HealthCheckId": "87654321-4321-4321-4321-210987654321"
}
}
]
}
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://weighted-routing.json
βοΈ Weighted Routing Parameters
- SetIdentifier: Unique name for this record set (required for routing policies)
- Weight: Relative weight (0-255), higher = more traffic
- HealthCheckId: Health check to determine if this endpoint is healthy
- TTL: Lower TTL (60s) for faster failover response
Traffic Distribution: With weights 80 and 20, primary gets 80% of traffic, secondary gets 20%
What This Does: Distributes traffic across multiple endpoints based on assigned weights. Automatically removes unhealthy endpoints from rotation.
Next Step: Consider latency-based routing for performance optimization.
Step 5: Latency-Based Routing
{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "global.example.com",
"Type": "A",
"SetIdentifier": "us-east-1-latency",
"Region": "us-east-1",
"TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.1"}],
"HealthCheckId": "12345678-1234-1234-1234-123456789012"
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "global.example.com",
"Type": "A",
"SetIdentifier": "eu-west-1-latency",
"Region": "eu-west-1",
"TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.3"}],
"HealthCheckId": "11111111-2222-3333-4444-555555555555"
}
}
]
}
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://latency-routing.json
β‘ Latency-Based Routing Parameters
- Region: AWS region where the resource is located
- SetIdentifier: Unique identifier including region for clarity
- HealthCheckId: Ensures only healthy endpoints receive traffic
Route 53 Behavior: Automatically routes users to the AWS region with the lowest latency based on network measurements
What This Does: Optimizes performance by routing users to the geographically closest healthy endpoint. Route 53 continuously measures latency from different locations.
Next Step: Add failover routing for high availability.
Step 6: Failover Routing
{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "app.example.com",
"Type": "A",
"SetIdentifier": "primary-failover",
"Failover": "PRIMARY",
"TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.1"}],
"HealthCheckId": "12345678-1234-1234-1234-123456789012"
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "app.example.com",
"Type": "A",
"SetIdentifier": "secondary-failover",
"Failover": "SECONDARY",
"TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.2"}]
}
}
]
}
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://failover-routing.json
π Failover Routing Parameters
- Failover: PRIMARY or SECONDARY designation
- HealthCheckId: Required for PRIMARY, optional for SECONDARY
- TTL: Low value (60s) for rapid failover detection
Failover Logic: Route 53 serves PRIMARY when healthy, automatically switches to SECONDARY when PRIMARY fails health checks
What This Does: Provides active-passive failover. All traffic goes to primary endpoint unless it fails health checks, then automatically routes to secondary.
Next Step: Consider Traffic Flow for complex routing scenarios.
Step 7: Traffic Flow Policy (Advanced)
{
"Document": {
"AWSPolicyFormatVersion": "2015-10-01",
"RecordType": "A",
"StartRule": "geolocation_rule",
"Rules": {
"geolocation_rule": {
"RuleType": "geolocation",
"Locations": [
{
"CountryCode": "US",
"EndpointReference": "us_weighted_rule"
},
{
"CountryCode": "GB",
"EndpointReference": "eu_endpoint"
},
{
"IsDefault": true,
"EndpointReference": "default_weighted_rule"
}
]
},
"us_weighted_rule": {
"RuleType": "weighted",
"Items": [
{
"Weight": 80,
"EndpointReference": "us_east_endpoint"
},
{
"Weight": 20,
"EndpointReference": "us_west_endpoint"
}
]
}
},
"Endpoints": {
"us_east_endpoint": {
"Type": "value",
"Value": "192.0.2.1"
},
"us_west_endpoint": {
"Type": "value",
"Value": "192.0.2.2"
},
"eu_endpoint": {
"Type": "value",
"Value": "192.0.2.3"
}
}
}
}
aws route53 create-traffic-policy \
--name "global-app-routing" \
--document file://traffic-policy.json \
--comment "Geolocation with weighted routing for global app"
π Traffic Flow Policy Parameters
- AWSPolicyFormatVersion: Policy format version (always use latest)
- RecordType: A, AAAA, CNAME, MX, etc.
- StartRule: The first rule to evaluate
- Rules: Decision tree with geolocation, weighted, latency, failover logic
- Endpoints: Final destinations for traffic
Policy Logic: US users get weighted distribution between east/west, UK users go to EU, all others get default weighted routing
What This Does: Creates complex routing logic combining multiple routing policies. Visual editor in AWS console shows decision tree.
Next Step: Create traffic policy instance to apply this policy to a DNS name.
Step 8: Apply Traffic Policy
aws route53 create-traffic-policy-instance \
--hosted-zone-id Z1234567890ABC \
--name "global.example.com" \
--ttl 300 \
--traffic-policy-id "12345678-1234-1234-1234-123456789012" \
--traffic-policy-version 1
π― Traffic Policy Instance Parameters
- --hosted-zone-id: Target hosted zone for the DNS name
- --name: DNS name to apply the policy to
- --ttl: Time to live for the policy responses
- --traffic-policy-id: ID returned from create-traffic-policy
- --traffic-policy-version: Version number (starts at 1)
What This Does: Applies the complex routing policy to a specific DNS name. Multiple instances can use the same policy.
Next Step: Enable query logging for monitoring and troubleshooting.
Step 9: Enable Query Logging
# First create CloudWatch Log Group
aws logs create-log-group \
--log-group-name "/aws/route53/example.com" \
--region us-east-1
# Then enable Route 53 query logging
aws route53 create-query-logging-config \
--hosted-zone-id Z1234567890ABC \
--cloud-watch-logs-log-group-arn "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/example.com"
π Query Logging Parameters
- --log-group-name: CloudWatch log group to receive query logs
- --hosted-zone-id: Hosted zone to monitor
- --cloud-watch-logs-log-group-arn: Full ARN of the log group
Log Contents: Query timestamp, client IP, query name, query type, response code, location, resolver IP
What This Does: Logs all DNS queries for the hosted zone to CloudWatch Logs for analysis, troubleshooting, and security monitoring.
Next Step: Set up CloudWatch alarms for monitoring DNS query patterns and failures.
πΊοΈ AWS Cloud Map - Service Discovery
graph TB
subgraph "Service Registration Flow"
App1[π± Application 1
web-service]
App2[π± Application 2
api-service]
App3[π± Application 3
db-service]
end
subgraph "AWS Cloud Map"
NS[π Namespace
my-company.local]
Svc1[π§ Service Registry
web-service]
Svc2[π§ Service Registry
api-service]
Svc3[π§ Service Registry
db-service]
Inst1[π Service Instance
10.0.1.100:8080]
Inst2[π Service Instance
10.0.2.100:3000]
Inst3[π Service Instance
10.0.3.100:5432]
end
subgraph "Service Discovery Methods"
DNS[π DNS-based Discovery
web-service.my-company.local]
API[π API-based Discovery
DiscoverInstances ]
Auto[π€ Auto Registration
ECS/EKS Integration]
end
subgraph "Health Monitoring"
HC1[β€οΈ Health Check
HTTP /health]
HC2[β€οΈ Health Check
TCP 3000]
HC3[β€οΈ Health Check
Custom Health Check]
end
subgraph "Consumer Services"
LB[βοΈ Load Balancer]
Gateway[πͺ API Gateway]
Mesh[πΈοΈ Service Mesh]
ECS[π¦ ECS Task]
end
App1 -->|Register| Svc1
App2 -->|Register| Svc2
App3 -->|Register| Svc3
Svc1 --> Inst1
Svc2 --> Inst2
Svc3 --> Inst3
NS --> Svc1
NS --> Svc2
NS --> Svc3
Inst1 --> HC1
Inst2 --> HC2
Inst3 --> HC3
DNS --> NS
API --> NS
Auto --> NS
LB --> DNS
Gateway --> API
Mesh --> DNS
ECS --> Auto
HC1 -.->|Health Status| DNS
HC2 -.->|Health Status| API
HC3 -.->|Health Status| Auto
style NS fill:#99ccff,stroke:#0066cc,stroke-width:3px
style DNS fill:#99ff99,stroke:#00cc00,stroke-width:2px
style API fill:#ffcc99,stroke:#ff9900,stroke-width:2px
style Auto fill:#ff9999,stroke:#cc0000,stroke-width:2px
π Cloud Map Service Discovery Explanation
Service Registration Flow:
- Applications: Register themselves with Cloud Map service registry
- Namespace: Logical grouping of services (like my-company.local)
- Service Registry: Contains metadata and instances for each service
- Service Instances: Individual running instances with IP addresses and ports
Discovery Methods: DNS-based (standard DNS queries), API-based (programmatic discovery), and automatic registration via ECS/EKS integrations
Health Monitoring: Continuous health checks ensure only healthy instances are discoverable
Step 1: Create Cloud Map Namespace
aws servicediscovery create-private-dns-namespace \
--name "my-company.local" \
--description "Private namespace for microservices" \
--vpc "vpc-12345678"
ποΈ Cloud Map Namespace Parameters
- --name: DNS namespace (use .local for private)
- --description: Human-readable description
- --vpc: VPC ID for private DNS namespace
Alternative Commands: create-public-dns-namespace for internet-accessible services, create-http-namespace for API-only discovery
What This Does: Creates a DNS namespace where services can register and be discovered. Private namespaces only work within the specified VPC.
Next Step: Create services within this namespace.
Step 2: Create Service Registry
{
"Name": "web-service",
"Description": "Frontend web application service",
"DnsConfig": {
"NamespaceId": "ns-12345678901234567",
"DnsRecords": [
{
"Type": "A",
"TTL": 60
}
]
},
"HealthCheckCustomConfig": {
"FailureThreshold": 3
}
}
aws servicediscovery create-service \
--name "web-service" \
--namespace-id "ns-12345678901234567" \
--dns-config "NamespaceId=ns-12345678901234567,DnsRecords=[{Type=A,TTL=60}]" \
--health-check-custom-config "FailureThreshold=3"
π§ Service Registry Parameters
- --name: Service name (becomes DNS name: web-service.my-company.local)
- --namespace-id: ID returned from create-private-dns-namespace
- DnsRecords.Type: A, AAAA, CNAME, or SRV records
- DnsRecords.TTL: DNS time-to-live in seconds
- FailureThreshold: Consecutive failed health checks before marking unhealthy
Alternative Options: HealthCheckConfig for Route 53 health checks, Tags for resource organization
What This Does: Creates a service registry that can contain multiple instances. Each service gets its own DNS name within the namespace.
Next Step: Register service instances with IP addresses and ports.
Step 3: Register Service Instance
{
"ServiceId": "srv-12345678901234567",
"InstanceId": "web-service-instance-1",
"Attributes": {
"AWS_INSTANCE_IPV4": "10.0.1.100",
"AWS_INSTANCE_PORT": "8080",
"environment": "production",
"version": "1.2.3"
}
}
aws servicediscovery register-instance \
--service-id "srv-12345678901234567" \
--instance-id "web-service-instance-1" \
--attributes AWS_INSTANCE_IPV4=10.0.1.100,AWS_INSTANCE_PORT=8080,environment=production,version=1.2.3
π Service Instance Parameters
- --service-id: ID returned from create-service
- --instance-id: Unique identifier for this instance
- AWS_INSTANCE_IPV4: Required IPv4 address
- AWS_INSTANCE_PORT: Port number for the service
- Custom Attributes: Additional metadata (environment, version, etc.)
Alternative Attributes: AWS_INSTANCE_IPV6, AWS_INSTANCE_CNAME for different record types
What This Does: Registers a running instance of the service with its network details. The instance becomes discoverable via DNS or API calls.
Next Step: Configure health checking for the instance.
β‘ CloudFront DNS Integration
graph TB
subgraph "Global Users"
US[πΊπΈ US Users]
EU[πͺπΊ EU Users]
ASIA[π¦πΈ Asia Users]
end
subgraph "CloudFront Edge Locations"
EdgeUS[π US Edge Location
Ashburn, VA]
EdgeEU[π EU Edge Location
Frankfurt]
EdgeASIA[π Asia Edge Location
Tokyo]
end
subgraph "DNS Resolution"
R53[π― Route 53
cdn.example.com]
CFDomain[β‘ CloudFront Domain
d123456789.cloudfront.net]
EdgeDNS[π Edge DNS Resolution]
end
subgraph "Origin Servers"
S3[πͺ£ S3 Origin
my-website-bucket]
ALB[βοΈ ALB Origin
api.example.com]
Custom[π Custom Origin
legacy-server.com]
end
subgraph "Cache Behavior"
StaticCache[π Static Content
TTL: 24 hours]
DynamicCache[π Dynamic Content
TTL: 0 seconds]
APICache[π API Responses
TTL: 5 minutes]
end
US -->|DNS Query| R53
EU -->|DNS Query| R53
ASIA -->|DNS Query| R53
R53 -->|CNAME| CFDomain
CFDomain -->|Route to Nearest| EdgeDNS
EdgeDNS -->|US Traffic| EdgeUS
EdgeDNS -->|EU Traffic| EdgeEU
EdgeDNS -->|Asia Traffic| EdgeASIA
EdgeUS -->|Cache Miss| S3
EdgeUS -->|API Calls| ALB
EdgeEU -->|Cache Miss| S3
EdgeEU -->|API Calls| ALB
EdgeASIA -->|Cache Miss| Custom
EdgeUS --> StaticCache
EdgeEU --> DynamicCache
EdgeASIA --> APICache
StaticCache -.->|Serve from Cache| US
DynamicCache -.->|Serve from Cache| EU
APICache -.->|Serve from Cache| ASIA
style R53 fill:#ff9999,stroke:#cc0000,stroke-width:3px
style CFDomain fill:#99ff99,stroke:#00cc00,stroke-width:3px
style EdgeDNS fill:#ffcc99,stroke:#ff9900,stroke-width:2px
π CloudFront DNS Integration Explanation
DNS Flow:
- Users query Route 53 for cdn.example.com
- Route 53 returns CloudFront distribution domain (CNAME)
- CloudFront's edge DNS resolution routes to nearest edge location
- Edge location serves cached content or fetches from origin
Edge Location Selection: CloudFront automatically routes users to the edge location with lowest latency based on network conditions
Cache Behavior: Different content types have different TTL settings for optimal performance and freshness
Step 1: Create CloudFront Distribution
{
"CallerReference": "cf-distribution-2024-001",
"Aliases": {
"Quantity": 1,
"Items": ["cdn.example.com"]
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "S3-my-website-bucket",
"DomainName": "my-website-bucket.s3.amazonaws.com",
"S3OriginConfig": {
"OriginAccessIdentity": "origin-access-identity/cloudfront/E123456789ABCD"
}
},
{
"Id": "ALB-api-origin",
"DomainName": "api.example.com",
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only"
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "S3-my-website-bucket",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"Compress": true
}
}
aws cloudfront create-distribution \
--distribution-config file://cloudfront-config.json
β‘ CloudFront Distribution Parameters
- CallerReference: Unique identifier for the distribution
- Aliases: Custom domain names (CNAMEs) for the distribution
- DefaultRootObject: Default file served for root requests
- Origins: Backend servers (S3, ALB, custom servers)
- S3OriginConfig: Configuration for S3 origins with OAI
- CustomOriginConfig: Configuration for non-S3 origins
- TargetOriginId: Which origin serves the default cache behavior
- ViewerProtocolPolicy: HTTP/HTTPS enforcement
- CachePolicyId: Predefined or custom cache policy
Alternative Options: PriceClass for geographic distribution, WebACLId for AWS WAF integration, Logging for access logs
What This Does: Creates a global CDN distribution with multiple origins and custom domain support
Next Step: Create Route 53 CNAME record pointing to the CloudFront domain
Step 2: Configure Route 53 for CloudFront
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "cdn.example.com",
"Type": "A",
"AliasTarget": {
"DNSName": "d123456789abcd.cloudfront.net",
"EvaluateTargetHealth": false,
"HostedZoneId": "Z2FDTNDATAQYW2"
}
}
}]
}
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://cloudfront-alias.json
π CloudFront Alias Record Parameters
- Name: Your custom domain name
- Type: A or AAAA record for alias
- DNSName: CloudFront distribution domain name
- EvaluateTargetHealth: Usually false for CloudFront
- HostedZoneId: CloudFront's hosted zone ID (always Z2FDTNDATAQYW2)
Alias vs CNAME: Alias records are free and can be used at the root domain, CNAMEs cost money and can't be used at root
What This Does: Creates a DNS alias that routes traffic from your custom domain to CloudFront without additional DNS lookup costs
Next Step: Configure SSL certificate for HTTPS support
πΈοΈ App Mesh DNS Integration
graph TB
subgraph "Service Mesh Control Plane"
AppMesh[πΈοΈ App Mesh Controller]
Envoy[π§ Envoy Proxy Config]
VirtualNodes[π¦ Virtual Nodes]
VirtualServices[π Virtual Services]
end
subgraph "ECS/EKS Cluster"
Task1[π¦ ECS Task 1
frontend-service]
Task2[π¦ ECS Task 2
api-service]
Task3[π¦ ECS Task 3
database-service]
Proxy1[π§ Envoy Sidecar 1]
Proxy2[π§ Envoy Sidecar 2]
Proxy3[π§ Envoy Sidecar 3]
end
subgraph "Service Discovery"
CloudMap[πΊοΈ Cloud Map
my-app.local]
DNS1[π frontend.my-app.local]
DNS2[π api.my-app.local]
DNS3[π database.my-app.local]
end
subgraph "Traffic Management"
LoadBalancing[βοΈ Load Balancing
Round Robin/Weighted]
HealthCheck[β€οΈ Health Checking
Circuit Breaker]
Retry[π Retry Logic
Timeout Handling]
TLS[π mTLS Encryption
Certificate Management]
end
Task1 --> Proxy1
Task2 --> Proxy2
Task3 --> Proxy3
AppMesh --> Envoy
Envoy --> Proxy1
Envoy --> Proxy2
Envoy --> Proxy3
VirtualNodes --> Task1
VirtualNodes --> Task2
VirtualNodes --> Task3
VirtualServices --> DNS1
VirtualServices --> DNS2
VirtualServices --> DNS3
CloudMap --> DNS1
CloudMap --> DNS2
CloudMap --> DNS3
Proxy1 -->|Service Call| Proxy2
Proxy2 -->|Service Call| Proxy3
Proxy1 --> LoadBalancing
Proxy2 --> HealthCheck
Proxy3 --> Retry
LoadBalancing --> TLS
HealthCheck --> TLS
Retry --> TLS
DNS1 -.->|Service Discovery| Proxy1
DNS2 -.->|Service Discovery| Proxy2
DNS3 -.->|Service Discovery| Proxy3
style AppMesh fill:#ff9999,stroke:#cc0000,stroke-width:3px
style CloudMap fill:#99ccff,stroke:#0066cc,stroke-width:3px
style TLS fill:#99ff99,stroke:#00cc00,stroke-width:3px
π App Mesh DNS Integration Explanation
Service Mesh Architecture:
- Virtual Nodes: Logical representation of compute resources (ECS tasks, EKS pods)
- Virtual Services: Abstract service names that map to virtual nodes
- Envoy Sidecars: Proxy containers that handle all network traffic
- Cloud Map Integration: Provides DNS-based service discovery
Traffic Flow: Services communicate via DNS names β Envoy proxies intercept traffic β App Mesh applies policies β Traffic routed to healthy endpoints
Benefits: Automatic load balancing, circuit breaking, retry logic, mTLS encryption, and observability
Step 1: Create App Mesh
aws appmesh create-mesh \
--mesh-name "my-application-mesh" \
--spec egressFilter="{type=ALLOW_ALL}"
πΈοΈ App Mesh Creation Parameters
- --mesh-name: Unique name for the service mesh
- egressFilter: ALLOW_ALL or DROP_ALL for external traffic
Egress Filter Options: ALLOW_ALL permits external calls, DROP_ALL blocks external traffic unless explicitly allowed
What This Does: Creates the service mesh container that will hold all virtual services and nodes
Next Step: Create virtual nodes for each service
Step 2: Create Virtual Node
{
"meshName": "my-application-mesh",
"virtualNodeName": "frontend-service-vn",
"spec": {
"listeners": [
{
"portMapping": {
"port": 8080,
"protocol": "http"
},
"healthCheck": {
"protocol": "http",
"path": "/health",
"intervalMillis": 30000,
"timeoutMillis": 5000,
"unhealthyThreshold": 3,
"healthyThreshold": 2
}
}
],
"serviceDiscovery": {
"awsCloudMap": {
"namespaceName": "my-app.local",
"serviceName": "frontend-service"
}
},
"backends": [
{
"virtualService": {
"virtualServiceName": "api-service.my-app.local"
}
}
]
}
}
aws appmesh create-virtual-node \
--mesh-name "my-application-mesh" \
--virtual-node-name "frontend-service-vn" \
--spec file://virtual-node-spec.json
π¦ Virtual Node Parameters
- listeners.portMapping: Port and protocol the service listens on
- healthCheck: Health check configuration for the service
- serviceDiscovery.awsCloudMap: Integration with Cloud Map for DNS
- backends: Other services this node can call
- intervalMillis: Health check frequency (30 seconds)
- unhealthyThreshold: Failed checks before marking unhealthy
Alternative Options: dns for DNS-based discovery, file for static configuration, logging for access logs
What This Does: Creates a logical representation of your service with health checking and service discovery integration
Next Step: Create virtual service to provide stable DNS name
Step 3: Create Virtual Service
{
"meshName": "my-application-mesh",
"virtualServiceName": "frontend-service.my-app.local",
"spec": {
"provider": {
"virtualNode": {
"virtualNodeName": "frontend-service-vn"
}
}
}
}
aws appmesh create-virtual-service \
--mesh-name "my-application-mesh" \
--virtual-service-name "frontend-service.my-app.local" \
--spec file://virtual-service-spec.json
π Virtual Service Parameters
- virtualServiceName: DNS name other services use to call this service
- provider.virtualNode: Routes all traffic to a single virtual node
Alternative Providers: virtualRouter for complex routing rules, traffic splitting, A/B testing
What This Does: Creates a stable DNS endpoint that abstracts the underlying virtual nodes. Services call the virtual service name instead of individual node IPs.
Next Step: Configure ECS/EKS tasks to use App Mesh and Envoy sidecars
Step 4: Configure ECS Task Definition with App Mesh
{
"family": "frontend-service-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
"proxyConfiguration": {
"type": "APPMESH",
"containerName": "envoy",
"properties": [
{
"name": "IgnoredUID",
"value": "1337"
},
{
"name": "ProxyIngressPort",
"value": "15000"
},
{
"name": "ProxyEgressPort",
"value": "15001"
},
{
"name": "AppPorts",
"value": "8080"
},
{
"name": "EgressIgnoredIPs",
"value": "169.254.170.2,169.254.169.254"
}
]
},
"containerDefinitions": [
{
"name": "frontend-app",
"image": "my-frontend-app:latest",
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "API_ENDPOINT",
"value": "api-service.my-app.local:3000"
}
],
"dependsOn": [
{
"containerName": "envoy",
"condition": "HEALTHY"
}
]
},
{
"name": "envoy",
"image": "public.ecr.aws/appmesh/aws-appmesh-envoy:v1.22.2.0-prod",
"essential": true,
"environment": [
{
"name": "APPMESH_VIRTUAL_NODE_NAME",
"value": "mesh/my-application-mesh/virtualNode/frontend-service-vn"
},
{
"name": "AWS_REGION",
"value": "us-east-1"
}
],
"healthCheck": {
"command": [
"CMD-SHELL",
"curl -s http://localhost:9901/server_info | grep state | grep -q LIVE"
],
"interval": 5,
"timeout": 2,
"retries": 3,
"startPeriod": 10
}
}
]
}
aws ecs register-task-definition \
--cli-input-json file://frontend-task-definition.json
π¦ ECS App Mesh Integration Parameters
- proxyConfiguration: Configures traffic interception by Envoy proxy
- IgnoredUID: User ID that Envoy runs as (1337 by convention)
- ProxyIngressPort: Port for incoming traffic (15000)
- ProxyEgressPort: Port for outgoing traffic (15001)
- AppPorts: Application ports to intercept
- EgressIgnoredIPs: AWS metadata service IPs to bypass
- APPMESH_VIRTUAL_NODE_NAME: Full ARN path to virtual node
- dependsOn: Ensures Envoy starts before application
Traffic Flow: All application traffic is transparently intercepted by Envoy sidecar using iptables rules
What This Does: Configures ECS task to participate in the service mesh with automatic traffic management and observability
Next Step: Deploy the service and verify mesh connectivity