mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-10-04 03:03:13 +00:00
fix(baseline): remove the management account web acl from the baseline (#173)
The live template already retains the WebACL. Dropping the construct forgets that missing ACL and deletes the management SSM parameter. Prod keeps seahaven-app-web-acl.
This commit is contained in:
parent
cd37817e1f
commit
86666b8d0b
4 changed files with 10 additions and 55 deletions
|
|
@ -222,10 +222,9 @@ new DeploySubstrateStack(app, "deploy-substrate-dev", {
|
|||
// PLAT-145). External-dev stays: SHOC IAM is not moving (PLAT-148).
|
||||
// deploy-substrate stays for remaining SAM (PLAT-150).
|
||||
|
||||
// Shared CloudFront WAF for seahaven-prod (PLAT-92). Same AppWebAcl construct
|
||||
// as mgmt account-baseline; thin stack so prod does not inherit the full
|
||||
// mgmt baseline. Publishes /seahaven/waf/app-web-acl-arn for in-account
|
||||
// CloudFront associations (same-account only).
|
||||
// Shared CloudFront WAF for seahaven-prod (PLAT-92). The management account
|
||||
// no longer publishes /seahaven/waf/app-web-acl-arn. This stack publishes that
|
||||
// parameter for in-account CloudFront associations (same-account only).
|
||||
new AppWebAclStack(app, "app-web-acl-prod", {
|
||||
stackName: "seahaven-app-web-acl",
|
||||
env: { account: PROD_ACCOUNT, region: "us-east-1" },
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import { BedrockLogging } from "./bedrock-logging";
|
|||
import { CisMonitoring } from "./cis-monitoring";
|
||||
import { FlowLogs } from "./flow-logs";
|
||||
import { SesMonitoring } from "./ses-monitoring";
|
||||
import { AppWebAcl } from "./web-acl";
|
||||
|
||||
/**
|
||||
* Account-level security baseline for Sea Haven (account 328440206208).
|
||||
|
|
@ -252,19 +251,6 @@ export class AccountBaselineStack extends cdk.Stack {
|
|||
vpcIds: props.flowLogVpcIds,
|
||||
});
|
||||
new SesMonitoring(this, "SesMonitoring");
|
||||
// Shared CloudFront WAF WebACL (M-17); ARN published to SSM for app stacks.
|
||||
// RETAIN on the WebACL only. The physical ACL is already gone
|
||||
// (WAFNonexistentItemException) while this stack still owns it. The
|
||||
// deletion policy has to be in the live template before the construct is
|
||||
// removed, or CloudFormation Deletes, fails, and rollback tries to
|
||||
// recreate it. The SSM parameter stays on Delete.
|
||||
// existingWebAclId keeps the parameter and output off WebACL.Arn. GetAtt
|
||||
// calls GetWebACL, which fails because the ACL is gone. The id is the
|
||||
// physical id CloudFormation already recorded for AppWebAclFE38F02F.
|
||||
new AppWebAcl(this, "AppWebAcl", {
|
||||
webAclRemovalPolicy: cdk.RemovalPolicy.RETAIN,
|
||||
existingWebAclId: "cd668fe8-5cff-4d6a-9432-5c32145a7db4",
|
||||
});
|
||||
|
||||
// ── Day 5 AI governance ──
|
||||
// Bedrock model invocation logging destinations + delivery role (H-20).
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@ import { AppWebAcl } from "./web-acl";
|
|||
* Thin per-account stack that owns the shared CloudFront WAFv2 WebACL (M-17)
|
||||
* and publishes its ARN to SSM `/seahaven/waf/app-web-acl-arn`.
|
||||
*
|
||||
* Mgmt already has this ACL inside `AccountBaselineStack`. Workload accounts
|
||||
* (starting with seahaven-prod / PLAT-92) get a dedicated stack so we do not
|
||||
* pull the full mgmt baseline (trail, budgets, flow logs, …) into prod just
|
||||
* to share a CloudFront WAF. App stacks associate by reading the SSM param
|
||||
* in-account — WAFv2 CloudFront associations are same-account only.
|
||||
* Prod owns this stack (PLAT-92). The management account's copy lived inside
|
||||
* `AccountBaselineStack` and was removed after its deletion policy was Retain,
|
||||
* because the physical ACL was already gone. App stacks associate by reading
|
||||
* the SSM param in-account. WAFv2 CloudFront associations are same-account only.
|
||||
*/
|
||||
export class AppWebAclStack extends cdk.Stack {
|
||||
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
||||
|
|
|
|||
|
|
@ -13,25 +13,8 @@ import { Construct } from "constructs";
|
|||
* The ARN is published to SSM (`/seahaven/waf/app-web-acl-arn`) so app stacks in
|
||||
* other repos can consume it via `{{resolve:ssm:...}}` without a hard CFN export.
|
||||
*/
|
||||
export interface AppWebAclProps {
|
||||
/**
|
||||
* Deletion policy for the WebACL only. The SSM parameter keeps the default
|
||||
* Delete policy so a later stack update can remove the parameter. Prod does
|
||||
* not set this. Management sets RETAIN first because the live WebACL is
|
||||
* already gone and a Delete call would fail and roll back into a recreate.
|
||||
*/
|
||||
readonly webAclRemovalPolicy?: cdk.RemovalPolicy;
|
||||
/**
|
||||
* Physical id of a WebACL CloudFormation already tracks. When set, the SSM
|
||||
* parameter and output publish `global/webacl/seahaven-app-waf/<id>` with
|
||||
* account and region tokens, and do not reference WebACL.Arn. GetAtt on a
|
||||
* missing ACL calls GetWebACL and fails the stack update.
|
||||
*/
|
||||
readonly existingWebAclId?: string;
|
||||
}
|
||||
|
||||
export class AppWebAcl extends Construct {
|
||||
constructor(scope: Construct, id: string, props?: AppWebAclProps) {
|
||||
constructor(scope: Construct, id: string) {
|
||||
super(scope, id);
|
||||
|
||||
const vis = (metric: string): wafv2.CfnWebACL.VisibilityConfigProperty => ({
|
||||
|
|
@ -81,25 +64,13 @@ export class AppWebAcl extends Construct {
|
|||
},
|
||||
],
|
||||
});
|
||||
if (props?.webAclRemovalPolicy) {
|
||||
webAcl.applyRemovalPolicy(props.webAclRemovalPolicy);
|
||||
}
|
||||
|
||||
const publishedArn = props?.existingWebAclId
|
||||
? cdk.Stack.of(this).formatArn({
|
||||
service: "wafv2",
|
||||
resource: "global/webacl",
|
||||
resourceName: `seahaven-app-waf/${props.existingWebAclId}`,
|
||||
arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME,
|
||||
})
|
||||
: webAcl.attrArn;
|
||||
|
||||
new ssm.StringParameter(this, "AppWebAclArnParam", {
|
||||
parameterName: "/seahaven/waf/app-web-acl-arn",
|
||||
stringValue: publishedArn,
|
||||
stringValue: webAcl.attrArn,
|
||||
description: "ARN of the shared CloudFront WAF WebACL (audit M-17)",
|
||||
});
|
||||
|
||||
new cdk.CfnOutput(this, "AppWebAclArn", { value: publishedArn });
|
||||
new cdk.CfnOutput(this, "AppWebAclArn", { value: webAcl.attrArn });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue