mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-09-30 17:03:14 +00:00
Adds an env config layer resolved from CDK context (`-c env=staging`, default prod) and threads it through all three stacks so a fully isolated staging environment can be deployed in the same AWS account. prod is byte-identical: the prod config reproduces the deployed values exactly and stackSuffix='' keeps every construct ID, stack name, and physical resource name unchanged. Verified via synth — prod foundation keeps proposal-system-db / -uploads / db-credentials / -auth / seahaven; staging suffixes all of them. - config.ts: EnvConfig (prod + staging, same account) + resolveConfig - app.ts: env-aware stack naming + config passthrough - foundation/compute/frontend: ~40 physical names suffixed with config.stackSuffix; CORS, Cognito domain/callbacks, alarms email from config; RETAIN / deletionProtection gated on config.retainData so staging can be torn down - cdk.json: register `env` context (default prod) - post-deploy.sh: STACK_SUFFIX for dynamic stack-name lookup (default prod) Note: automated staging CI deploy needs a one-line `cdk-context` input added to the org reusable cd-cdk.yaml (companion change). prod deploy is unaffected (default prod).
80 lines
3 KiB
TypeScript
80 lines
3 KiB
TypeScript
import * as cdk from 'aws-cdk-lib';
|
|
|
|
// Multi-environment configuration (PR2). Resolved from CDK context: `-c env=staging`,
|
|
// default `prod`. CRITICAL: the prod config MUST keep the exact construct IDs, stack
|
|
// names, and resource settings the deployed stacks already use — renaming a deployed
|
|
// CloudFormation stack triggers replace-and-delete, which would destroy the RDS instance.
|
|
// Only non-prod environments take a stack-name suffix.
|
|
|
|
export type EnvName = 'prod' | 'staging';
|
|
|
|
export interface EnvConfig {
|
|
readonly envName: EnvName;
|
|
readonly env: cdk.Environment;
|
|
/** Suffix for stack names + construct IDs. '' for prod so deployed stacks are untouched. */
|
|
readonly stackSuffix: string;
|
|
/** S3 bucket CORS allowed origins. */
|
|
readonly s3CorsOrigins: string[];
|
|
/** API Gateway CORS allowed origins. */
|
|
readonly apiCorsOrigins: string[];
|
|
/** Cognito web-client callback / logout URLs. */
|
|
readonly webCallbackUrls: string[];
|
|
readonly webLogoutUrls: string[];
|
|
/** Cognito hosted-UI domain prefix (must be globally unique). */
|
|
readonly cognitoDomainPrefix: string;
|
|
/** Email subscribed to the CloudWatch alarm SNS topic. */
|
|
readonly alarmsEmail: string;
|
|
/** Retain stateful resources (RDS, buckets) on stack deletion. */
|
|
readonly retainData: boolean;
|
|
}
|
|
|
|
const ACCOUNT = '328440206208';
|
|
const REGION = 'us-east-1';
|
|
|
|
// Prod values reproduce the currently-deployed stacks EXACTLY (verified against
|
|
// foundation-stack.ts / compute-stack.ts) so `cdk diff` shows no prod changes.
|
|
const PROD: EnvConfig = {
|
|
envName: 'prod',
|
|
env: { account: ACCOUNT, region: REGION },
|
|
stackSuffix: '',
|
|
s3CorsOrigins: ['https://proposals.seahaven.com', 'http://localhost:5173'],
|
|
apiCorsOrigins: [
|
|
'https://proposals.seahaven.com',
|
|
'https://d2yevct5e5uuz5.cloudfront.net',
|
|
'http://localhost:5173',
|
|
],
|
|
webCallbackUrls: [
|
|
'https://proposals.seahaven.com/callback',
|
|
'http://localhost:5173/callback',
|
|
],
|
|
webLogoutUrls: ['https://proposals.seahaven.com', 'http://localhost:5173'],
|
|
cognitoDomainPrefix: 'proposal-system-seahaven',
|
|
alarmsEmail: 'adam@seahavenind.com',
|
|
retainData: true,
|
|
};
|
|
|
|
// Staging: same AWS account (Adam, 2026-06-12), suffixed stacks, no permanent domain
|
|
// yet (CloudFront default URL + localhost), data not retained.
|
|
const STAGING: EnvConfig = {
|
|
envName: 'staging',
|
|
env: { account: ACCOUNT, region: REGION },
|
|
stackSuffix: '-staging',
|
|
s3CorsOrigins: ['http://localhost:5173'],
|
|
apiCorsOrigins: ['http://localhost:5173'],
|
|
webCallbackUrls: ['http://localhost:5173/callback'],
|
|
webLogoutUrls: ['http://localhost:5173'],
|
|
cognitoDomainPrefix: 'proposal-system-seahaven-staging',
|
|
alarmsEmail: 'adam@seahavenind.com',
|
|
retainData: false,
|
|
};
|
|
|
|
const CONFIGS: Record<EnvName, EnvConfig> = { prod: PROD, staging: STAGING };
|
|
|
|
export function resolveConfig(app: cdk.App): EnvConfig {
|
|
const name = (app.node.tryGetContext('env') as EnvName | undefined) ?? 'prod';
|
|
const config = CONFIGS[name];
|
|
if (!config) {
|
|
throw new Error(`Unknown env '${name}'. Use -c env=prod (default) or -c env=staging.`);
|
|
}
|
|
return config;
|
|
}
|