Skip to content

Commit 05acf14

Browse files
committed
Initial commit
1 parent a346b73 commit 05acf14

13 files changed

+5743
-41
lines changed

README.md

Lines changed: 165 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,169 @@
1-
# Welcome to your CDK TypeScript project
1+
# Rabbits Playground AWS CDK
22

3-
This is a blank project for CDK development with TypeScript.
3+
This project contains the AWS infrastructure for Rabbits Playground, ported from Terraform/Terragrunt to AWS CDK.
44

5-
The `cdk.json` file tells the CDK Toolkit how to execute your app.
5+
## Architecture
66

7-
## Useful commands
7+
The infrastructure includes:
88

9-
* `npm run build` compile typescript to js
10-
* `npm run watch` watch for changes and compile
11-
* `npm run test` perform the jest unit tests
12-
* `npx cdk deploy` deploy this stack to your default AWS account/region
13-
* `npx cdk diff` compare deployed stack with current state
14-
* `npx cdk synth` emits the synthesized CloudFormation template
9+
- **VPC**: Multi-AZ networking with public and private subnets
10+
- **EKS**: Kubernetes cluster with managed node groups (ARM64/Graviton instances)
11+
- **Bastion**: EC2 bastion host for secure access
12+
- **S3**: Static content and user content buckets with lifecycle policies
13+
- **CloudFront**: CDN for static content delivery
14+
- **Route53**: DNS management and routing
15+
16+
## Project Structure
17+
18+
```
19+
├── bin/
20+
│ └── rabbits-playground-aws-cdk.ts # CDK app entry point
21+
├── lib/
22+
│ ├── constructs/ # Reusable constructs
23+
│ │ ├── vpc-construct.ts
24+
│ │ ├── eks-construct.ts
25+
│ │ ├── bastion-construct.ts
26+
│ │ ├── s3-construct.ts
27+
│ │ ├── cloudfront-construct.ts
28+
│ │ └── route53-construct.ts
29+
│ └── stacks/
30+
│ └── infrastructure-stack.ts # Main infrastructure stack
31+
├── config/
32+
│ └── environment.ts # Environment-specific configurations
33+
└── cdk.json # CDK configuration
34+
```
35+
36+
## Environments
37+
38+
Two environments are supported:
39+
- **dev**: Development environment with cost-optimized settings
40+
- **prod**: Production environment with high-availability settings
41+
42+
### Key Differences
43+
44+
| Feature | Dev | Prod |
45+
|---------|-----|------|
46+
| VPC CIDR | 10.0.0.0/16 | 10.1.0.0/16 |
47+
| NAT Gateways | 1 (cost optimization) | 3 (multi-AZ HA) |
48+
| EKS Capacity | SPOT instances | ON_DEMAND instances |
49+
| EKS Instance Type | t4g.medium | t4g.large, t4g.xlarge |
50+
| EKS Nodes | 2 desired (1-3) | 3 desired (3-10) |
51+
| EKS API Access | Public | Private |
52+
| Log Retention | 7 days | 30 days |
53+
| S3 Versioning | Disabled | Enabled |
54+
| S3 Lifecycle | Disabled | Enabled (IA at 90d, Glacier at 180d) |
55+
56+
## Prerequisites
57+
58+
- Node.js 14.x or later
59+
- AWS CLI configured with appropriate credentials
60+
- AWS CDK CLI: `npm install -g aws-cdk`
61+
62+
## Setup
63+
64+
1. Install dependencies:
65+
```bash
66+
npm install
67+
```
68+
69+
2. Configure AWS credentials:
70+
```bash
71+
export AWS_ACCOUNT_ID=your-account-id
72+
export AWS_REGION=us-west-2
73+
```
74+
75+
3. Bootstrap CDK (first time only):
76+
```bash
77+
cdk bootstrap aws://${AWS_ACCOUNT_ID}/${AWS_REGION}
78+
```
79+
80+
## Deployment
81+
82+
### Deploy to Dev Environment
83+
84+
```bash
85+
cdk deploy -c environment=dev
86+
```
87+
88+
### Deploy to Prod Environment
89+
90+
```bash
91+
cdk deploy -c environment=prod
92+
```
93+
94+
## Useful Commands
95+
96+
* `npm run build` - Compile TypeScript to JavaScript
97+
* `npm run watch` - Watch for changes and compile
98+
* `npm run test` - Run unit tests
99+
* `cdk diff -c environment=dev` - Compare deployed stack with current state
100+
* `cdk synth -c environment=dev` - Emit the synthesized CloudFormation template
101+
* `cdk deploy -c environment=dev` - Deploy stack to AWS account/region
102+
* `cdk destroy -c environment=dev` - Remove stack from AWS account/region
103+
104+
## Configuration
105+
106+
Environment-specific configurations are defined in `config/environment.ts`. Update these values as needed for your environments:
107+
108+
- VPC CIDR ranges
109+
- EKS cluster settings
110+
- Bastion access CIDRs
111+
- S3 bucket names
112+
- Domain names
113+
- Route53 hosted zone settings
114+
115+
## Connecting to Resources
116+
117+
### EKS Cluster
118+
119+
After deployment, configure kubectl:
120+
```bash
121+
aws eks update-kubeconfig --region us-west-2 --name rabbits-playground-dev
122+
```
123+
124+
### Bastion Host
125+
126+
Connect via SSM Session Manager:
127+
```bash
128+
aws ssm start-session --target <instance-id>
129+
```
130+
131+
Or via SSH (if key pair configured):
132+
```bash
133+
ssh -i your-key.pem ec2-user@bastion.dev.example.com
134+
```
135+
136+
## Outputs
137+
138+
After deployment, the stack outputs include:
139+
140+
- VPC ID and subnet IDs
141+
- EKS cluster endpoint and security group
142+
- Bastion host IPs
143+
- S3 bucket names and ARNs
144+
- CloudFront distribution domain name
145+
- Route53 hosted zone details
146+
147+
## Security Considerations
148+
149+
- EKS nodes run in private subnets
150+
- Bastion host uses IMDSv2 and SSM for secure access
151+
- S3 buckets have encryption and public access blocking enabled
152+
- CloudFront enforces HTTPS-only access
153+
- Security groups restrict traffic by default
154+
- IAM roles follow principle of least privilege
155+
156+
## Migration from Terraform
157+
158+
This CDK implementation replaces the previous Terraform/Terragrunt setup with equivalent functionality:
159+
160+
- Terraform modules → CDK constructs
161+
- Terragrunt environments → CDK context
162+
- Remote state in S3 → CloudFormation stacks
163+
- Outputs → CDK CfnOutput
164+
165+
## Support
166+
167+
For issues or questions, please refer to the AWS CDK documentation:
168+
- https://docs.aws.amazon.com/cdk/
169+
- https://github.com/aws/aws-cdk

bin/rabbits-playground-aws-cdk.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
#!/usr/bin/env node
22
import * as cdk from 'aws-cdk-lib';
3-
import { RabbitsPlaygroundAwsCdkStack } from '../lib/rabbits-playground-aws-cdk-stack';
3+
import { InfrastructureStack } from '../lib/stacks/infrastructure-stack';
4+
import { getConfig } from '../config/environment';
45

56
const app = new cdk.App();
6-
new RabbitsPlaygroundAwsCdkStack(app, 'RabbitsPlaygroundAwsCdkStack', {
7-
/* If you don't specify 'env', this stack will be environment-agnostic.
8-
* Account/Region-dependent features and context lookups will not work,
9-
* but a single synthesized template can be deployed anywhere. */
107

11-
/* Uncomment the next line to specialize this stack for the AWS Account
12-
* and Region that are implied by the current CLI configuration. */
13-
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
8+
// Get environment from context or default to 'dev'
9+
const environment = app.node.tryGetContext('environment') || 'dev';
1410

15-
/* Uncomment the next line if you know exactly what Account and Region you
16-
* want to deploy the stack to. */
17-
// env: { account: '123456789012', region: 'us-east-1' },
11+
if (environment !== 'dev' && environment !== 'prod') {
12+
throw new Error('Environment must be either "dev" or "prod"');
13+
}
1814

19-
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
20-
});
15+
// Get configuration for the specified environment
16+
const config = getConfig(environment);
17+
18+
// Get AWS account and region from environment variables or CDK context
19+
const account = process.env.CDK_DEFAULT_ACCOUNT || process.env.AWS_ACCOUNT_ID;
20+
const region = config.region;
21+
22+
// Create the infrastructure stack
23+
new InfrastructureStack(app, `RabbitsPlayground-${environment}`, {
24+
env: {
25+
account: account,
26+
region: region,
27+
},
28+
config: config,
29+
description: `Rabbits Playground infrastructure for ${environment} environment`,
30+
stackName: `rabbits-playground-${environment}`,
31+
});
32+
33+
app.synth();

config/environment.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
export interface EnvironmentConfig {
2+
account?: string;
3+
region: string;
4+
environment: 'dev' | 'prod';
5+
6+
// VPC Configuration
7+
vpcCidr: string;
8+
singleNatGateway: boolean;
9+
10+
// EKS Configuration
11+
clusterName: string;
12+
kubernetesVersion: string;
13+
nodeInstanceTypes: string[];
14+
nodeCapacityType: 'SPOT' | 'ON_DEMAND';
15+
nodeDesiredSize: number;
16+
nodeMinSize: number;
17+
nodeMaxSize: number;
18+
endpointPublicAccess: boolean;
19+
logRetentionDays: number;
20+
21+
// Bastion Configuration
22+
bastionInstanceType: string;
23+
bastionAllowedCidrs: string[];
24+
bastionKeyName?: string;
25+
26+
// S3 Configuration
27+
staticBucketName: string;
28+
userBucketName: string;
29+
enableVersioning: boolean;
30+
enableLifecycleRules: boolean;
31+
32+
// CloudFront Configuration
33+
cloudfrontPriceClass: string;
34+
35+
// Route53 Configuration
36+
domainName: string;
37+
createHostedZone: boolean;
38+
hostedZoneId?: string;
39+
40+
// Tags
41+
tags: { [key: string]: string };
42+
}
43+
44+
export const devConfig: EnvironmentConfig = {
45+
region: 'us-west-2',
46+
environment: 'dev',
47+
48+
// VPC
49+
vpcCidr: '10.0.0.0/16',
50+
singleNatGateway: true,
51+
52+
// EKS
53+
clusterName: 'rabbits-playground-dev',
54+
kubernetesVersion: '1.28',
55+
nodeInstanceTypes: ['t4g.medium'],
56+
nodeCapacityType: 'SPOT',
57+
nodeDesiredSize: 2,
58+
nodeMinSize: 1,
59+
nodeMaxSize: 3,
60+
endpointPublicAccess: true,
61+
logRetentionDays: 7,
62+
63+
// Bastion
64+
bastionInstanceType: 't4g.micro',
65+
bastionAllowedCidrs: ['0.0.0.0/0'],
66+
67+
// S3
68+
staticBucketName: 'rabbits-playground-static-dev',
69+
userBucketName: 'rabbits-playground-user-content-dev',
70+
enableVersioning: false,
71+
enableLifecycleRules: false,
72+
73+
// CloudFront
74+
cloudfrontPriceClass: 'PriceClass_100',
75+
76+
// Route53
77+
domainName: 'dev.example.com',
78+
createHostedZone: false,
79+
80+
tags: {
81+
ManagedBy: 'AWS CDK',
82+
Environment: 'dev',
83+
},
84+
};
85+
86+
export const prodConfig: EnvironmentConfig = {
87+
region: 'us-west-2',
88+
environment: 'prod',
89+
90+
// VPC
91+
vpcCidr: '10.1.0.0/16',
92+
singleNatGateway: false,
93+
94+
// EKS
95+
clusterName: 'rabbits-playground-prod',
96+
kubernetesVersion: '1.28',
97+
nodeInstanceTypes: ['t4g.large', 't4g.xlarge'],
98+
nodeCapacityType: 'ON_DEMAND',
99+
nodeDesiredSize: 3,
100+
nodeMinSize: 3,
101+
nodeMaxSize: 10,
102+
endpointPublicAccess: false,
103+
logRetentionDays: 30,
104+
105+
// Bastion
106+
bastionInstanceType: 't4g.micro',
107+
bastionAllowedCidrs: ['10.1.0.0/16'],
108+
109+
// S3
110+
staticBucketName: 'rabbits-playground-static-prod',
111+
userBucketName: 'rabbits-playground-user-content-prod',
112+
enableVersioning: true,
113+
enableLifecycleRules: true,
114+
115+
// CloudFront
116+
cloudfrontPriceClass: 'PriceClass_100',
117+
118+
// Route53
119+
domainName: 'example.com',
120+
createHostedZone: false,
121+
122+
tags: {
123+
ManagedBy: 'AWS CDK',
124+
Environment: 'prod',
125+
},
126+
};
127+
128+
export function getConfig(environment: 'dev' | 'prod'): EnvironmentConfig {
129+
return environment === 'dev' ? devConfig : prodConfig;
130+
}

0 commit comments

Comments
 (0)