The DNS Stack is the foundation layer (Phase 1) of the EveryoneCook infrastructure. It manages the Route 53 Hosted Zone for the everyonecook.cloud domain, providing DNS infrastructure that all other stacks depend on.
Deployment Order: This stack MUST be deployed first before any other stacks.
┌─────────────────────────────────────────────────────────┐
│ Hostinger Domain │
│ everyonecook.cloud │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Domain Registrar Settings │ │
│ │ • Update Nameservers to Route 53 NS records │ │
│ └────────────────┬───────────────────────────────┘ │
└───────────────────┼──────────────────────────────────────┘
│ DNS Delegation
▼
┌─────────────────────────────────────────────────────────┐
│ AWS Route 53 Hosted Zone │
│ everyonecook.cloud │
│ │
│ Resources Created: │
│ • Public Hosted Zone │
│ • 4 Nameserver (NS) Records │
│ • SOA Record (automatic) │
│ │
│ Exports: │
│ • Hosted Zone ID → Used by Certificate Stack │
│ • Hosted Zone Name → Used by other stacks │
│ • Nameservers → Configure at Hostinger │
└─────────────────────────────────────────────────────────┘
infrastructure/lib/stacks/
└── dns-stack.ts # DNS Stack implementation
File: infrastructure/lib/stacks/dns-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { BaseStack, BaseStackProps } from '../base-stack';
export class DnsStack extends BaseStack {
public readonly hostedZone: cdk.aws_route53.IHostedZone;
constructor(scope: Construct, id: string, props: BaseStackProps) {
super(scope, id, props);
// Add stack-specific tags
cdk.Tags.of(this).add('StackType', 'DNS');
cdk.Tags.of(this).add('Layer', 'Foundation');
cdk.Tags.of(this).add('CostCenter', `DNS-${this.config.environment}`);
// Create Route 53 Hosted Zone
this.hostedZone = this.createHostedZone();
// Export stack outputs
this.exportOutputs();
}
private createHostedZone(): cdk.aws_route53.IHostedZone {
// Extract root domain from environment config
const rootDomain = this.config.domains.frontend
.replace(/^(dev\.|staging\.)/, ''); // everyonecook.cloud
const hostedZone = new cdk.aws_route53.PublicHostedZone(
this,
'HostedZone',
{
zoneName: rootDomain,
comment: `Hosted Zone for Everyone Cook ${this.config.environment} environment`,
}
);
cdk.Tags.of(hostedZone).add('Component', 'DNS');
cdk.Tags.of(hostedZone).add('ManagedBy', 'CDK');
return hostedZone;
}
private exportOutputs(): void {
// Export Hosted Zone ID
new cdk.CfnOutput(this, 'HostedZoneId', {
value: this.hostedZone.hostedZoneId,
exportName: this.exportName('HostedZoneId'),
description: 'Route 53 Hosted Zone ID',
});
// Export Hosted Zone Name
new cdk.CfnOutput(this, 'HostedZoneName', {
value: this.hostedZone.zoneName,
exportName: this.exportName('HostedZoneName'),
description: 'Domain name managed by Route 53',
});
// Export Nameservers (for Hostinger configuration)
new cdk.CfnOutput(this, 'NameServers', {
value: cdk.Fn.join(', ', this.hostedZone.hostedZoneNameServers || []),
description: '⚠️ Update these nameservers at Hostinger',
});
}
}
The stack automatically extracts the root domain from the environment configuration:
// Environment config: dev.everyonecook.cloud
// Extracted domain: everyonecook.cloud
const rootDomain = this.config.domains.frontend.replace(/^(dev\.|staging\.)/, '');
Environments:
dev.everyonecook.cloud → Hosted Zone: everyonecook.cloudstaging.everyonecook.cloud → Hosted Zone: everyonecook.cloudeveryonecook.cloud → Hosted Zone: everyonecook.cloudAll resources follow a consistent naming pattern:
// Resource name format: everyonecook-{env}-{resource}
protected resourceName(name: string): string {
return `everyonecook-${this.config.environment}-${name}`;
}
// Export name format: EveryoneCook-{Env}-{Export}
protected exportName(name: string): string {
return `EveryoneCook-${this.config.environment}-${name}`;
}
Example:
EveryoneCook-dev-DNSEveryoneCook-dev-HostedZoneIdEvery resource is tagged for cost tracking and management:
{
Stack: 'EveryoneCook-dev-DNS',
Environment: 'dev',
StackType: 'DNS',
Layer: 'Foundation',
CostCenter: 'DNS-dev',
Component: 'DNS',
ManagedBy: 'CDK',
Project: 'EveryoneCook'
}
After deployment, the stack exports the following values:
| Output Name | Value | Usage |
|---|---|---|
HostedZoneId | Z0123456789ABCDEFGHIJ | Used by Certificate Stack for DNS validation |
HostedZoneName | everyonecook.cloud | Used by other stacks to create DNS records |
NameServers | ns-1.awsdns-01.com, ns-2.awsdns-02.org, ... | Configure at Hostinger for DNS delegation |
Navigate to the infrastructure directory:
cd D:\Project_AWS\everyonecook\infrastructure
Verify the environment configuration in config/environment.ts:
dev: {
environment: 'dev',
account: 'YOUR_AWS_ACCOUNT_ID',
region: 'ap-southeast-1',
domains: {
frontend: 'dev.everyonecook.cloud',
api: 'api-dev.everyonecook.cloud',
cdn: 'cdn-dev.everyonecook.cloud',
},
// ... other configs
}
Deploy the DNS stack to AWS:
# Deploy DNS Stack only
npx cdk deploy EveryoneCook-dev-DNS --context environment=dev
Expected output:
✨ Synthesis time: 5.23s
EveryoneCook-dev-DNS: deploying...
EveryoneCook-dev-DNS: creating CloudFormation changeset...
✅ EveryoneCook-dev-DNS
✨ Deployment time: 45.67s
Outputs:
EveryoneCook-dev-DNS.HostedZoneId = Z0123456789ABCDEFGHIJ
EveryoneCook-dev-DNS.HostedZoneName = everyonecook.cloud
EveryoneCook-dev-DNS.NameServers = ns-123.awsdns-45.com, ns-678.awsdns-90.net,
ns-1234.awsdns-56.org, ns-5678.awsdns-01.co.uk
Stack ARN:
arn:aws:cloudformation:ap-southeast-1:123456789012:stack/EveryoneCook-dev-DNS/...
everyonecook.cloud is createdExpected view:
everyonecook.cloud
Route 53 Hosted Zone showing domain details, NS records (4 nameservers), and SOA record
From the CloudFormation Outputs or Route 53 console, copy all 4 nameserver records:
ns-123.awsdns-45.com
ns-678.awsdns-90.net
ns-1234.awsdns-56.org
ns-5678.awsdns-01.co.uk
Location of nameserver records in Route 53 console
⚠️ IMPORTANT: After deploying the DNS Stack, you MUST update nameservers at Hostinger to delegate DNS management to Route 53.
Login to Hostinger hPanel
Access Domain Management
everyonecook.cloud domainChange Nameservers
Enter Route 53 Nameservers
ns-123.awsdns-45.comns-678.awsdns-90.netns-1234.awsdns-56.orgns-5678.awsdns-01.co.ukSave Configuration
Hostinger hPanel showing custom nameservers configuration with Route 53 NS records
After updating nameservers, verify the delegation:
# Check nameservers for the domain
nslookup -type=NS everyonecook.cloud
# Or using dig (if available)
dig NS everyonecook.cloud
Expected output:
everyonecook.cloud nameserver = ns-123.awsdns-45.com
everyonecook.cloud nameserver = ns-678.awsdns-90.net
everyonecook.cloud nameserver = ns-1234.awsdns-56.org
everyonecook.cloud nameserver = ns-5678.awsdns-01.co.uk
| Resource | Cost | Notes |
|---|---|---|
| Route 53 Hosted Zone | $0.50/month | Fixed cost per hosted zone |
| DNS Queries | $0.40 per million queries | First 1 billion queries/month |
| Total (Estimated) | ~$0.50-1.00/month | Very low traffic in dev environment |
The DNS Stack exports values that are imported by:
Certificate Stack (Phase 1.5)
HostedZoneIdCore Stack (Phase 2)
HostedZoneId, HostedZoneNameBackend Stack (Phase 4)
HostedZoneIdDNS Stack (Route 53)
│
├─► Certificate Stack (ACM certificates)
│
├─► Core Stack (CloudFront DNS records)
│
└─► Backend Stack (API Gateway DNS records)
Before proceeding to Certificate Stack deployment:
nslookup or digAfter successfully deploying and configuring the DNS Stack:
➡️ 5.4.2 Certificate Stack - Create ACM certificates with DNS validation
The Certificate Stack will:
cdn.everyonecook.cloud)*.everyonecook.cloud)infrastructure/lib/stacks/dns-stack.tsinfrastructure/lib/base-stack.tsinfrastructure/config/environment.ts