Commit c5f644d
ci: CFN correctness lint — catch Sprint-4-class bugs at Layer 1 (#43)
Sprint 4 shipped two separate incidents where cfn-lint reported green but
CloudFormation rejected the template at stack-create:
PR #41 — `ReconciliationRole` RoleName rendered to 69 chars, over IAM's
64-char limit. cfn-lint does not evaluate !Sub templates against
AWS service-side length constraints.
PR #42 — configurator.html had `RoleName: ...${AWS::Region}...` without
!Sub wrapping. The pseudo-parameter was emitted as a literal
`${AWS::Region}` string; IAM rejected the `:` as an invalid
RoleName character.
Both caught now. Five checks implemented in a new .github/scripts/
lint_cfn_correctness.py, wired as Layer 1 job #9 "CFN Correctness":
1. Unsubbed `${AWS::...}` in any scalar NOT wrapped in !Sub / !GetAtt.
This catches the PR #42 class directly.
2. Named-resource length overruns. For each resource with a Name /
RoleName / FunctionName / QueueName / TopicName / RuleName /
LogGroupName, compute worst-case rendered length using budgets of
MpeId=20 chars (MAP spec cap) and AWS::Region=14 chars (longest
current region). Compare to AWS service-side limits. Catches PR #41.
3. IAM RoleName character class. RoleName must match [A-Za-z0-9+=,.@_-].
Strips !Sub wrappers, JS template-literal escapes (\$), and CFN
placeholders; validates remaining literals. Second angle on PR #42.
4. Dangling !Ref / !GetAtt targets. Every reference must point at a
known Parameter, Resource, Condition, or CFN pseudo-parameter.
5. !Sub undefined template variables. Every ${...} inside a !Sub must
resolve to a known logical ID or pseudo-parameter. Skips lowercase-
led names (configurator.html JS-template-literal interpolations that
expand at generation time, not CFN runtime).
Runs against BOTH sources of truth:
- map2-auto-tagger-optimized.yaml (runtime)
- configurator.html (inline CFN template extracted from
generateMainTemplate's return `...`)
Both regression scenarios verified: re-introducing PR #41's 69-char
RoleName or PR #42's unsubbed RoleName in the worktree immediately
triggers targeted FAIL messages with line numbers.
Does NOT replace cfn-lint — runs alongside it. Closes the outstanding
follow-up captured as task #25 (resource-name-length validator) by
subsuming that scope into the broader pack.
Co-authored-by: Chris Hyu <chhyu@amazon.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent a2eff40 commit c5f644d
2 files changed
Lines changed: 425 additions & 0 deletions
0 commit comments