mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-09-30 03:23:15 +00:00
feat(waf): add seahaven-prod shared CloudFront WebACL (PLAT-92) (#96)
* feat(waf): add seahaven-prod shared CloudFront WebACL stack Stand up AppWebAcl in a thin prod stack and widen seahaven-site HCP roles to read the SSM ARN so CloudFront can associate the ACL in-account. * fix(deploy): add app-web-acl-prod to deploy.yaml
This commit is contained in:
parent
2789f3cbcf
commit
a6f22880db
5 changed files with 68 additions and 1 deletions
2
.github/workflows/deploy.yaml
vendored
2
.github/workflows/deploy.yaml
vendored
|
|
@ -56,7 +56,7 @@ jobs:
|
|||
uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@7ac3528750b346f181347bb09f6af927a1c0aa14 # v1.0.6
|
||||
with:
|
||||
node-version: "24"
|
||||
stacks: "prod-baseline dynamodb-cmk-prod alarm-topic-prod deploy-substrate-prod terraform-substrate-prod"
|
||||
stacks: "prod-baseline dynamodb-cmk-prod alarm-topic-prod deploy-substrate-prod terraform-substrate-prod app-web-acl-prod"
|
||||
stack-name: "seahaven-prod-baseline"
|
||||
secrets:
|
||||
deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN_PROD }}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ the TypeScript source — no separate compile step needed for `cdk synth` /
|
|||
| `deploy-substrate-dev` | `seahaven-deploy-substrate` | 710827005802 | us-east-1 | `lib/deploy-substrate-stack.ts` |
|
||||
| `dynamodb-cmk-prod` | `seahaven-dynamodb-cmk` | 011934824531 | us-east-1 | `lib/dynamodb-cmk-stack.ts` |
|
||||
| `alarm-topic-prod` | `seahaven-alarm-topic` | 011934824531 | us-east-1 | `lib/alarm-topic-stack.ts` |
|
||||
| `app-web-acl-prod` | `seahaven-app-web-acl` | 011934824531 | us-east-1 | `lib/app-web-acl-stack.ts` |
|
||||
|
||||
Member-account stacks deploy with per-account credentials — the CD workflow
|
||||
runs one job per account, each assuming that account's OIDC deploy role. Local
|
||||
|
|
|
|||
10
bin/app.ts
10
bin/app.ts
|
|
@ -9,6 +9,7 @@ import { RegionalBaselineStack } from "../lib/regional-baseline-stack";
|
|||
import { DeploySubstrateStack } from "../lib/deploy-substrate-stack";
|
||||
import { TerraformSubstrateStack } from "../lib/terraform-substrate-stack";
|
||||
import { DynamoDbCmkStack } from "../lib/dynamodb-cmk-stack";
|
||||
import { AppWebAclStack } from "../lib/app-web-acl-stack";
|
||||
import { MemberBaselineStack } from "../lib/member-baseline-stack";
|
||||
import { OrgGovernanceStack } from "../lib/org-governance-stack";
|
||||
|
||||
|
|
@ -207,6 +208,15 @@ const terraformSubstrateProd = new TerraformSubstrateStack(
|
|||
);
|
||||
terraformSubstrateProd.addStackDependency(deploySubstrateProd);
|
||||
|
||||
// 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).
|
||||
new AppWebAclStack(app, "app-web-acl-prod", {
|
||||
stackName: "seahaven-app-web-acl",
|
||||
env: { account: PROD_ACCOUNT, region: "us-east-1" },
|
||||
});
|
||||
|
||||
const terraformSubstrateDev = new TerraformSubstrateStack(
|
||||
app,
|
||||
"terraform-substrate-dev",
|
||||
|
|
|
|||
25
lib/app-web-acl-stack.ts
Normal file
25
lib/app-web-acl-stack.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import * as cdk from "aws-cdk-lib";
|
||||
import { Construct } from "constructs";
|
||||
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.
|
||||
*/
|
||||
export class AppWebAclStack extends cdk.Stack {
|
||||
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
new AppWebAcl(this, "AppWebAcl");
|
||||
|
||||
cdk.Tags.of(this).add("Project", "account-baseline");
|
||||
cdk.Tags.of(this).add("Owner", "adam@seahavenind.com");
|
||||
cdk.Tags.of(this).add("ManagedBy", "cdk");
|
||||
}
|
||||
}
|
||||
|
|
@ -1482,6 +1482,19 @@ Resources:
|
|||
- acm:ListTagsForCertificate
|
||||
- acm:GetCertificate
|
||||
Resource: "*"
|
||||
- Sid: RefreshAppWebAclSsm
|
||||
Effect: Allow
|
||||
Action:
|
||||
- ssm:GetParameter
|
||||
- ssm:GetParameters
|
||||
Resource:
|
||||
- !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/seahaven/waf/app-web-acl-arn"
|
||||
- Sid: RefreshWafWebAcl
|
||||
Effect: Allow
|
||||
Action:
|
||||
- wafv2:GetWebACL
|
||||
- wafv2:ListWebACLs
|
||||
Resource: "*"
|
||||
|
||||
HcptfSeahavenSiteApplyRole:
|
||||
Type: AWS::IAM::Role
|
||||
|
|
@ -1554,3 +1567,21 @@ Resources:
|
|||
Condition:
|
||||
StringEquals:
|
||||
"aws:ResourceTag/Project": seahaven-site
|
||||
# CloudFront web_acl_id is set via UpdateDistribution (cloudfront:*
|
||||
# above). Read the shared ACL ARN from SSM (PLAT-92) and allow
|
||||
# WAFv2 describe so plans/applies can validate the association.
|
||||
- Sid: ReadAppWebAclSsm
|
||||
Effect: Allow
|
||||
Action:
|
||||
- ssm:GetParameter
|
||||
- ssm:GetParameters
|
||||
Resource:
|
||||
- !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/seahaven/waf/app-web-acl-arn"
|
||||
- Sid: ReadWafWebAcl
|
||||
Effect: Allow
|
||||
Action:
|
||||
- wafv2:GetWebACL
|
||||
- wafv2:GetWebACLForResource
|
||||
- wafv2:ListWebACLs
|
||||
- wafv2:ListResourcesForWebACL
|
||||
Resource: "*"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue