Qualify inline sub-component output names to prevent config collisions#205
Open
jaredbrook wants to merge 2 commits into
Open
Qualify inline sub-component output names to prevent config collisions#205jaredbrook wants to merge 2 commits into
jaredbrook wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a compiler output collision where multiple sibling inline components (and their inline subcomponents) can overwrite each other’s generated config/cfndsl artifacts due to identical output filenames, causing later compiles to “win” and earlier instances to evaluate with the wrong config.
Changes:
- Extend
ComponentCompilerto accept an optionalqualified_nameand use it to generate unique output basenames for inline subcomponents. - Qualify inline subcomponent compiler names using their parent compiler name to avoid
*.config.yaml/*.compiled.cfndsl.rbcollisions. - Add a new RSpec regression test + fixtures that reproduce the collision across a multi-level inline hierarchy and assert per-instance config isolation.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
lib/cfhighlander.compiler.rb |
Adds qualified_name support and qualifies inline subcomponent output names to reduce artifact collisions. |
spec/test_inline_config_isolation_spec.rb |
New regression spec verifying two inline instances of the same template compile with distinct configs. |
spec/data/inline_config_isolation/src/p.config.yaml |
Test config providing distinct values for child_a vs child_b. |
spec/data/inline_config_isolation/src/p.cfndsl.rb |
Minimal parent CFNDSL stub for the regression test. |
spec/data/inline_config_isolation/src/p.cfhighlander.rb |
Parent template wiring two inline child components with different configs. |
spec/data/inline_config_isolation/src/child/child.cfndsl.rb |
Minimal child CFNDSL stub for the regression test. |
spec/data/inline_config_isolation/src/child/child.cfhighlander.rb |
Child template inlining the grandchild component (passes config through). |
spec/data/inline_config_isolation/src/grandchild/grandchild.cfndsl.rb |
Produces an S3 bucket whose name is derived from config (assertion target). |
spec/data/inline_config_isolation/src/grandchild/grandchild.cfhighlander.rb |
Minimal grandchild template stub for the regression test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+61
to
+69
| # Inline sub-components share the parent's output directory and their | ||
| # resources get flattened into the parent template, so they don't need | ||
| # stable filenames. Qualify with parent name to prevent collisions when | ||
| # multiple sibling components define sub-components with the same name. | ||
| child_name = if sub_component.inlined | ||
| "#{@component_name}_#{sub_component.name}" | ||
| else | ||
| sub_component.name | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When multiple sibling components use the same template with
render: Inline(e.g. severalfargate-v2instances each creating anapplication-autoscalingsub-component named"autoscaling"), the compiler writes their config and cfndsl output to the same filename. The last component to compile overwrites all previous ones, so every instance evaluates using a single shared config — the last writer wins.Example: A project defines five ECS services as
fargate-v2components. Each creates an inlineapplication-autoscalingcomponent which in turn creates an inlineecs-scalingsub-component named"autoscaling". All five write toautoscaling.config.yamlandautoscaling.compiled.cfndsl.rb. The last one to compile overwrites the rest, causing all services to share identical scaling policies regardless of their individual config.Fix
Qualify inline sub-component
@component_namevalues with their parent's component name, producing unique output filenames per instance. The qualified name is passed into the constructor via a new optionalqualified_nameparameter so it propagates recursively through the entire component tree.Non-inline (nested stack) components keep their original unqualified names so that template URLs and S3 publishing paths remain compatible.
Impact
flattenCloudformation, which is unaffected. The existing flatten spec passes.myTask.compiled.yaml→myproject_myservice_myTask.compiled.yaml). Any tooling that references these intermediate paths will need updating.Testing
test_cloudformation_util_spec(flatten test) passes — confirms the final CloudFormation output is identical.test_inline_config_isolation_spec— creates two inline instances of the same template with different configs (via a three-level parent/child/grandchild hierarchy to trigger the collision). Verified that the spec fails against unpatched 0.13.4 (child_agets"beta"instead of"alpha") and passes with the fix.