Add dispatch-only CDK deployment and weekly drift check workflows - #2070
Add dispatch-only CDK deployment and weekly drift check workflows#2070KyleOps wants to merge 2 commits into
Conversation
The CDK stacks had no automation at all. Deploying meant someone building the packages locally and running cdk deploy by hand, and because nothing compared main against the running infrastructure, the two drifted apart from 2025-08 to 2026-07 without anyone noticing. Add two workflows. Deployment is dispatch only rather than on push: these stacks back demo and evaluation environments, and deploying replaces the HAPI tasks, which briefly takes the FHIR servers offline. It takes a stack and an action, both defaulting to the safe option, and the diff job always runs first so whoever approves a deploy can see the pending changes in the run summary. Access control is the aws-production GitHub environment rather than an actor check in the workflow, because an actor check is trivially bypassable and is not a security boundary. Until that environment is configured the deploy job cannot run, while diff still works. The drift check runs weekly, reports whether either stack differs from main, and opens or updates an issue labelled cdk-drift, closing it once they match again. The two jobs deliberately diff differently. Deployment uses the default change set method, because that asks CloudFormation to validate the resource graph; a template-only comparison is what let a circular dependency between the HAPI service and its database reach a deploy attempt undetected. The drift check only asks whether main and the deployed stack differ, which a template comparison answers without needing permission to create change sets. Both need a repository variable AWS_CDK_DEPLOY_ROLE_ARN. The account already has the GitHub OIDC provider and the cdk-hnb659fds-* bootstrap roles, but no role for running CDK from CI; SmartFormsReactAppDeployment is scoped to the React app's S3 deployment and widening it would be worse than adding a dedicated role. The required trust policy and permissions are documented in deployment/README.md.
|
Blocked on the IAM role, tracked in aehrc/smart-forms-infrastructure#1. That issue carries everything needed to create it: trust policy, the exact bootstrap role ARNs to allow, a working reference implementation, and the reasoning for putting it in Terraform there rather than as CDK in this repo (in short: the workflow should not be able to deploy the role that grants the workflow its permissions). One detail worth surfacing here, because it will otherwise cost someone an afternoon. The Matching only the documented first form fails to assume with an unhelpful STS error. Note the existing This PR is safe to leave open in the meantime. Both workflows check for |
Note for review: this repo is public, so these workflow runs are tooWorth a conscious decision before merging rather than discovering it later. What that does expose
What it does not exposeI checked this against real
RecommendationI would leave it as is. The CDK source is already public, so a diff of it reveals nothing the code does not, and having the detail in the run summary is most of the value: it is what lets a reviewer see what they are approving before the deploy job runs. If we would rather not publish it, the change is small and I am happy to make it: have the drift check report only which stacks drifted and drop the per-resource detail from RelatedThe trust policy in aehrc/smart-forms-infrastructure#1 has been tightened since I first wrote it, for the same reason. It no longer uses |
|
Discussed with team and they are happy with weekly drift check that pings me |
Extract the Node setup, deployment role check, npm install, package builds, and AWS credential configuration shared by all three CDK jobs into a cdk-setup composite action. The deploy job previously lacked the role check; it now inherits it from the shared action. Remove the diff job's has_changes output, which nothing consumed. Derive the drift check's stack list from cdk-stacks.sh instead of hardcoding it in two places. Shrink the workflow header rationale comments to one line each and point to deployment/README.md, which keeps the full rationale.
Why
The CDK stacks have no automation: deploying means building the packages locally and running
cdk deployby hand, and nothing comparesmainagainst what is actually running. Both stacks sat un-deployed from 2025-08 until 2026-07 without anyone noticing.What
cdk_deploy.ymlisworkflow_dispatchonly, since deploying replaces the HAPI tasks and briefly takes the FHIR servers offline. Inputs are the stack (bothby default) and the action (diffordeploy, defaulting todiff), so an accidental run changes nothing. Thediffjob always runs first and writes the pending changes to the run summary, so the approver sees what they are approving. After deploying, it polls both FHIR endpoints until they serve 200.cdk_drift_check.ymlruns weekly and on demand, reports whether either stack differs frommain, and opens, updates, or closes an issue labelledcdk-driftaccordingly.Setup common to both lives in a
cdk-setupcomposite action, and.github/scripts/cdk-stacks.shmaps the stack input to stack names and app directories.Two decisions worth reviewing
Access control is the
aws-productionGitHub environment with required reviewers, not an actor check, which is trivially bypassable. Until the environment is configured thedeployjob cannot run, whilediffstill works.The two jobs diff differently on purpose. Deployment uses the change set method so CloudFormation validates the resource graph; a template-only comparison is what let the circular dependency fixed in #2069 reach a deploy attempt undetected. The drift check only asks whether the stacks differ at all, which
--method=templateanswers without permission to create change sets.Not included
The IAM role the workflows assume (repository variable
AWS_CDK_DEPLOY_ROLE_ARN) does not exist yet and should be created deliberately by someone with account ownership. The trust policy and permissions it needs are documented indeployment/README.md.