proposal-system/infra/bin/app.ts
Adam Moussa 0f9d27fbf0
chore(infra): prep proposal-system for seahaven-prod deployment (#227)
* chore(infra): retarget prod to seahaven-prod account + OIDC deploy-role artifacts

Retarget the CDK prod env from mgmt (328440206208, now frozen for workloads) to the
dedicated seahaven-prod workload account (011934824531). proposal-system is the org's
first prod tenant. Hard-block env=staging (still targets frozen mgmt) in resolveConfig
until it is retargeted to seahaven-dev (710827005802). Add a WARN-only out-of-pipeline
deploy guard in bin/app.ts.

Add infra/deploy-role/: OIDC trust policy (sub scoped to
Sea-Haven-Industries/proposal-system:ref:refs/heads/main), least-privilege permissions
policy (AssumeRole on the verified cdk-hnb659fds bootstrap roles, deterministic site
bucket, account-scoped CloudFront invalidation), and an idempotent creation script.
Verified against live prod: bootstrap qualifier hnb659fds v32, OIDC provider present.
Passed GPT-4.1 cross-review (APPROVE) and workflow red-team (CLEAN). Role NOT yet created
— gated on /sh-security-review + the deploy go-ahead.

Docs: README + CLAUDE.md reflect the prod account and pipeline-only deploy.

* chore(infra): region-bound deploy-role DescribeStacks to us-east-1 (sh-security-review IAM-L2)

* feat(infra): Aurora prod backup retention 14d + window; prod-only CDK context

Bump Aurora automated-backup (PITR) retention 7->14d and set a preferred backup
window for the prod tenant. Dedicated AWS Backup vault + cross-account restore
test is a tracked follow-up (no org central-backup design exists yet). Prune the
stale mgmt-account AZ context; prod (011934824531) is the only deploy target.
2026-07-15 14:44:35 -04:00

60 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import * as cdk from 'aws-cdk-lib';
import { FoundationStack } from '../lib/foundation-stack';
import { ComputeStack } from '../lib/compute-stack';
import { FrontendStack } from '../lib/frontend-stack';
import { resolveConfig } from '../lib/config';
const app = new cdk.App();
// Multi-env (PR2): `-c env=staging` (default prod). prod targets seahaven-prod
// (011934824531) with no stack-name suffix; staging is suffixed and currently hard-disabled
// (see resolveConfig — mgmt account is frozen).
const config = resolveConfig(app);
const { env, stackSuffix } = config;
// Pipeline-only deploy signal (WARN, not block). Prod deploys must go through the cd-cdk
// pipeline (GitHub Actions sets CI/GITHUB_ACTIONS). A local synth/deploy to prod is a
// drift risk + "no manual prod deploys" violation. True enforcement is an org-baseline SCP
// (tracked follow-up); this is the cheap in-repo backstop.
if (config.envName === 'prod' && !process.env.CI && !process.env.GITHUB_ACTIONS) {
// eslint-disable-next-line no-console
console.warn(
'\n⚠️ Running the PROD CDK app outside CI. Prod deploys must go through the cd-cdk ' +
'pipeline (deploy.yaml, workflow_dispatch). Do NOT `cdk deploy` to prod locally.\n',
);
}
const foundation = new FoundationStack(app, `proposal-system-foundation${stackSuffix}`, {
stackName: `proposal-system-foundation${stackSuffix}`,
env,
config,
description: 'Proposal System - VPC, RDS, S3, SQS, Cognito',
});
const compute = new ComputeStack(app, `proposal-system-compute${stackSuffix}`, {
stackName: `proposal-system-compute${stackSuffix}`,
env,
config,
description: 'Proposal System - API Lambda, Python Lambdas, Bedrock KB',
vpc: foundation.vpc,
lambdaSecurityGroup: foundation.lambdaSecurityGroup,
dbSecret: foundation.dbSecret,
dbCluster: foundation.dbCluster,
uploadsBucket: foundation.uploadsBucket,
generatedBucket: foundation.generatedBucket,
libraryBucket: foundation.libraryBucket,
jobsQueue: foundation.jobsQueue,
userPool: foundation.userPool,
alarmTopic: foundation.alarmTopic,
webClientId: foundation.webClientId,
mobileClientId: foundation.mobileClientId,
});
new FrontendStack(app, `proposal-system-frontend${stackSuffix}`, {
stackName: `proposal-system-frontend${stackSuffix}`,
env,
config,
description: 'Proposal System - CloudFront + S3 web hosting',
});
void compute;