Skip to content

Commit 068b024

Browse files
committed
fix(core): Fn::Transform excluded in resource deep merge
The intrinsic function `Fn::Transform` can be used anywhere in a CloudFormation template which makes it special compared to the other intrinsic functions. In order for CfnResources to have Fn::Transform as a property key, this intrinsic needs to be merged like any other property. #36203
1 parent d8c324a commit 068b024

2 files changed

Lines changed: 60 additions & 2 deletions

File tree

packages/aws-cdk-lib/core/lib/cfn-resource.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,12 @@ export interface ICfnResourceOptions {
625625

626626
/**
627627
* Object keys that deepMerge should not consider. Currently these include
628-
* CloudFormation intrinsics
628+
* CloudFormation intrinsics, exluding Fn::Transform.
629+
*
630+
* Intrinsics are objects in CloudFormation templates where the one and only key is the function name and the value is
631+
* the function's arguments. Fn::Transform is a unique intrinsic as it can appear as a key in multi-key objects (like
632+
* resource Properties). For this reason it is left out of this list as it should not get rid of other keys when doing object
633+
* deep merges.
629634
*
630635
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
631636
*/
@@ -642,7 +647,6 @@ const MERGE_EXCLUDE_KEYS: string[] = [
642647
'Fn::Select',
643648
'Fn::Split',
644649
'Fn::Sub',
645-
'Fn::Transform',
646650
'Fn::And',
647651
'Fn::Equals',
648652
'Fn::If',

packages/aws-cdk-lib/core/test/cfn-resource.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,60 @@ describe('cfn resource', () => {
4545
},
4646
});
4747
});
48+
49+
test('renders "Properties" for resource with Fn::Transform as an override', () => {
50+
const app = new core.App();
51+
const stack = new core.Stack(app, 'TestStack');
52+
const resource = new core.CfnResource(stack, 'Resource', {
53+
type: 'Test::Resource::Fake',
54+
properties: {
55+
FakeProperty: 'Foo',
56+
},
57+
});
58+
59+
resource.addOverride('Properties.Fn::Transform', {
60+
Name: 'FakeTransform',
61+
});
62+
63+
expect(app.synth().getStackByName(stack.stackName).template?.Resources).toEqual({
64+
Resource: {
65+
Type: 'Test::Resource::Fake',
66+
Properties: {
67+
'FakeProperty': 'Foo',
68+
'Fn::Transform': {
69+
Name: 'FakeTransform',
70+
},
71+
},
72+
},
73+
});
74+
});
75+
76+
test('renders "Properties" for resource with Fn::Transform as a property', () => {
77+
const app = new core.App();
78+
const stack = new core.Stack(app, 'TestStack');
79+
const resource = new core.CfnResource(stack, 'Resource', {
80+
type: 'Test::Resource::Fake',
81+
properties: {
82+
'Fn::Transform': {
83+
Name: 'FakeTransform',
84+
},
85+
},
86+
});
87+
88+
resource.addOverride('Properties.FakeProperty', 'Foo');
89+
90+
expect(app.synth().getStackByName(stack.stackName).template?.Resources).toEqual({
91+
Resource: {
92+
Type: 'Test::Resource::Fake',
93+
Properties: {
94+
'FakeProperty': 'Foo',
95+
'Fn::Transform': {
96+
Name: 'FakeTransform',
97+
},
98+
},
99+
},
100+
});
101+
});
48102
});
49103

50104
describe('snapshot removal policy', () => {

0 commit comments

Comments
 (0)