Skip to content

Commit c5f644d

Browse files
hyunsiesChris Hyuclaude
authored
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

File tree

0 commit comments

Comments
 (0)