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 Permalink 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;