Add CI/CD pipeline and fix stack name to kebab-case (#3)

* Add CI/CD pipeline and fix stack name to kebab-case

CodePipeline V2 (po-ingest-pipeline) triggers CodeBuild on push
to main, running cdk deploy via buildspec.yml. Stack name changed
from PoIngestStack to po-ingest to match naming conventions.

* Add RETAIN policy to Secrets Manager secret

Prevents the Anthropic API key from being deleted if the stack
is ever removed. Matches the RETAIN policy on all other stateful
resources (DynamoDB tables, S3 bucket).
This commit is contained in:
Adam Moussa 2026-05-01 19:17:19 -04:00 • committed by GitHub
parent 2b8e121413
commit 36f49ae259
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 2 deletions

View file

@ -30,7 +30,7 @@ Backfill stats (initial run): 14,825 POs scanned → 9,900 with extractable site
## Architecture
- **IaC:** AWS CDK (Python), stack name `PoIngestStack`, region `us-east-1`.
- **IaC:** AWS CDK (Python), stack name `po-ingest`, region `us-east-1`.
- **Lambdas** (all Python 3.12, arm64, 60-day log retention):
- `po-email-processor` — S3-triggered, parses PO emails via Claude Haiku.
- `po-web-ui` — Function URL, HTML dashboard.
@ -42,6 +42,13 @@ Backfill stats (initial run): 14,825 POs scanned → 9,900 with extractable site
- DynamoDB `pending-site-review` — PK `po_number`. POs with no extractable site code and no address match, awaiting manual Payee Central verification.
- **Secrets:** Anthropic API key in Secrets Manager at `po-ingest/anthropic-api-key`.
- **SES:** adds the `PoEmailRule` to the existing `INBOUND_MAIL` receipt rule set (shared with `workorder-ingest`).
- **CI/CD:** CodePipeline V2 (`po-ingest-pipeline`) → CodeBuild (`po-ingest-build`). Pushes to `main` auto-deploy via `buildspec.yml`.
## CI/CD
Merges to `main` trigger the `po-ingest-pipeline` (CodePipeline V2) which runs CodeBuild to `cdk deploy`. The pipeline uses the existing CodeStar connection to the Sea-Haven-Industries GitHub org.
**Branch protection:** `main` requires a PR (no direct push), no deletion, no force push.
## Setup

15
buildspec.yml Normal file
View file

@ -0,0 +1,15 @@
version: 0.2
phases:
install:
runtime-versions:
python: 3.12
nodejs: 22
commands:
- npm install -g aws-cdk
- pip install -r cdk/requirements.txt
- pip install -r lambdas/email_processor/requirements.txt -t lambdas/email_processor/package/
- cp lambdas/email_processor/handler.py lambdas/email_processor/package/
build:
commands:
- cd cdk && cdk deploy --require-approval never

View file

@ -4,7 +4,7 @@ from stack import PoIngestStack
app = cdk.App()
PoIngestStack(app, "po-ingest",
stack_name="PoIngestStack",
stack_name="po-ingest",
env=cdk.Environment(region="us-east-1"),
)
app.synth()

View file

@ -53,6 +53,7 @@ class PoIngestStack(Stack):
self, "AnthropicApiKey",
secret_name="po-ingest/anthropic-api-key",
description="Anthropic API key for Coupa PO email parsing",
removal_policy=RemovalPolicy.RETAIN,
)
# --- Lambda function ---