255 lines
7.6 KiB
JavaScript
255 lines
7.6 KiB
JavaScript
#!/usr/bin/env node
|
|
import "source-map-support/register";
|
|
import * as cdk from "aws-cdk-lib";
|
|
import { ConditionCheckLambdaStack } from "../lib/condition-check-lambda-stack";
|
|
import { ImageProcessorLambdaStack } from "../lib/image-processor-lambda-stack";
|
|
import { VpcStack } from "../lib/vpc-stack";
|
|
import { CertificateStack } from "../lib/certificate-stack";
|
|
import { SecretsStack } from "../lib/secrets-stack";
|
|
import { EcrStack } from "../lib/ecr-stack";
|
|
import { RdsStack } from "../lib/rds-stack";
|
|
import { EcsServiceStack } from "../lib/ecs-service-stack";
|
|
|
|
const app = new cdk.App();
|
|
|
|
// Get environment from context or default to dev
|
|
const environment = app.node.tryGetContext("env") || "dev";
|
|
|
|
// Get context variables for deployment configuration
|
|
const allowedIp = app.node.tryGetContext("allowedIp"); // e.g., "1.2.3.4/32"
|
|
const domainName = app.node.tryGetContext("domainName") || "village-share.com";
|
|
|
|
// Environment-specific configurations
|
|
const envConfig: Record<
|
|
string,
|
|
{
|
|
databaseUrl: string;
|
|
frontendUrl: string;
|
|
sesFromEmail: string;
|
|
emailEnabled: boolean;
|
|
natGateways: number;
|
|
subdomain: string;
|
|
dbInstanceType: "micro" | "small" | "medium";
|
|
multiAz: boolean;
|
|
}
|
|
> = {
|
|
dev: {
|
|
databaseUrl:
|
|
process.env.DATABASE_URL ||
|
|
"postgresql://user:password@localhost:5432/rentall_dev",
|
|
frontendUrl: `https://dev.${domainName}`,
|
|
sesFromEmail: `noreply@${domainName}`,
|
|
emailEnabled: false, // Disable emails in dev
|
|
natGateways: 1,
|
|
subdomain: "dev",
|
|
dbInstanceType: "micro",
|
|
multiAz: false,
|
|
},
|
|
staging: {
|
|
databaseUrl:
|
|
process.env.DATABASE_URL ||
|
|
"postgresql://user:password@localhost:5432/rentall_staging",
|
|
frontendUrl: `https://staging.${domainName}`,
|
|
sesFromEmail: `noreply@${domainName}`,
|
|
emailEnabled: true,
|
|
natGateways: 1,
|
|
subdomain: "staging",
|
|
dbInstanceType: "micro",
|
|
multiAz: false,
|
|
},
|
|
prod: {
|
|
databaseUrl:
|
|
process.env.DATABASE_URL ||
|
|
"postgresql://user:password@localhost:5432/rentall_prod",
|
|
frontendUrl: `https://${domainName}`,
|
|
sesFromEmail: `noreply@${domainName}`,
|
|
emailEnabled: true,
|
|
natGateways: 2, // Multi-AZ NAT gateways for high availability
|
|
subdomain: "", // No subdomain for prod
|
|
dbInstanceType: "small",
|
|
multiAz: true,
|
|
},
|
|
};
|
|
|
|
const config = envConfig[environment];
|
|
|
|
if (!config) {
|
|
throw new Error(`Unknown environment: ${environment}`);
|
|
}
|
|
|
|
const envProps = {
|
|
env: {
|
|
account: process.env.CDK_DEFAULT_ACCOUNT,
|
|
region: process.env.CDK_DEFAULT_REGION || "us-east-1",
|
|
},
|
|
};
|
|
|
|
// Common tags for all stacks
|
|
const commonTags = {
|
|
Environment: environment,
|
|
Project: "village-share",
|
|
ManagedBy: "cdk",
|
|
};
|
|
|
|
// ============================================================================
|
|
// Certificate Stack (Shared across environments)
|
|
// Deploy this once and validate DNS before deploying other stacks
|
|
// ============================================================================
|
|
const certificateStack = new CertificateStack(app, "CertificateStack", {
|
|
domainName,
|
|
...envProps,
|
|
description: `ACM wildcard certificate for ${domainName}`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "certificate",
|
|
},
|
|
});
|
|
|
|
// ============================================================================
|
|
// VPC Stack
|
|
// ============================================================================
|
|
const vpcStack = new VpcStack(app, `VpcStack-${environment}`, {
|
|
environment,
|
|
natGateways: config.natGateways,
|
|
maxAzs: 2,
|
|
...envProps,
|
|
description: `VPC infrastructure with private subnets and VPC endpoints (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "networking",
|
|
},
|
|
});
|
|
|
|
// ============================================================================
|
|
// Secrets Stack
|
|
// ============================================================================
|
|
const secretsStack = new SecretsStack(app, `SecretsStack-${environment}`, {
|
|
environment,
|
|
...envProps,
|
|
description: `Secrets Manager secrets for database and application (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "secrets",
|
|
},
|
|
});
|
|
|
|
// ============================================================================
|
|
// ECR Stack
|
|
// ============================================================================
|
|
const ecrStack = new EcrStack(app, `EcrStack-${environment}`, {
|
|
environment,
|
|
...envProps,
|
|
description: `ECR repositories for Docker images (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "ecr",
|
|
},
|
|
});
|
|
|
|
// ============================================================================
|
|
// RDS Stack
|
|
// ============================================================================
|
|
const rdsStack = new RdsStack(app, `RdsStack-${environment}`, {
|
|
environment,
|
|
vpc: vpcStack.vpc,
|
|
databaseSecret: secretsStack.databaseSecret,
|
|
databaseName: "rentall",
|
|
multiAz: config.multiAz,
|
|
...envProps,
|
|
description: `RDS PostgreSQL database (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "database",
|
|
},
|
|
});
|
|
|
|
// RDS depends on VPC and Secrets
|
|
rdsStack.addDependency(vpcStack);
|
|
rdsStack.addDependency(secretsStack);
|
|
|
|
// ============================================================================
|
|
// ECS Service Stack
|
|
// ============================================================================
|
|
const fullDomainName = config.subdomain
|
|
? `${config.subdomain}.${domainName}`
|
|
: domainName;
|
|
|
|
const ecsServiceStack = new EcsServiceStack(
|
|
app,
|
|
`EcsServiceStack-${environment}`,
|
|
{
|
|
environment,
|
|
vpc: vpcStack.vpc,
|
|
certificate: certificateStack.certificate,
|
|
backendRepository: ecrStack.backendRepository,
|
|
frontendRepository: ecrStack.frontendRepository,
|
|
databaseSecret: secretsStack.databaseSecret,
|
|
appSecret: secretsStack.appSecret,
|
|
databaseSecurityGroup: rdsStack.databaseSecurityGroup,
|
|
dbEndpoint: rdsStack.dbEndpoint,
|
|
dbPort: rdsStack.dbPort,
|
|
dbName: "rentall",
|
|
domainName: fullDomainName,
|
|
allowedIp: environment === "dev" ? allowedIp : undefined, // Only restrict in dev
|
|
frontendUrl: config.frontendUrl,
|
|
...envProps,
|
|
description: `ECS Fargate services with ALB (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "ecs",
|
|
},
|
|
}
|
|
);
|
|
|
|
// ECS depends on VPC, Certificate, ECR, Secrets, and RDS
|
|
ecsServiceStack.addDependency(vpcStack);
|
|
ecsServiceStack.addDependency(certificateStack);
|
|
ecsServiceStack.addDependency(ecrStack);
|
|
ecsServiceStack.addDependency(secretsStack);
|
|
ecsServiceStack.addDependency(rdsStack);
|
|
|
|
// ============================================================================
|
|
// Lambda Stacks (existing)
|
|
// ============================================================================
|
|
const conditionCheckStack = new ConditionCheckLambdaStack(
|
|
app,
|
|
`ConditionCheckLambdaStack-${environment}`,
|
|
{
|
|
environment,
|
|
databaseUrl: config.databaseUrl,
|
|
frontendUrl: config.frontendUrl,
|
|
sesFromEmail: config.sesFromEmail,
|
|
emailEnabled: config.emailEnabled,
|
|
vpc: vpcStack.vpc,
|
|
lambdaSecurityGroup: vpcStack.lambdaSecurityGroup,
|
|
...envProps,
|
|
description: `Condition Check Reminder Lambda infrastructure (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "condition-check-reminder",
|
|
},
|
|
}
|
|
);
|
|
|
|
conditionCheckStack.addDependency(vpcStack);
|
|
|
|
const imageProcessorStack = new ImageProcessorLambdaStack(
|
|
app,
|
|
`ImageProcessorLambdaStack-${environment}`,
|
|
{
|
|
environment,
|
|
databaseUrl: config.databaseUrl,
|
|
frontendUrl: config.frontendUrl,
|
|
vpc: vpcStack.vpc,
|
|
lambdaSecurityGroup: vpcStack.lambdaSecurityGroup,
|
|
...envProps,
|
|
description: `Image Processor Lambda infrastructure (${environment})`,
|
|
tags: {
|
|
...commonTags,
|
|
Service: "image-processor",
|
|
},
|
|
}
|
|
);
|
|
|
|
imageProcessorStack.addDependency(vpcStack);
|